之前忽略了一個點,如下: 在compiler對象的fs模塊掛載完後,會對傳入的插件進行載入,這個過程在內置插件載入之前。 插件部分單獨講解,所以這個地方先暫時略過。 內置插件全部plugin完畢後,會檢測編譯的回調函數: vue-cli的腳手架生產模式的構建文件build.js中就很明顯的傳了一個回 ...
之前忽略了一個點,如下:
if (options.plugins && Array.isArray(options.plugins)) { compiler.apply.apply(compiler, options.plugins); }
在compiler對象的fs模塊掛載完後,會對傳入的插件進行載入,這個過程在內置插件載入之前。
插件部分單獨講解,所以這個地方先暫時略過。
內置插件全部plugin完畢後,會檢測編譯的回調函數:
if (callback) { if (typeof callback !== "function") throw new Error("Invalid argument: callback"); // 檢測是否有watch選項 if (options.watch === true || (Array.isArray(options) && options.some(o => o.watch))) { const watchOptions = Array.isArray(options) ? options.map(o => o.watchOptions || {}) : (options.watchOptions || {}); return compiler.watch(watchOptions, callback); } compiler.run(callback); }
vue-cli的腳手架生產模式的構建文件build.js中就很明顯的傳了一個回調函數:
webpack(webpackConfig, (err, stats) => { /**/ })
這裡的回調函數主要是輸出一些打包信息,包括打包文件的狀態、打包錯誤提示、打包完成提示等等。
暫時不管這個回調,因此會直接返回compiler,回到預編譯的webpack.js文件中。
又回到了久違的bin/webpack.js,後面的流程簡化後源碼如下:
try { compiler = webpack(options); } catch (err) { /**/ } // --progress用於輸出打包信息 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) { /**/ } // 直接編譯 else compiler.run(compilerCallback);
在返回compiler對象後,此時還未進行打包操作,只是準備好了一切,剩餘的幾步如下:
1、檢測--progress指令,該指令用於將進度輸出到控制台
2、檢測--watch指令或者配置文件中的watch參數,如果有,則打包完後持續檢測相關文件,發生變動立即調用打包操作
3、沒有配置watch則直接進行打包操作,打包完成後調用回調函數
progress這個可以自己去嘗試,可以想象成安裝程式那個界面。
watch指令作用如圖:
打包完進程並不會退出,當修改入口文件並保存後,會立即打包並刷新提示輸出信息。
這裡先暫時不管watch。
最後一步就是打包的操作:
compiler.run(compilerCallback);
傳入的回調函數只是負責輸出打包信息,源碼如下:
function compilerCallback(err, stats) { // 非watch模式下清理緩存 if (!options.watch || err) { compiler.purgeInputFileSystem(); } // 錯誤處理 if (err) { /**/ } // 輸出打包信息 if (outputOptions.json) { process.stdout.write(JSON.stringify(stats.toJson(outputOptions), null, 2) + "\n"); } else if (stats.hash !== lastHash) { lastHash = stats.hash; var statsString = stats.toString(outputOptions); if (statsString) process.stdout.write(statsString + "\n"); } if (!options.watch && stats.hasErrors()) { process.exitCode = 2; } }
stats是打包後生成的信息,將其格式化後通過prcess,stdout.write輸出,這個輸出方式底層就是console.log,上面那個圖中打包完成信息就是通過這行代碼輸出的。
至此,所以與打包過程無關的操作都已經完事,剩下的內容都集中在compiler.run這個調用中。
將目前所知的plugin整理如下: