webpack 的使用其實並無太多難點,對於開發者來講,webpack 是一個黑盒,按照官方配置便可快速的配置開發環境。node
一樣的,若是使用過程當中有一些不常見的報錯或異常行爲,這個 webpack 黑盒 產生報錯或異常的緣由就較難排查。webpack
好比,若是文件 index.js
在被修改後,馬上做爲 webpack 的入口文件,並啓動 webpack 且監聽,會引發持續時間大約 10s 的頻繁的編譯和回調。web
這個現象在 webpack-dev-server 上能夠重現。bash
以 webpack 爲例,代碼以下:webpack-dev-server
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}`
);
});
複製代碼
效果:oop
尋找相關代碼ui
node_modules/watchpack/lib/DirectoryWatcher.js
中有這樣一段代碼:spa
是 watchpack 的問題,仍是 webpack 的問題,仍是 webpack 和 watchpack 的配合的問題?3d
分析這個問題,可能須要一層層理解相關的邏輯,成本很大,那麼,咱們可否經過一些蛛絲馬跡猜測一下問題可能出在哪裏呢?code
注意到 node_modules/watchpack/lib/DirectoryWatcher.js
中有大量的邏輯涉及到 mtime
,也就是文件的修改時間。咱們發現的編譯和回調持續 10s 左右極有可能和 FS_ACCURACY
的值 10000
有關。
可能的解決方案
既然可能和文件的 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,但從官方的反饋來看,近期修復的可能性不大。