Skip to content

Commit

Permalink
test: case for watch/serve and reemitting assets (#1812)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait authored Jun 21, 2023
1 parent a214736 commit 5c15284
Show file tree
Hide file tree
Showing 2 changed files with 150 additions and 0 deletions.
13 changes: 13 additions & 0 deletions spec/fixtures/html-template-with-image.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Test</title>
</head>
<body>
<p>Some unique text</p>
<div>
<img src="./logo.png" alt="Logo">
</div>
</body>
</html>
137 changes: 137 additions & 0 deletions spec/hot.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const DEFAULT_LOADER = require.resolve('../lib/loader.js') + '?force';
const DEFAULT_TEMPLATE = DEFAULT_LOADER + '!' + require.resolve('../default_index.ejs');

jest.setTimeout(30000);

process.on('unhandledRejection', r => console.log(r));

describe('HtmlWebpackPluginHMR', () => {
Expand Down Expand Up @@ -85,4 +86,140 @@ describe('HtmlWebpackPluginHMR', () => {
})
.then(() => compiler.stopWatching());
});

it('should re-emit favicon and assets from a loader if watch is active', () => {
const template = path.join(__dirname, './fixtures/html-template-with-image.html');
const config = {
mode: 'development',
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
assetModuleFilename: '[name][ext]',
path: OUTPUT_DIR
},
module: {
rules: [
{
test: /\.html$/,
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
favicon: path.join(__dirname, './fixtures/favicon.ico'),
template
})
]
};

const templateContent = fs.readFileSync(template, 'utf-8');
const compiler = new WebpackRecompilationSimulator(webpack(config));
const jsFileTempPath = compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
const expected = ['logo.png', 'main.js', 'favicon.ico', 'index.html'];

return compiler.startWatching()
// Change the template file and compile again
.then((stats) => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(jsFileTempPath, 'module.exports = function calc(a, b){ return a - b };');

return compiler.waitForWatchRunComplete();
})
.then(stats => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(template, templateContent.replace(/Some unique text/, 'Some other unique text'));

return compiler.waitForWatchRunComplete();
})
.then((stats) => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(template, templateContent);
})
.then(() => compiler.stopWatching());
});

it('should re-emit favicon and assets from a loader if watch is active and clean enabled', () => {
const expected = ['logo.png', 'main.js', 'favicon.ico', 'index.html'];

class MyPlugin {
apply (compiler) {
compiler.hooks.thisCompilation.tap({ name: this.constructor.name }, (compilation) => {
return compilation.hooks.processAssets.tap(
{ name: this.constructor.name, stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE },
(assets) => {
expect(expected.every(val => Object.keys(assets).includes(val))).toBe(true);
}
);
});
}
}

const template = path.join(__dirname, './fixtures/html-template-with-image.html');
const config = {
mode: 'development',
entry: path.join(__dirname, 'fixtures/index.js'),
output: {
clean: true,
assetModuleFilename: '[name][ext]',
path: OUTPUT_DIR
},
module: {
rules: [
{
test: /\.html$/,
loader: 'html-loader'
}
]
},
plugins: [
new HtmlWebpackPlugin({
favicon: path.join(__dirname, './fixtures/favicon.ico'),
template
}),
new MyPlugin()
]
};

const templateContent = fs.readFileSync(template, 'utf-8');
const compiler = new WebpackRecompilationSimulator(webpack(config));
const jsFileTempPath = compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));

return compiler.startWatching()
// Change the template file and compile again
.then((stats) => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(jsFileTempPath, 'module.exports = function calc(a, b){ return a - b };');

return compiler.waitForWatchRunComplete();
})
.then(stats => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(template, templateContent.replace(/Some unique text/, 'Some other unique text'));

return compiler.waitForWatchRunComplete();
})
.then((stats) => {
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
expect(stats.compilation.errors).toEqual([]);
expect(stats.compilation.warnings).toEqual([]);

fs.writeFileSync(template, templateContent);
})
.then(() => compiler.stopWatching());
});
});

0 comments on commit 5c15284

Please sign in to comment.