Skip to content

Commit 5c15284

Browse files
test: case for watch/serve and reemitting assets (#1812)
1 parent a214736 commit 5c15284

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8"/>
5+
<title>Test</title>
6+
</head>
7+
<body>
8+
<p>Some unique text</p>
9+
<div>
10+
<img src="./logo.png" alt="Logo">
11+
</div>
12+
</body>
13+
</html>

spec/hot.spec.js

+137
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ const DEFAULT_LOADER = require.resolve('../lib/loader.js') + '?force';
2020
const DEFAULT_TEMPLATE = DEFAULT_LOADER + '!' + require.resolve('../default_index.ejs');
2121

2222
jest.setTimeout(30000);
23+
2324
process.on('unhandledRejection', r => console.log(r));
2425

2526
describe('HtmlWebpackPluginHMR', () => {
@@ -85,4 +86,140 @@ describe('HtmlWebpackPluginHMR', () => {
8586
})
8687
.then(() => compiler.stopWatching());
8788
});
89+
90+
it('should re-emit favicon and assets from a loader if watch is active', () => {
91+
const template = path.join(__dirname, './fixtures/html-template-with-image.html');
92+
const config = {
93+
mode: 'development',
94+
entry: path.join(__dirname, 'fixtures/index.js'),
95+
output: {
96+
assetModuleFilename: '[name][ext]',
97+
path: OUTPUT_DIR
98+
},
99+
module: {
100+
rules: [
101+
{
102+
test: /\.html$/,
103+
loader: 'html-loader'
104+
}
105+
]
106+
},
107+
plugins: [
108+
new HtmlWebpackPlugin({
109+
favicon: path.join(__dirname, './fixtures/favicon.ico'),
110+
template
111+
})
112+
]
113+
};
114+
115+
const templateContent = fs.readFileSync(template, 'utf-8');
116+
const compiler = new WebpackRecompilationSimulator(webpack(config));
117+
const jsFileTempPath = compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
118+
const expected = ['logo.png', 'main.js', 'favicon.ico', 'index.html'];
119+
120+
return compiler.startWatching()
121+
// Change the template file and compile again
122+
.then((stats) => {
123+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
124+
expect(stats.compilation.errors).toEqual([]);
125+
expect(stats.compilation.warnings).toEqual([]);
126+
127+
fs.writeFileSync(jsFileTempPath, 'module.exports = function calc(a, b){ return a - b };');
128+
129+
return compiler.waitForWatchRunComplete();
130+
})
131+
.then(stats => {
132+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
133+
expect(stats.compilation.errors).toEqual([]);
134+
expect(stats.compilation.warnings).toEqual([]);
135+
136+
fs.writeFileSync(template, templateContent.replace(/Some unique text/, 'Some other unique text'));
137+
138+
return compiler.waitForWatchRunComplete();
139+
})
140+
.then((stats) => {
141+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
142+
expect(stats.compilation.errors).toEqual([]);
143+
expect(stats.compilation.warnings).toEqual([]);
144+
145+
fs.writeFileSync(template, templateContent);
146+
})
147+
.then(() => compiler.stopWatching());
148+
});
149+
150+
it('should re-emit favicon and assets from a loader if watch is active and clean enabled', () => {
151+
const expected = ['logo.png', 'main.js', 'favicon.ico', 'index.html'];
152+
153+
class MyPlugin {
154+
apply (compiler) {
155+
compiler.hooks.thisCompilation.tap({ name: this.constructor.name }, (compilation) => {
156+
return compilation.hooks.processAssets.tap(
157+
{ name: this.constructor.name, stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ANALYSE },
158+
(assets) => {
159+
expect(expected.every(val => Object.keys(assets).includes(val))).toBe(true);
160+
}
161+
);
162+
});
163+
}
164+
}
165+
166+
const template = path.join(__dirname, './fixtures/html-template-with-image.html');
167+
const config = {
168+
mode: 'development',
169+
entry: path.join(__dirname, 'fixtures/index.js'),
170+
output: {
171+
clean: true,
172+
assetModuleFilename: '[name][ext]',
173+
path: OUTPUT_DIR
174+
},
175+
module: {
176+
rules: [
177+
{
178+
test: /\.html$/,
179+
loader: 'html-loader'
180+
}
181+
]
182+
},
183+
plugins: [
184+
new HtmlWebpackPlugin({
185+
favicon: path.join(__dirname, './fixtures/favicon.ico'),
186+
template
187+
}),
188+
new MyPlugin()
189+
]
190+
};
191+
192+
const templateContent = fs.readFileSync(template, 'utf-8');
193+
const compiler = new WebpackRecompilationSimulator(webpack(config));
194+
const jsFileTempPath = compiler.addTestFile(path.join(__dirname, 'fixtures/index.js'));
195+
196+
return compiler.startWatching()
197+
// Change the template file and compile again
198+
.then((stats) => {
199+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
200+
expect(stats.compilation.errors).toEqual([]);
201+
expect(stats.compilation.warnings).toEqual([]);
202+
203+
fs.writeFileSync(jsFileTempPath, 'module.exports = function calc(a, b){ return a - b };');
204+
205+
return compiler.waitForWatchRunComplete();
206+
})
207+
.then(stats => {
208+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
209+
expect(stats.compilation.errors).toEqual([]);
210+
expect(stats.compilation.warnings).toEqual([]);
211+
212+
fs.writeFileSync(template, templateContent.replace(/Some unique text/, 'Some other unique text'));
213+
214+
return compiler.waitForWatchRunComplete();
215+
})
216+
.then((stats) => {
217+
expect(expected.every(val => Object.keys(stats.compilation.assets).includes(val))).toBe(true);
218+
expect(stats.compilation.errors).toEqual([]);
219+
expect(stats.compilation.warnings).toEqual([]);
220+
221+
fs.writeFileSync(template, templateContent);
222+
})
223+
.then(() => compiler.stopWatching());
224+
});
88225
});

0 commit comments

Comments
 (0)