2019-09-13 09:27:16 +08:00
|
|
|
"use strict";
|
|
|
|
|
2021-07-15 20:51:52 +08:00
|
|
|
require("./helpers/warmup-webpack");
|
|
|
|
|
2019-09-13 09:27:16 +08:00
|
|
|
const path = require("path");
|
|
|
|
const fs = require("graceful-fs");
|
2025-07-03 17:06:45 +08:00
|
|
|
const { Volume, createFsFromVolume } = require("memfs");
|
2019-09-13 09:27:16 +08:00
|
|
|
const rimraf = require("rimraf");
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
const createCompiler = (config) => {
|
2021-07-15 20:51:52 +08:00
|
|
|
const webpack = require("..");
|
2025-07-02 20:10:54 +08:00
|
|
|
|
2019-09-13 09:27:16 +08:00
|
|
|
const compiler = webpack(config);
|
2020-02-15 13:54:52 +08:00
|
|
|
compiler.outputFileSystem = createFsFromVolume(new Volume());
|
2019-09-13 09:27:16 +08:00
|
|
|
return compiler;
|
|
|
|
};
|
|
|
|
|
2019-11-16 03:31:22 +08:00
|
|
|
const tempFolderPath = path.join(__dirname, "ChangesAndRemovalsTemp");
|
2019-09-13 09:27:16 +08:00
|
|
|
const tempFilePath = path.join(tempFolderPath, "temp-file.js");
|
|
|
|
const tempFile2Path = path.join(tempFolderPath, "temp-file2.js");
|
|
|
|
|
2024-07-31 11:31:11 +08:00
|
|
|
const createSingleCompiler = () =>
|
|
|
|
createCompiler({
|
2019-09-13 09:27:16 +08:00
|
|
|
entry: tempFilePath,
|
|
|
|
output: {
|
|
|
|
path: tempFolderPath,
|
|
|
|
filename: "bundle.js"
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2019-10-22 15:51:23 +08:00
|
|
|
const onceDone = (compiler, action) => {
|
|
|
|
let initial = true;
|
|
|
|
compiler.hooks.done.tap("ChangesAndRemovalsTest", () => {
|
|
|
|
if (!initial) return;
|
|
|
|
initial = false;
|
2019-11-07 04:35:54 +08:00
|
|
|
setTimeout(action, 1000);
|
2019-10-22 15:51:23 +08:00
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
const getChanges = (compiler) => {
|
2019-11-15 22:14:03 +08:00
|
|
|
const modifiedFiles = compiler.modifiedFiles;
|
|
|
|
const removedFiles = compiler.removedFiles;
|
|
|
|
return {
|
2025-07-03 17:06:45 +08:00
|
|
|
removed: removedFiles && [...removedFiles],
|
|
|
|
modified: modifiedFiles && [...modifiedFiles]
|
2019-11-15 22:14:03 +08:00
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2025-04-22 20:42:33 +08:00
|
|
|
/**
|
|
|
|
* @param {(err?: unknown) => void} callback callback
|
|
|
|
*/
|
2019-10-22 16:22:15 +08:00
|
|
|
function cleanup(callback) {
|
|
|
|
rimraf(tempFolderPath, callback);
|
2019-09-13 09:27:16 +08:00
|
|
|
}
|
|
|
|
|
2025-04-22 20:42:33 +08:00
|
|
|
/**
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2019-09-13 09:27:16 +08:00
|
|
|
function createFiles() {
|
2019-11-16 03:31:22 +08:00
|
|
|
fs.mkdirSync(tempFolderPath, { recursive: true });
|
2019-11-16 02:47:03 +08:00
|
|
|
|
2019-09-13 09:27:16 +08:00
|
|
|
fs.writeFileSync(
|
|
|
|
tempFilePath,
|
|
|
|
"module.exports = function temp() {return 'temp file';};\n require('./temp-file2')",
|
2025-07-02 20:10:54 +08:00
|
|
|
"utf8"
|
2019-09-13 09:27:16 +08:00
|
|
|
);
|
2019-11-16 02:47:03 +08:00
|
|
|
|
2019-09-13 09:27:16 +08:00
|
|
|
fs.writeFileSync(
|
|
|
|
tempFile2Path,
|
|
|
|
"module.exports = function temp2() {return 'temp file 2';};",
|
2025-07-02 20:10:54 +08:00
|
|
|
"utf8"
|
2019-09-13 09:27:16 +08:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2025-07-02 20:10:54 +08:00
|
|
|
jest.setTimeout(30000);
|
2019-09-13 09:27:16 +08:00
|
|
|
|
2025-07-02 20:10:54 +08:00
|
|
|
describe("ChangesAndRemovals", () => {
|
2025-07-17 00:13:14 +08:00
|
|
|
beforeEach((done) => {
|
|
|
|
cleanup((err) => {
|
2019-10-22 16:22:15 +08:00
|
|
|
if (err) return done(err);
|
|
|
|
createFiles();
|
2019-11-16 03:31:22 +08:00
|
|
|
// Wait 2.5s after creating the files,
|
|
|
|
// otherwise the newly-created files will trigger the webpack watch mode to re-compile.
|
|
|
|
setTimeout(done, 2500);
|
2019-10-22 16:22:15 +08:00
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
2025-07-02 20:10:54 +08:00
|
|
|
|
2019-10-22 16:22:15 +08:00
|
|
|
afterEach(cleanup);
|
2019-09-13 09:27:16 +08:00
|
|
|
|
2025-07-02 20:10:54 +08:00
|
|
|
if (process.env.NO_WATCH_TESTS) {
|
|
|
|
// eslint-disable-next-line jest/no-disabled-tests
|
|
|
|
it.skip("watch tests excluded", () => {});
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
it("should not track modified/removed files during initial watchRun", (done) => {
|
2019-09-13 09:27:16 +08:00
|
|
|
const compiler = createSingleCompiler();
|
2025-07-17 00:13:14 +08:00
|
|
|
const watchRunFinished = new Promise((resolve) => {
|
|
|
|
compiler.hooks.watchRun.tap("ChangesAndRemovalsTest", (compiler) => {
|
2019-11-15 22:14:03 +08:00
|
|
|
expect(getChanges(compiler)).toEqual({
|
|
|
|
removed: undefined,
|
|
|
|
modified: undefined
|
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
resolve();
|
|
|
|
});
|
|
|
|
});
|
2025-07-17 00:13:14 +08:00
|
|
|
const watcher = compiler.watch({ aggregateTimeout: 200 }, (err) => {
|
2019-11-07 04:35:54 +08:00
|
|
|
if (err) done(err);
|
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
|
|
|
|
watchRunFinished.then(() => {
|
2019-10-22 05:59:50 +08:00
|
|
|
watcher.close(done);
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
it("should track modified files when they've been modified", (done) => {
|
2019-09-13 09:27:16 +08:00
|
|
|
const compiler = createSingleCompiler();
|
|
|
|
let watcher;
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
compiler.hooks.watchRun.tap("ChangesAndRemovalsTest", (compiler) => {
|
2019-11-07 04:35:54 +08:00
|
|
|
if (!watcher) return;
|
2019-10-22 05:59:50 +08:00
|
|
|
if (!compiler.modifiedFiles) return;
|
2019-11-15 22:14:03 +08:00
|
|
|
expect(getChanges(compiler)).toEqual({
|
|
|
|
modified: [tempFilePath],
|
|
|
|
removed: []
|
|
|
|
});
|
2019-10-22 05:59:50 +08:00
|
|
|
watcher.close(done);
|
2019-11-07 04:35:54 +08:00
|
|
|
watcher = null;
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
watcher = compiler.watch({ aggregateTimeout: 200 }, (err) => {
|
2019-11-07 04:35:54 +08:00
|
|
|
if (err) done(err);
|
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
|
2019-10-22 15:51:23 +08:00
|
|
|
onceDone(compiler, () => {
|
2019-11-07 04:35:54 +08:00
|
|
|
fs.appendFileSync(tempFilePath, "\nlet x = 'file modified';");
|
2019-10-22 15:51:23 +08:00
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
it("should track removed file when removing file", (done) => {
|
2019-09-13 09:27:16 +08:00
|
|
|
const compiler = createSingleCompiler();
|
|
|
|
let watcher;
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
compiler.hooks.watchRun.tap("ChangesAndRemovalsTest", (compiler) => {
|
2019-11-07 04:35:54 +08:00
|
|
|
if (!watcher) return;
|
|
|
|
if (!compiler.modifiedFiles) return;
|
2019-11-15 22:14:03 +08:00
|
|
|
expect(getChanges(compiler)).toEqual({
|
|
|
|
removed: [tempFilePath],
|
|
|
|
modified: []
|
|
|
|
});
|
2019-10-22 05:59:50 +08:00
|
|
|
watcher.close(done);
|
2019-11-07 04:35:54 +08:00
|
|
|
watcher = null;
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
|
2025-07-17 00:13:14 +08:00
|
|
|
watcher = compiler.watch({ aggregateTimeout: 200 }, (err) => {
|
2019-11-07 04:35:54 +08:00
|
|
|
if (err) done(err);
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
|
2019-10-22 15:51:23 +08:00
|
|
|
onceDone(compiler, () => {
|
2019-11-07 04:35:54 +08:00
|
|
|
fs.unlinkSync(tempFilePath);
|
2019-10-22 15:51:23 +08:00
|
|
|
});
|
2019-09-13 09:27:16 +08:00
|
|
|
});
|
|
|
|
});
|