Skip to content

Commit 6f130e2

Browse files
committed
docs: add the "Problems & Solutions"
1 parent de494cf commit 6f130e2

1 file changed

Lines changed: 159 additions & 74 deletions

File tree

README.md

Lines changed: 159 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -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
54635564
module.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

Comments
 (0)