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,但从官方的反馈来看,近期修复的可能性不大。