Skip to content

Commit f3896e3

Browse files
committed
fix: if used splitChunks.chunks option then this options will be removed and will be displayed a warning
1 parent dcd0ea5 commit f3896e3

20 files changed

Lines changed: 246 additions & 14 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# Change log
22

3+
## 4.5.1 (2024-11-28)
4+
5+
- fix: if used `splitChunks.chunks` option then this options will be removed and will be displayed a warning
6+
This option make no sense, because we will split only scripts.
7+
- docs: update readme
8+
39
## 4.5.0 (2024-11-25)
410

511
- feat: add limited support the HMR for styles imported in JavaScript files

README.md

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ module.exports = {
398398
> Don't use Webpack's `output.filename`, hold all relevant settings in one place - in plugin options.\
399399
> Both places have the same effect, but `js.filename` has priority over `output.filename`.
400400
401+
For `splitChunks` see [How to configure splitChunks](#recipe-split-chunks).
402+
401403
No additional template loader is required. The plugin handles templates with base `EJS`-like syntax automatically.
402404
The default templating engine is [Eta](https://eta.js.org).
403405

@@ -537,7 +539,7 @@ See [boilerplate](https://github.com/webdiscus/webpack-html-scss-boilerplate)
537539
- [How to process a PHP template](#recipe-preprocessor-php)
538540
- [How to pass data into multiple templates](#recipe-pass-data-to-templates)
539541
- [How to use some different template engines](#recipe-diff-templates)
540-
- [How to config `splitChunks`](#recipe-split-chunks)
542+
- [How to configure `splitChunks`](#recipe-split-chunks)
541543
- [How to keep package name for **split chunks** from **node_modules**](#recipe-split-chunks-keep-module-name)
542544
- [How to split CSS files](#recipe-split-css)
543545
2. [Problems & Solutions](#solutions)
@@ -6251,20 +6253,21 @@ module.exports = {
62516253
62526254
<a id="recipe-split-chunks" name="recipe-split-chunks"></a>
62536255
6254-
### How to config `splitChunks`
6256+
### How to configure `splitChunks`
62556257
62566258
Webpack tries to split every entry file, include template files, which completely breaks the compilation process in the plugin.
62576259
62586260
To avoid this issue, you must specify which scripts should be split, using `optimization.splitChunks.cacheGroups`:
62596261
6260-
```js
6262+
```diff
62616263
module.exports = {
62626264
optimization: {
62636265
splitChunks: {
6266+
- chunks: 'all', // <= DO NOT use this here
62646267
cacheGroups: {
62656268
scripts: {
62666269
test: /\.(js|ts)$/, // <= IMPORTANT: split only script files
6267-
chunks: 'all',
6270+
+ chunks: 'all', // <= DEFINE it here only
62686271
},
62696272
},
62706273
},
@@ -6276,6 +6279,17 @@ module.exports = {
62766279
>
62776280
> In the `test` option must be specified all extensions of scripts which should be split.
62786281
6282+
> ⚠️ **Warning**
6283+
>
6284+
> DO NOT use the `chunks: 'all'` option globally!
6285+
>
6286+
> The `splitChunks.chunks: 'all'` option splits all types of chunks, but it make no sense, because we need split only scripts.
6287+
> Templates, CSS, images and other assets can't be split.
6288+
>
6289+
> Define `chunks: 'all'` only in a cache group where is specified the `test` option for your scripts.
6290+
>
6291+
> ‼️ The `splitChunks.chunks` option will be automatically removed, because some assets can't be resolved or output files may be corrupted!
6292+
62796293
See details by [splitChunks.cacheGroups](https://webpack.js.org/plugins/split-chunks-plugin/#splitchunkscachegroups).
62806294
62816295
For example, in a template are used the scripts and styles from `node_modules`:
@@ -6299,7 +6313,7 @@ For example, in a template are used the scripts and styles from `node_modules`:
62996313
> In the generated HTML, all script tags remain in their original places, and the split chunks will be added there
63006314
> in the order in which Webpack generated them.
63016315
6302-
In this use case the `optimization.cacheGroups.{cacheGroup}.test` option must match exactly only JS files from `node_modules`:
6316+
In this use case the `optimization.splitChunks.cacheGroups.{cacheGroup}.test` option must match exactly only JS files from `node_modules`:
63036317
63046318
```js
63056319
module.exports = {
@@ -6309,8 +6323,7 @@ module.exports = {
63096323
cacheGroups: {
63106324
vendor: {
63116325
test: /[\\/]node_modules[\\/].+\.(js|ts)$/, // <= IMPORTANT: split only script files
6312-
name: 'vendor',
6313-
chunks: 'all',
6326+
chunks: 'all', // <= DEFINE it here only
63146327
},
63156328
},
63166329
},
@@ -6332,7 +6345,7 @@ module.exports = {
63326345
63336346
### How to keep package name for split chunks from node_modules
63346347
6335-
To save split chunks under a custom name use `optimization.cacheGroups.{cacheGroup}.name` as function.
6348+
To save split chunks under a custom name use `optimization.splitChunks.cacheGroups.{cacheGroup}.name` as function.
63366349
63376350
For example, many node modules are imported in the `main.js`:
63386351
@@ -6376,12 +6389,11 @@ module.exports = {
63766389
optimization: {
63776390
runtimeChunk: true,
63786391
splitChunks: {
6379-
// chunks: 'all', // DO NOT use it here, otherwise the compiled pages will be corrupted
63806392
maxSize: 1000000, // split chunks bigger than 100KB, defaults is 20KB
63816393
cacheGroups: {
63826394
app: {
63836395
test: /\.(js|ts)$/, // <= IMPORTANT: split only script files
6384-
chunks: 'all', // <= use it only in cache groups
6396+
chunks: 'all', // <= define it only in a cache group
63856397
name({ context }, chunks, groupName) {
63866398
// save split chunks of the node module under package name
63876399
if (/[\\/]node_modules[\\/]/.test(context)) {

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "html-bundler-webpack-plugin",
3-
"version": "4.5.0",
3+
"version": "4.5.1",
44
"description": "HTML Bundler Plugin for Webpack renders HTML templates containing source files of scripts, styles, images. Supports template engines: Eta, EJS, Handlebars, Nunjucks, Pug, TwigJS. Alternative to html-webpack-plugin.",
55
"keywords": [
66
"html",

src/Plugin/AssetCompiler.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -916,6 +916,16 @@ class AssetCompiler {
916916

917917
this.collection.addEntry(entry);
918918

919+
// reserved solution
920+
// problem: if used `splitChunks.chunks` then, some assets may not found in chunkModules
921+
// solution: the `chunks` option must be defined in `splitChunks.cacheGroups.{cacheGroup}.chunks` only
922+
// see the test `resolve-image-in-multipages-splitChunks`
923+
// for (const [key, module] of this.compilation._modules.entries()) {
924+
// if (key.startsWith(ASSET_MODULE_TYPE_RESOURCE)) {
925+
// this.assetResource.saveData(module);
926+
// }
927+
// }
928+
919929
for (const module of chunkModules) {
920930
const { buildInfo, resource, resourceResolveData } = module;
921931
const { isScript, isImportedStyle, isCSSStyleSheet } = resourceResolveData?._bundlerPluginMeta || {};

src/Plugin/Collection.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,17 +288,24 @@ class Collection {
288288
const splitChunkIds = new Set();
289289
const chunkCache = new Map();
290290

291+
//console.log('### chunks: ', chunks);
292+
//console.log('### assets: ', assets); // 'img/apple.02a7c382.png': CachedSource
293+
//console.log('### namedChunkGroups: ', namedChunkGroups);
294+
//console.log('### chunkGraph: ', chunkGraph.moduleGraph._moduleMap);
295+
291296
for (let [resource, { type, name, entries }] of this.assets) {
292297
if (type !== Collection.type.script) continue;
293298

294299
const entrypoint = namedChunkGroups.get(name);
295300

301+
//console.log('### auxiliaryFiles: ', { name, entrypoint });
302+
296303
// prevent error when in watch mode after removing a script in the template
297304
if (!entrypoint) continue;
298305

299306
const chunkFiles = new Set();
300307

301-
for (const { id, files } of entrypoint.chunks) {
308+
for (const { id, files, auxiliaryFiles } of entrypoint.chunks) {
302309
for (const file of files) {
303310
const info = assetsInfo.get(file);
304311

@@ -311,6 +318,8 @@ class Collection {
311318
if (isJavascript && info.hotModuleReplacement !== true) chunkFiles.add(file);
312319
}
313320
splitChunkIds.add(id);
321+
322+
//console.log('### auxiliaryFiles: ', { id, files, auxiliaryFiles });
314323
}
315324

316325
const hasSplitChunks = chunkFiles.size > 1;

src/Plugin/Messages/Warnings.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const { greenBright, redBright, reset, black } = require('ansis');
2+
const { outToConsole } = require('../../Common/Helpers');
3+
const Config = require('../../Common/Config');
4+
5+
const { pluginLabel } = Config.get();
6+
const headerWarning = `\n${reset.black.bgYellow` ${pluginLabel} ${black.bg(227)` WARNING `}`}\n`;
7+
8+
const optionSplitChunksChunksAllWarning = () => {
9+
const message = `DO NOT use the ${redBright`chunks: 'all'`} option globally!
10+
The ${redBright`splitChunks.chunks`} option is automatically deleted, because it corrupts output files generated by this plugin!
11+
12+
${black.bgYellowBright` SOLUTION `}
13+
Define the ${greenBright`chunks`} option in ${greenBright`'splitChunks.cacheGroups.{group}.chunks'`}, e.g.:
14+
15+
splitChunks: {
16+
${redBright`- chunks: 'all',`} // <= DO NOT use this here
17+
cacheGroups: {
18+
myGroup: {
19+
test: /\\.(js|ts)$/, // <= IMPORTANT: split only script files
20+
${greenBright`+ chunks: 'all',`} // <= DEFINE it here only
21+
},
22+
},
23+
},
24+
`;
25+
26+
outToConsole(headerWarning + message);
27+
};
28+
29+
module.exports = {
30+
optionSplitChunksChunksAllWarning,
31+
};

src/Plugin/Option.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const path = require('path');
22
const { isWin, isFunction, pathToPosix } = require('../Common/Helpers');
33
const { postprocessException, beforeEmitException } = require('./Messages/Exception');
4+
const { optionSplitChunksChunksAllWarning } = require('./Messages/Warnings');
45

56
const Preprocessor = require('../Loader/Preprocessor');
67
const PluginService = require('../Plugin/PluginService');
@@ -99,8 +100,16 @@ class Option {
99100
* @param {Object} compiler The Webpack compiler.
100101
*/
101102
initWebpack(compiler) {
102-
const options = compiler.options;
103103
const { entry, js, css } = this.options;
104+
const options = compiler.options;
105+
const splitChunks = options?.optimization?.splitChunks?.chunks;
106+
107+
if (splitChunks && splitChunks === 'all') {
108+
//
109+
delete options.optimization.splitChunks.chunks;
110+
optionSplitChunksChunksAllWarning();
111+
//console.log('*** options: ', options.optimization.splitChunks);
112+
}
104113

105114
this.compiler = compiler;
106115
this.assetEntry = this.pluginContext.assetEntry;
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<title>Test</title>
5+
</head>
6+
<body>
7+
<h1>Hello World!</h1>
8+
</body>
9+
</html>
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
const path = require('path');
2+
const HtmlBundlerPlugin = require('@test/html-bundler-webpack-plugin');
3+
4+
module.exports = {
5+
mode: 'production',
6+
7+
output: {
8+
path: path.join(__dirname, 'dist/'),
9+
},
10+
11+
plugins: [
12+
new HtmlBundlerPlugin({
13+
entry: {
14+
index: './src/index.html',
15+
},
16+
}),
17+
],
18+
19+
optimization: {
20+
splitChunks: {
21+
chunks: 'all', // <= DO NOT use this here, it doesn't make sense because we will split only scripts in a group
22+
cacheGroups: {
23+
vendor: {
24+
test: /[\\/]node_modules[\\/].+\.(js|ts)$/, // <= IMPORTANT: split only script files
25+
name: 'vendor',
26+
chunks: 'all', // <= DEFINE `chunks: 'all'` only in a cache group
27+
},
28+
default: {
29+
minChunks: 2,
30+
reuseExistingChunk: true,
31+
enforce: true,
32+
},
33+
},
34+
},
35+
},
36+
};
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<html>
2+
<head>
3+
</head>
4+
<body>
5+
<h1>About</h1>
6+
<!-- test resolving the same image in diff templates: ERROR -->
7+
<img src="img/apple.02a7c382.png" />
8+
<!-- test resolving the diff image in diff templates: OK -->
9+
<img src="img/pear.6b9b072a.png" />
10+
</body>
11+
</html>

0 commit comments

Comments
 (0)