作为模块加载和打包神器,只需配置几个文件,加载各种 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); }
内容版权声明:除非注明,否则皆为本站原创文章。