webpack 的使用其實並無太多難點,對於開發者來講,webpack 是一個黑盒,按照官方配置便可快速的配置開發環境。node
一樣的,若是使用過程當中有一些不常見的報錯或異常行爲,這個 webpack 黑盒 產生報錯或異常的緣由就較難排查。webpack
好比,若是文件 index.js
在被修改後,馬上做爲 webpack 的入口文件,並啓動 webpack 且監聽,會引發持續時間大約 10s 的頻繁的編譯和回調。web
這個現象在 webpack-dev-server 上能夠重現。webpack-dev-server
以 webpack 爲例,代碼以下:oop
const webpack = require('webpack'); const fse = require('fs-extra'); const fs = require('fs'); const path = require('path'); const entryFile = path.join(__dirname, './src/index.js'); const tmpFile = path.join(__dirname, './src/tmp.js'); // 臨時文件複製到入口文件,會觸發持續時間大約 10s 的回調 fse.copySync(tmpFile, entryFile); // 入口文件被修改,一樣會觸發持續時間大約 10s 的回調 // fs.writeFileSync(entryFile, (fs.readFileSync(entryFile).toString() + '')); const webpackConfig = { // 啓動 webpack 監聽 watch: true, entry: { index: './src/index.js' }, output: { path: path.resolve(`./dist/`), // 絕對路徑 filename: '[name].js' } }; let startTime = Date.now(); let loopCount = 0; const compiler = webpack(webpackConfig, function() { console.log( `webpack 觸發回調, 距離 webpack 啓動的時間: ${(Date.now() - startTime) / 1000} s`, `回調次數: ${++loopCount}` ); });
效果:ui
node_modules/watchpack/lib/DirectoryWatcher.js
中有這樣一段代碼:spa
分析這個問題,可能須要一層層理解相關的邏輯,成本很大,那麼,咱們可否經過一些蛛絲馬跡猜測一下問題可能出在哪裏呢?3d
注意到 node_modules/watchpack/lib/DirectoryWatcher.js
中有大量的邏輯涉及到 mtime
,也就是文件的修改時間。咱們發現的編譯和回調持續 10s 左右極有可能和 FS_ACCURACY
的值 10000
有關。code
可能的解決方案server
既然可能和文件的 mtime
有關,那就嘗試把被修改的入口文件的 mtime
修改到 10s(保險起見,大於 10s 更好) 之前,看看可否解決問題。
代碼以下:
// 臨時文件複製到入口文件,會觸發持續時間大約 10s 的回調 fse.copySync(tmpFile, entryFile); // 修改入口文件的 mtime fs.utimesSync(entryFile, ((Date.now() - 10 * 1000)) / 1000, (Date.now() - 10 * 1000) / 1000); // 啓動 webpack...
結果是:
問題解決!
若是入口文件有依賴其餘的模塊且這些模塊也有修改的話,該模塊的文件時間戳也須要修改,這是須要注意的一點。
不過這個方案仍是比較 hack。這個問題已反饋到 webpack 和 watchpack,但從官方的反饋來看,近期修復的可能性不大。