webpack+react項目初體驗——記錄個人webpack環境配置

這兩天學習了一些webpack的知識,loaders+plugins真的很強大!不過配置起來也很複雜,看了一些文章,本身也寫了項目練手,寫下來加深本身的印象。css

首先,很是很是推薦的幾篇文章,初學者必定要看!
<入門Webpack,看這篇就夠了>
http://www.jianshu.com/p/42e1...
(標題一點也不誇張,很是適合0基礎)
<Webpack傻瓜式指南> 
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
https://zhuanlan.zhihu.com/p/...
(這個系列有三篇文章,第三章是一個webpack+react的小項目,跟着作一遍會頗有收穫~)html

另外,也推薦看一下阮一峯es6書中module這一章,弄清楚export/import/export default等等命令,畢竟webpack的各個模塊是靠export/import/require(commonjs)連接起來的,因此這些都要掌握。node

具體到項目的話,webpack有幾個比較基本的概念:
一、loaders:經過不一樣的loaders,webpack能夠處理各式各樣的文件,而後打包到一個文件中(好比bundle.js);
二、plugins:plugins是爲了拓展webpack的功能的,和loaders不一樣的是,loader是用來處理單個文件的(好比json-loader處理.json,sass-loader處理.scss),可是plugins是直接對整個構建過程進行處理(好比自動生成html文件的html-webpack-plugin);
三、others: 這些我也不知道要歸到哪裏去,可是在配置中也是必不可少,包括webpack-dev-server/source-map等等,後面會具體說;
四、配置文件:我這個小項目包括的文件有.babelrc(用來處理babel),webpack.config.js(webpack項目基礎配置文件),package.json(這個文件會記錄全部的devDependencies)。react

而後咱們就一項一項來分析吧:jquery

一、loaders

1) style-loader / css-loader / sass-loaderwebpack

這幾個loader用來處理.css和.scss文件,一塊兒安裝用空格隔開:es6

$ npm install --save-dev style-loader css-loader sass-loader

同時修改webpack.config.js:web

module: {
        loaders: [
        {
            test: /\.scss$/,
            //loaders是依靠正則表達式來測試這個文件是否是這個loader來處理,因此test不能少
            loaders: ['style-loader','css-loader','sass-loader'],
            //"-loader"必定要寫,否則會報錯
            //loaders的處理順序是從右向左,就是會先用sass-loader,其次css-loader,再次style-loader
        }

2) url-loader正則表達式

這個loader是用來處理url連接,就是圖片或者其餘靜態文件。
安裝:npm

$ npm install --save-dev url-loader

webpack.config.js (寫在module裏):

{
            test: /\.(png|jpq)$/,
            loader: 'url? limit = 40000'
        }

3) json-loader

安裝和配置和以前同樣~用來處理json文件

4) babel相關的loaders:

這個包括的就比較多,有babel-core/babel-loader/babel-preset-es2015/babel-preset-react,後面兩個是爲了寫es6和react服務。

//webpack.config.js
        {
            test: /\.jsx$/,
            loader:'babel-loader',
            include: APP_PATH,
            //這個include是說只對這裏面的文件負責,還有一個對應的exclude,就是忽略範圍內的文件, 好比:exclude: './node_modules/';
        }

另外由於babel須要寫的選項比較多,能夠配一個.babelrc在根目錄下:

//.babelrc
{
    'presets':['react','es2015'],
    }
}

以上就是用的比較多的loaders,配完這些webpack就能夠處理json/sass/es6啦~

二、plugins

1) html-webpack-plugin

這個插件的做用就是自動生成html(其實也能夠本身寫,就是加了個bundle.js的script而已,不過感受比較酷):
plugins安裝好了以後要放在webpack.config.js的plugins的數組裏,不要寫在modules裏呀~

//webpack.config.js
    plugins: [
        new HtmlWebpackPlugin({
        //在最前面先定義下HtmlWebpackPlugin--
        //var HtmlWebpackPlugin = require('html-webpack-plugin');
            title: 'searchBar',    //配合html-webpack-plugin的配置
        })
    ],

2) react-transform-hrm

HMR是一個webpack插件,它讓你能瀏覽器中實時觀察模塊修改後的效果,可是若是你想讓它工做,須要對模塊進行額外的配額;
Babel有一個叫作react-transform-hrm的插件,能夠在不對React模塊進行額外的配置的前提下讓HMR正常工做;
安裝:

$ npm install --save-dev babel-plugin-react-transform react-transform-hmr

配置:

//webpack.config.js (plugins裏)
new webpack.HotModuleReplacementPlugin();

而後修改下.babelrc:

{
  "presets": ["react", "es2015"],
  "env": {
    "development": {
    "plugins": [["react-transform", {
       "transforms": [{
         "transform": "react-transform-hmr",

         "imports": ["react"],

         "locals": ["module"]
       }]
     }]]
    }
  }
}

這樣在使用react的時候就能夠熱加載模塊了~

3)UglifyJsPlugin:

壓縮JS代碼;

4)ExtractTextPlugin:

分離CSS和JS文件;
以上兩個插件此次沒有用,先記下來下次用過了再來補~

三、others

1) webpack-dev-server

用來構建本地開發的服務器,可讓瀏覽器監測代碼的修改,並自動刷新修改後的結果;
安裝:

$npm --save-dev webpack-dev-server

webpack-dev-server有如下幾個配置選項:

  • contentBase:默認webpack-dev-server會爲根文件夾提供本地服務器,若是想爲另一個目錄下的文件提供本地服務器,應該在這裏設置其所在目錄(本例設置到「public"目錄)

  • port:設置默認監聽端口,若是省略,默認爲」8080「

  • inline:設置爲true,當源文件改變時會自動刷新頁面

  • historyApiFallback:在開發單頁應用時很是有用,它依賴於HTML5 history API,若是設置爲true,全部的跳轉將指向index.html

    //webpack.config.js
    devServer: {
               contentBase: "./public",//本地服務器所加載的頁面所在的目錄
               historyApiFallback: true,//不跳轉
               inline: true//實時刷新
           }
//package.json
 "scripts": {
    "start": "webpack-dev-server --inline",
  }

而後就能夠用http://localhost:8080/index.html預覽項目啦~

2)source-map:

source maps提供了一種對應編譯文件和源文件的方法,使得編譯後的代碼可讀性更高,也更容易調試。
在學習階段和寫中、小型項目的時候,用eval-source-map,若是是開發大型項目能夠用cheap-module-eval-source-map,會更快。

//webpack.config.js
devtool: 'eval-source-map',

3) 第三方庫:

這個就包括一些咱們比較瞭解的好比react/react-dom/jquery/moment/bootstrap等等啦,配置起來也很方便,首先是安裝:

$npm --save-dev jquery moment react react-dom
$npm install bootstrap@4.0.0-alpha.2 --save-dev

而後在你須要的js文件裏引用這些庫:

import React from 'react';
import ReactDOM from 'react-dom';

var $ = require('jquery');
var moment = require('moment');

而後就能夠愉快地寫各類js、jsx文件啦~

四、配置文件

最後咱們來說一講幾個配置文件的問題:

1) webpack.config.js

上面提到的都是各類肢解,我此次的config文件是這樣的:

var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ROOT_PATH = path.resolve(__dirname);
var APP_PATH = path.resolve(ROOT_PATH, 'app');
var BUILD_PATH = path.resolve(ROOT_PATH, 'build');

module.exports = {
    devtool: 'eval-source-map',
    entry: __dirname + '/app/index.jsx',
//webpack的入口文件只有一個,因此寫的全部components甚至包括css/json什麼的,都要引用在這裏
output:{
    path: __dirname +'/public',
    filename: 'bundle.js',
},
//我這邊是新建了一個folder叫public,用來放index.html和bundle.js
devServer: {
    contentBase: "./public",//本地服務器所加載的頁面所在的目錄
    historyApiFallback: true,//不跳轉
    inline: true//實時刷新
},
plugins: [
    new HtmlWebpackPlugin({
        title: 'searchBar',    //配合html-webpack-plugin的配置
    })
],
module: {
    loaders: [
    {
        test: /\.scss$/,
        loaders: ['style-loader','css-loader','sass-loader'],
    },{
        test: /\.(png|jpq)$/,
        loader: 'url? limit = 40000'
    },{
        test: /\.jsx$/,
        loader:'babel-loader',
        include: APP_PATH,
    }]
},
resolve:{
        extensions: ['','.js', '.jsx']
    },
};

2) package.json

這個文件會在你最開始npm init的時候就生成,一路回車就能夠,後來均可以改~

{
  "name": "serach-bar",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --progress --profile --colors --hot",
    "build": "webpack --progress --profile --colors",
    "test": "karma start"
  },
 //scripts這邊能夠改一下,改start能夠,在終端用npm start,上面有例子~這邊的dev要改的話在終端的命令是'npm run dev;
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.22.1",
    "babel-loader": "^6.2.10",
    "babel-plugin-react-transform": "^2.0.2",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-react": "^6.22.0",
    "babel-preset-react-hmre": "^1.1.1",
    "bootstrap": "^4.0.0-alpha.2",
    "css-loader": "^0.26.1",
    "file-loader": "^0.10.0",
    "html-webpack-plugin": "^2.28.0",
    "jquery": "^3.1.1",
    "jshint": "^2.9.4",
    "jshint-loader": "^0.8.3",
    "json-loader": "^0.5.4",
    "node-sass": "^4.5.0",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "react-transform-catch-errors": "^1.0.2",
    "react-transform-hmr": "^1.0.4",
    "redbox-react": "^1.3.3",
    "sass-loader": "^4.1.1",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.3.0"
  }
}

裝了不少dev,其實用不着那麼多哈哈~

3) .babelrc

{
    'presets':['react','es2015'],
    'env':{
    'development':{
    'presets':['react-hmre']
    }
    }
}

ok,這樣就差很少啦~另外還要注意的是index.jsx/index.js,全部的components都要引用過來,css/scss也是,css文件的話最好有一個main.css進行整合,這樣不會漏掉。
看一眼此次的index.jsx:

// '注意這些import
import '../node_modules/bootstrap/scss/bootstrap.scss';
import './main.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import Search from './components/search';
import Plist from './components/plist';

class App extends React.Component{
    constructor(props){
        super(props);
        this.state={'keyword':''};
        this.refreshKeyword = this.refreshKeyword.bind(this);
    }
    refreshKeyword(name){
        this.setState({'keyword':name});
    }
    render(){
        return (
            <div className = 'container'>
                <section className = 'jumbotron'>
                    <h3 className ='jumbotron-heading'>Search Github Users</h3>
                    <Search sendAction = {this.refreshKeyword} />
                </section>
                <Plist keyword={this.state.keyword} />
            </div>
                )
    }
};

const app = document.createElement('div');
document.body.appendChild(app);
ReactDOM.render(<App />, app);

恩,差很少就是這樣啦~~項目初始化的時候不要忘記npm install --save-dev webpack哦!coding愉快!

相關文章
相關標籤/搜索