引言
目前,几乎所有业务的开发构建都会用到 webpack 。的确,作为模块加载和打包神器,只需配置几个文件,加载各种 loader 就可以享受无痛流程化开发。但对于 webpack 这样一个复杂度较高的插件集合,它的整体流程及思想对我们来说还是很透明的。那么接下来我会带你了解 webpack 这样一个构建黑盒,首先来谈谈它的流程。
准备工作
1. webstorm 中配置 webpack-webstorm-debugger-script
在开始了解之前,必须要能对 webpack 整个流程进行 debug ,配置过程比较简单。
先将 webpack-webstorm-debugger-script 中的 webstorm-debugger.js 置于webpack.config.js 的同一目录下,搭建好你的脚手架后就可以直接 Debug 这个 webstorm-debugger.js 文件了。
2. webpack.config.js 配置
估计大家对 webpack.config.js 的配置也尝试过不少次了,这里就大致对这个配置文件进行个分析。
var path = require('path');
var node_modules = path.resolve(__dirname, 'node_modules');
var pathToReact = path.resolve(node_modules, 'react/dist/react.min.js');
module.exports = {
// 入口文件,是模块构建的起点,同时每一个入口文件对应最后生成的一个 chunk。
entry: {
bundle: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
path.resolve(__dirname, 'app/app.js')
]
},
// 文件路径指向(可加快打包过程)。
resolve: {
alias: {
'react': pathToReact
}
},
// 生成文件,是模块构建的终点,包括输出文件与输出路径。
output: {
path: path.resolve(__dirname, 'build'),
filename: '[name].js'
},
// 这里配置了处理各模块的 loader ,包括 css 预处理 loader ,es6 编译 loader,图片处理 loader。
module: {
loaders: [
{
test: /\.js$/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
],
noParse: [pathToReact]
},
// webpack 各插件对象,在 webpack 的事件流中执行对应的方法。
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
除此之外再大致介绍下 webpack 的一些核心概念:
loader:能转换各类资源,并处理成对应模块的加载器。loader 间可以串行使用。
chunk:code splitting 后的产物,也就是按需加载的分块,装载了不同的 module。
对于 module 和 chunk 的关系可以参照 webpack 官方的这张图:
plugin:webpack 的插件实体,这里以 UglifyJsPlugin 为例。
function UglifyJsPlugin(options) {
this.options = options;
}
module.exports = UglifyJsPlugin;
UglifyJsPlugin.prototype.apply = function(compiler) {
compiler.plugin("compilation", function(compilation) {
compilation.plugin("build-module", function(module) {
});
compilation.plugin("optimize-chunk-assets", function(chunks, callback) {
// Uglify 逻辑
});
compilation.plugin("normal-module-loader", function(context) {
});
});
};
在 webpack 中你经常可以看到 compilation.plugin(‘xxx’, callback) ,你可以把它当作是一个事件的绑定,这些事件在打包时由 webpack 来触发。
3. 流程总览
在具体流程学习前,可以先通过这幅 webpack 整体流程图 了解一下大致流程(建议保存下来查看)。
shell 与 config 解析
每次在命令行输入 webpack 后,操作系统都会去调用 ./node_modules/.bin/webpack 这个 shell 脚本。这个脚本会去调用 ./node_modules/webpack/bin/webpack.js 并追加输入的参数,如 -p , -w 。(图中 webpack.js 是 webpack 的启动文件,而 $@ 是后缀参数)
在 webpack.js 这个文件中 webpack 通过 optimist 将用户配置的 webpack.config.js 和 shell 脚本传过来的参数整合成 options 对象传到了下一个流程的控制对象中。
1. optimist
和 commander 一样,optimist 实现了 node 命令行的解析,其 API 调用非常方便。
var optimist