作为模块加载和打包神器,只需配置几个文件,加载各种 loader 就可以享受无痛流程化开发。但对于 webpack 这样一个复杂度较高的插件集合,它的整体流程及思想对我们来说还是很透明的。
本文旨在搞清楚从命令行下敲下 webpack 命令,或者配置 npm script 后执行 package.json 中的命令,到工程目录下出现打包的后的 bundle 文件的过程中,webpack都替我们做了哪些工作。
测试用webpack版本为 webpack@3.4.1
webpack.config.js中定义好相关配置,包括 entry、output、module、plugins等,命令行执行 webpack 命令,webpack 便会根据配置文件中的配置进行打包处理文件,并生成最后打包后的文件。
第一步:执行 webpack 命令时,发生了什么?(bin/webpack.js)
命令行执行 webpack 时,如果全局命令行中未找到webpack命令的话,执行本地的node-modules/bin/webpack.js 文件。
在bin/webpack.js中使用 yargs库 解析了命令行的参数,处理了 webpack 的配置对象 options,调用 processOptions() 函数。
// 处理编译相关,核心函数
function processOptions(options) {
// promise风格的处理,暂时还没遇到这种情况的配置
if(typeof options.then === "function") {...}
// 处理传入的options为数组的情况
var firstOptions = [].concat(options)[0];
var statsPresetToOptions = require("../lib/Stats.js").presetToOptions;
// 设置输出的options
var outputOptions = options.stats;
if(typeof outputOptions === "boolean" || typeof outputOptions === "string") {
outputOptions = statsPresetToOptions(outputOptions);
} else if(!outputOptions) {
outputOptions = {};
}
// 处理各种现实相关的参数
ifArg("display", function(preset) {
outputOptions = statsPresetToOptions(preset);
});
...
// 引入lib下的webpack.js,入口文件
var webpack = require("../lib/webpack.js");
// 设置最大错误追踪堆栈
Error.stackTraceLimit = 30;
var lastHash = null;
var compiler;
try {
// 编译,这里是关键,需要进入lib/webpack.js文件查看
compiler = webpack(options);
} catch(e) {
// 错误处理
var WebpackOptionsValidationError = require("../lib/WebpackOptionsValidationError");
if(e instanceof WebpackOptionsValidationError) {
if(argv.color)
console.error("\u001b[1m\u001b[31m" + e.message + "\u001b[39m\u001b[22m");
else
console.error(e.message);
process.exit(1); // eslint-disable-line no-process-exit
}
throw e;
}
// 显示相关参数处理
if(argv.progress) {
var ProgressPlugin = require("../lib/ProgressPlugin");
compiler.apply(new ProgressPlugin({
profile: argv.profile
}));
}
// 编译完后的回调函数
function compilerCallback(err, stats) {}
// watch模式下的处理
if(firstOptions.watch || options.watch) {
var watchOptions = firstOptions.watchOptions || firstOptions.watch || options.watch || {};
if(watchOptions.stdin) {
process.stdin.on("end", function() {
process.exit(0); // eslint-disable-line
});
process.stdin.resume();
}
compiler.watch(watchOptions, compilerCallback);
console.log("\nWebpack is watching the files…\n");
} else
// 调用run()函数,正式进入编译过程
compiler.run(compilerCallback);
}
内容版权声明:除非注明,否则皆为本站原创文章。
