@@ -377,9 +377,11 @@ See [boilerplate](https://github.com/webdiscus/webpack-html-scss-boilerplate)
377377 - [ How to pass data into multiple templates] ( #recipe-pass-data-to-templates )
378378 - [ How to use some different template engines] ( #recipe-diff-templates )
379379 - [ How to config ` splitChunks ` ] ( #recipe-split-chunks )
380+ - [ How to keep package name for ** split chunks** from ** node_modules** ] ( #recipe-split-chunks-keep-module-name )
380381 - [ How to split CSS files] ( #recipe-split-css )
381- - [ How to keep package name for split chunks from ** node_modules** ] ( #recipe-split-chunks-keep-module-name )
382- 2 . <a id =" demo-sites " name =" demo-sites " ></a >
382+ 2 . [ Problems & Solutions] ( #solutions )
383+ - [ Automatic resolving of file extensions] ( #solutions-resolve-extensions )
384+ 3 . <a id =" demo-sites " name =" demo-sites " ></a >
383385 Demo sites
384386 - Multiple page e-shop template (` Handlebars ` ) [ demo] ( https://alpine-html-bootstrap.vercel.app/ ) | [ source] ( https://github.com/webdiscus/demo-shop-template-bundler-plugin )
385387 - Design system NIHR: Components, Elements, Layouts (` Handlebars ` ) [ demo] ( https://design-system.nihr.ac.uk ) | [ source] ( https://github.com/webdiscus/design-system )
@@ -5333,6 +5335,105 @@ module.exports = {
53335335> then Webpack concatenates JS code together with CSS in one file and Webpack compilation will failed or generate files with a wrong content.
53345336> Webpack can't differentiate CSS module from JS module, therefore you MUST match only JS files.
53355337
5338+ ---
5339+
5340+ #### [↑ back to contents](#contents)
5341+
5342+ <a id="recipe-split-chunks-keep-module-name" name="recipe-split-chunks-keep-module-name"></a>
5343+
5344+ ### How to keep package name for split chunks from node_modules
5345+
5346+ To save split chunks under a custom name use ` optimization .cacheGroups .{cacheGroup}.name ` as function.
5347+
5348+ For example, many node modules are imported in the ` main .js ` :
5349+
5350+ ` ` ` js
5351+ import { Button } from ' bootstrap' ;
5352+ import _ , { map } from ' underscore' ;
5353+ // ...
5354+ ` ` `
5355+
5356+ There is a template used the ` main .js ` _./src/views/index.html_:
5357+
5358+ ` ` ` html
5359+ < html>
5360+ < head>
5361+ <!-- include source script -->
5362+ < script src= " ./main.js" defer= " defer" >< / script>
5363+ < / head>
5364+ < body>
5365+ < h1> Hello World! < / h1>
5366+ < / body>
5367+ < / html>
5368+ ` ` `
5369+
5370+ Then, use the ` optimization .splitChunks .cacheGroups .{cacheGroup}.name ` as following function:
5371+
5372+ ` ` ` js
5373+ const HtmlBundlerPlugin = require (' html-bundler-webpack-plugin' );
5374+
5375+ module .exports = {
5376+ plugins: [
5377+ new HtmlBundlerPlugin ({
5378+ entry: {
5379+ index: ' src/views/index.html' ,
5380+ },
5381+ js: {
5382+ filename: ' js/[name].[contenthash:8].js' ,
5383+ chunkFilename: ' js/[id].[contenthash:8].js' ,
5384+ },
5385+ }),
5386+ ],
5387+ optimization: {
5388+ runtimeChunk: true ,
5389+ splitChunks: {
5390+ // chunks: 'all', // DO NOT use it here, otherwise the compiled pages will be corrupted
5391+ maxSize: 1000000 , // split chunks bigger than 100KB, defaults is 20KB
5392+ cacheGroups: {
5393+ app: {
5394+ test: / \. (js| ts)$ / , // split only JS files
5395+ chunks: ' all' , // <- use it only in cache groups
5396+ name ({ context }, chunks , groupName ) {
5397+ // save split chunks of the node module under package name
5398+ if (/ [\\ /] node_modules[\\ /] / .test (context)) {
5399+ const moduleName = context .match (/ [\\ /] node_modules[\\ /] (. *? )(?:[\\ /] | $ )/ )[1 ].replace (' @' , ' ' );
5400+ return ` npm.${ moduleName} ` ;
5401+ }
5402+ // save split chunks of the application
5403+ return groupName;
5404+ },
5405+ },
5406+ },
5407+ },
5408+ },
5409+ };
5410+ ` ` `
5411+
5412+ > **Warning**
5413+ >
5414+ > The group name MUST be different from the script names used in the template.
5415+ > Otherwise, a chunk name conflict occurs.
5416+ >
5417+ > For example,
5418+ > if you are already using ` main .js ` in the template, the group name should not be ` main` .
5419+ > Take another name, e.g. ` app` .
5420+
5421+ The split files will be saved like this:
5422+
5423+ ` ` `
5424+ dist/ js/ runtime.9cd0e0f9 .js
5425+ dist/ js/ npm .popperjs / core .f96a1152 .js < - split chunks of node modules
5426+ dist/ js/ npm .bootstrap .f69a4e44 .js
5427+ dist/ js/ npm .underscore .4e44f69a .js
5428+ dist/ js/ main.3010da09 .js < - base code of main script
5429+ dist/ js/ app- 5fa74877 .7044e96a .js < - split chinks of main script
5430+ dist/ js/ app- d6ae2b10.92215a4e .js
5431+ dist/ js/ app- 5fa74877 .1aceb2db .js
5432+
5433+ ` ` `
5434+
5435+ ---
5436+
53365437#### [↑ back to contents](#contents)
53375438
53385439<a id="recipe-split-css" name="recipe-split-css"></a>
@@ -5427,103 +5528,87 @@ If you want save module styles separate from your styles, then load them in a te
54275528
54285529#### [↑ back to contents](#contents)
54295530
5430- <a id="recipe-split-chunks-keep-module-name" name="recipe-split-chunks-keep-module-name"></a>
54315531
5432- ### How to keep package name for split chunks from node_modules
5532+ <a id="solutions" name="solutions"></a>
54335533
5434- To save split chunks under a custom name use ` optimization . cacheGroups .{cacheGroup}. name ` as function.
5534+ ## Problems & Solutions
54355535
5436- For example, many node modules are imported in the ` main .js ` :
54375536
5438- ` ` ` js
5439- import { Button } from ' bootstrap' ;
5440- import _ , { map } from ' underscore' ;
5441- // ...
5442- ` ` `
5537+ <a id="solutions-resolve-extensions" name="solutions-resolve-extensions"></a>
54435538
5444- There is a template used the ` main .js ` _./src/views/index.html_:
5539+ ### Automatic resolving of file extensions
5540+
5541+ Defaults, the Webpack resolves the omitted ` .js ` extension.
5542+ If you use the TypeScript, you can add the ` .ts ` extension to be resolved.
5543+
5544+ For example, you have the files:
54455545
5446- ` ` ` html
5447- < html>
5448- < head>
5449- <!-- include source script -->
5450- < script src= " ./main.js" defer= " defer" >< / script>
5451- < / head>
5452- < body>
5453- < h1> Hello World! < / h1>
5454- < / body>
5455- < / html>
5546+ ` ` `
5547+ - moduleA .js
5548+ - moduleB .ts
5549+ - app .ts
5550+ - app .scss
54565551` ` `
54575552
5458- Then, use the ` optimization . splitChunks . cacheGroups .{cacheGroup}. name ` as following function:
5553+ The file extensions can be omitted:
54595554
5555+ _app.ts_
54605556` ` ` js
5461- const HtmlBundlerPlugin = require (' html-bundler-webpack-plugin' );
5557+ import moduleA from ' ./moduleA' ;
5558+ import moduleB from ' ./moduleB' ;
5559+ ` ` `
5560+
5561+ To allow this magic, you should configure the [resolve.extensions](https://webpack.js.org/configuration/resolve/#resolveextensions) Webpack option.
54625562
5563+ ` ` ` js
54635564module .exports = {
5464- plugins: [
5465- new HtmlBundlerPlugin ({
5466- entry: {
5467- index: ' src/views/index.html' ,
5468- },
5469- js: {
5470- filename: ' js/[name].[contenthash:8].js' ,
5471- chunkFilename: ' js/[id].[contenthash:8].js' ,
5472- },
5473- }),
5474- ],
5475- optimization: {
5476- runtimeChunk: true ,
5477- splitChunks: {
5478- // chunks: 'all', // DO NOT use it here, otherwise the compiled pages will be corrupted
5479- maxSize: 1000000 , // split chunks bigger than 100KB, defaults is 20KB
5480- cacheGroups: {
5481- app: {
5482- test: / \. (js| ts)$ / , // split only JS files
5483- chunks: ' all' , // <- use it only in cache groups
5484- name ({ context }, chunks , groupName ) {
5485- // save split chunks of the node module under package name
5486- if (/ [\\ /] node_modules[\\ /] / .test (context)) {
5487- const moduleName = context .match (/ [\\ /] node_modules[\\ /] (. *? )(?:[\\ /] | $ )/ )[1 ].replace (' @' , ' ' );
5488- return ` npm.${ moduleName} ` ;
5489- }
5490- // save split chunks of the application
5491- return groupName;
5492- },
5493- },
5494- },
5495- },
5565+ // ...
5566+ resolve: {
5567+ extensions: [' .js' , ' .ts' ],
54965568 },
54975569};
54985570` ` `
54995571
5500- > **Warning**
5501- >
5502- > The group name MUST be different from the script names used in the template.
5503- > Otherwise, a chunk name conflict occurs.
5504- >
5505- > For example,
5506- > if you are already using ` main .js ` in the template, the group name should not be ` main` .
5507- > Take another name, e.g. ` app` .
5572+ #### Problem with styles
55085573
5509- The split files will be saved like this :
5574+ If you import style files in your script and want automatically to resolve the ` . css ` , ` . scss ` extensions, e.g., as the following :
55105575
5576+ _app.ts_
5577+ ` ` ` js
5578+ import moduleA from ' ./moduleA' ;
5579+ import moduleB from ' ./moduleB' ;
5580+
5581+ // import app.scss file
5582+ import ' ./app' ; // <= DON'T DO IT!
55115583` ` `
5512- dist/ js/ runtime.9cd0e0f9 .js
5513- dist/ js/ npm .popperjs / core .f96a1152 .js < - split chunks of node modules
5514- dist/ js/ npm .bootstrap .f69a4e44 .js
5515- dist/ js/ npm .underscore .4e44f69a .js
5516- dist/ js/ main.3010da09 .js < - base code of main script
5517- dist/ js/ app- 5fa74877 .7044e96a .js < - split chinks of main script
5518- dist/ js/ app- d6ae2b10.92215a4e .js
5519- dist/ js/ app- 5fa74877 .1aceb2db .js
55205584
5585+ ` ` ` js
5586+ module .exports = {
5587+ // ...
5588+ resolve: {
5589+ extensions: [' .js' , ' .ts' , ' .scss' ], // <= DO NOT mix script and style extensions
5590+ },
5591+ };
55215592` ` `
55225593
5523- #### [↑ back to contents](#contents)
5594+ If you use as above, it won't work.
5595+
5596+ #### Solution
5597+
5598+ To import styles in a script, you MUST use a style extension and not add a style extension to the ` resolve .extensions ` option.
5599+
5600+ _app.ts_
5601+ ` ` ` js
5602+ import moduleA from ' ./moduleA' ;
5603+ import moduleB from ' ./moduleB' ;
5604+
5605+ import ' ./app.scss' ; // <= use the style extension
5606+ ` ` `
55245607
55255608---
55265609
5610+ #### [↑ back to contents](#contents)
5611+
55275612## Also See
55285613
55295614- [ansis][ansis] - The Node.js lib for ANSI color styling of text in terminal
0 commit comments