Webpack 是一款模块加载兼打包工具, 能把各种资源, 例如 JS(X), coffee, css(sass/less), 图片等都作为模块来使用和处理

可以直接使用 require 的形式来引入各模块, 即时他们可能需要经过编译, webpack 上有各种健全的加载器(loader)会处理这些事情.

Webpack 优势

  1. webpack 是一 commonJS 的形式来书写脚本的, 但对 AMD/CMD 的支持也很全面, 方便就项目进行代码迁移
  2. 能被模块化的不仅是 JS 了
  3. 开发便捷, 能替代部分 grunt/gulp 工作, 比如打包, 压缩混淆, 图片转 base64等
  4. 扩展性强, 插件机制完善, 特别支持 React 热拔插(react-hot-loader).

安装与配置

常规使用 npm 安装
$npm install -g webpack
如果是常规项目, 还是把依赖写入 package.json 更好

$npm init
$npm install --save-dev webpack
`</pre>

### 配置

每个项目下都必须配置一个 webpack.config.js, 他的作用如同常规的 gulpfile.js, 就是一个配置项, 告诉 webpack 需要做什么

比如:

<pre>`var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');

module.exports = {
  //插件项
  plugins: [commonsPlugin],

  //页面入口文件配置
  entry:{
    index: './src/js/page/entry1.js'
  },

  //文件输出配置
  output:{
    path: 'dist/js/page',
    filename: '[name].js'
  },

  module:{
    //加载器配置
    loaders:[
      {test: /\.css$/, loader: 'style-loader!css-loader'},
      {test: /\.js$/, loader: 'jsx-loader?harmony'},
      {test: /\.scss$/, loader: 'style!css!sass?sourceMap'},
      {test: /\.(png|jpg)$/, loader: 'url-loader?limit-8192'}
    ]
  },
};
`</pre>

#### plugins 插件项

这里使用了一个 CommonsChunkPlugin 的插件, 用于提取多个入口文件的公共部分, 然后生成一个 common.js 来访方便多页面之间的复用

#### entry 是页面入口文件配置, output 是输出配置

决定入口文件要生成什么名字的文件, 存放到哪里

<pre>`{
  entry: {
    page1: './page1',
    //支持数组, 将加载数组中的所有模块, 但一最后一个模块为输出
    page2: ['./entry1','./entry2']
  },
  output:{
    path:'dist/js/page',
    filename: '[name].bundle.js'
  }
}
`</pre>

这段代码最终会生成一个page1.bundle.js, 和一个page2.bundle.js, 并存放到./dist/page下

#### module.loaders 是最关键的配置

告诉 webpack 每一种文件都要用什么加载器来处理
多个 loader 之间用'!'连接
所有加载器都要通过 npm 来加载
配置信息的参数'?limit=8192'表示将所有小于8kb的图片都转为 base64格式, 超过8kb 的图片用 url-loader 来处理

### 运行 webpack

`$webpack --display-error-details`
后面的参数'--display-error-details' 是推荐加上的, 方便出错的时候能查阅更详细的信息
其他主要参数有

<pre>`$webpack --config XXX.js //使用另一份配置文件
$webpack --watch //监听变动并自动打包
$webpack -p //压缩混淆脚本, 这个很重要
$webpack -d //生成 map 隐射文件, 告知哪些模块被最终打包到哪里
`</pre>

### 模块引入

#### HTML

直接在页面&lt;body&gt;中引入 webpack 最终生成的页面脚本即可

<pre>`&lt;body&gt;
  &lt;script scr = 'dist/js/page/common.js'&gt;&lt;/script&gt;
  &lt;script scr = 'dist/js/page/index.js'&gt;&lt;/script&gt;
&lt;/body&gt;
`</pre>

可以看到连样式都不需要, 脚本执行的时候会动态生成&lt;style&gt;并注入 head

#### JS

各脚本模块可以直接用 commonJS 来书写, 并可以直接引入未经编译的模块, 比如 JSX, Sass, coffee 等(只要在 webpack.config.js 中配置好加载器)
看一下编译前的页面入口文件(index.js)

<pre>`require('../../css/reset.scss'); //加载 Reset 模块
require('../../css/allComponent.scss'); //加载组件模块
var React = require('react');
var AppWrap = require('redux').createRedux;
var Provider = require('redux/react').Provider;
var stores = require('AppStore');

var redux = createRedux(stores);
var App = React.createClass({
  render: function(){
    return (
      &lt;Provider redux = {redux}&gt;
        {function() {return &lt;AppWrap /&gt;;}}
      &lt;/Provider&gt;
    );
  }
});

ReactDOM.render(
  &lt;App /&gt;,document.body
);

后续的都由 webpack 处理