Skip to content

Commit 4f7064e

Browse files
committed
fix: inject javascripts in the <head> tag for inject:true and scriptLoading:'defer'
1 parent b3c290c commit 4f7064e

File tree

5 files changed

+36
-7
lines changed

5 files changed

+36
-7
lines changed

.travis.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@ node_js:
55
- 6.9
66
env:
77
- WEBPACK_CORE=4
8-
- WEBPACK_CORE=next
8+
- WEBPACK_CORE=5
99
jobs:
1010
exclude:
1111
- node_js: 6.9
12-
env: WEBPACK_CORE=next
12+
env: WEBPACK_CORE=5
1313
before_install:
1414
- stty columns 120
1515
install:
16-
- travis_retry npm install --ignore-scripts
17-
- travis_retry npm install "webpack@$WEBPACK_CORE" --ignore-scripts
16+
- travis_retry npm install --ignore-scripts --force --legacy-peer-deps
17+
- travis_retry npm install "webpack@$WEBPACK_CORE" --ignore-scripts --force --legacy-peer-deps
1818
script:
1919
- travis_retry npm test

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ Allowed values are as follows:
146146
|**`template`**|`{String}`|``|`webpack` relative or absolute path to the template. By default it will use `src/index.ejs` if it exists. Please see the [docs](https://github.com/jantimon/html-webpack-plugin/blob/master/docs/template-option.md) for details|
147147
|**`templateContent`**|`{string\|Function\|false}`|false| Can be used instead of `template` to provide an inline template - please read the [Writing Your Own Templates](https://github.com/jantimon/html-webpack-plugin#writing-your-own-templates) section |
148148
|**`templateParameters`**|`{Boolean\|Object\|Function}`| `false`| Allows to overwrite the parameters used in the template - see [example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/template-parameters) |
149-
|**`inject`**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `true` or `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element - see the [inject:false example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position)|
149+
|**`inject`**|`{Boolean\|String}`|`true`|`true \|\| 'head' \|\| 'body' \|\| false` Inject all assets into the given `template` or `templateContent`. When passing `'body'` all javascript resources will be placed at the bottom of the body element. `'head'` will place the scripts in the head element. Passing `true` will add it to the head/body depending on the `scriptLoading` option. Passing `false` will disable automatic injections. - see the [inject:false example](https://github.com/jantimon/html-webpack-plugin/tree/master/examples/custom-insertion-position)|
150150
|**`publicPath`**|`{String\|'auto'}`|`'auto'`|The publicPath used for script and link tags|
151151
|**`scriptLoading`**|`{'blocking'\|'defer'}`|`'blocking'`| Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. |
152152
|**`favicon`**|`{String}`|``|Adds the given favicon path to the output HTML|

index.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const { createHtmlTagObject, htmlTagObjectToString, HtmlTagArray } = require('./
2323
const prettyError = require('./lib/errors.js');
2424
const chunkSorter = require('./lib/chunksorter.js');
2525
const getHtmlWebpackPluginHooks = require('./lib/hooks.js').getHtmlWebpackPluginHooks;
26+
const { assert } = require('console');
2627

2728
const fsStatAsync = promisify(fs.stat);
2829
const fsReadFileAsync = promisify(fs.readFile);
@@ -65,6 +66,10 @@ class HtmlWebpackPlugin {
6566
/** @type {ProcessedHtmlWebpackOptions} */
6667
this.options = Object.assign(defaultOptions, userOptions);
6768

69+
// Assert correct option spelling
70+
assert(this.options.scriptLoading === 'defer' || this.options.scriptLoading === 'blocking', 'scriptLoading needs to be set to "defer" or "blocking');
71+
assert(this.options.inject === true || this.options.inject === false || this.options.inject === 'head' || this.options.inject === 'body', 'inject needs to be set to true, false, "head" or "body');
72+
6873
// Default metaOptions if no template is provided
6974
if (!userOptions.template && this.options.templateContent === false && this.options.meta) {
7075
const defaultMeta = {
@@ -209,7 +214,8 @@ class HtmlWebpackPlugin {
209214
}))
210215
.then(({ assetTags }) => {
211216
// Inject scripts to body unless it set explicitly to head
212-
const scriptTarget = self.options.inject === 'head' ? 'head' : 'body';
217+
const scriptTarget = self.options.inject === 'head' ||
218+
(self.options.inject !== 'body' && self.options.scriptLoading === 'defer') ? 'head' : 'body';
213219
// Group assets to `head` and `body` tag arrays
214220
const assetGroups = this.generateAssetGroups(assetTags, scriptTarget);
215221
// Allow third-party-plugin authors to reorder and change the assetTags once they are grouped

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"@types/webpack": "^4.41.8",
5656
"html-minifier-terser": "^5.0.1",
5757
"loader-utils": "^1.2.3",
58-
"lodash": "^4.17.15",
58+
"lodash": "^4.17.20",
5959
"pretty-error": "^2.1.1",
6060
"tapable": "^1.1.3",
6161
"util.promisify": "1.0.0"

spec/basic.spec.js

+23
Original file line numberDiff line numberDiff line change
@@ -2343,6 +2343,29 @@ describe('HtmlWebpackPlugin', () => {
23432343
}, [/<selfclosed\/>/], null, done);
23442344
});
23452345

2346+
it('should add the javascript assets to the head for inject:true with scriptLoading:defer', done => {
2347+
testHtmlPlugin({
2348+
mode: 'production',
2349+
entry: path.join(__dirname, 'fixtures/theme.js'),
2350+
output: {
2351+
path: OUTPUT_DIR,
2352+
filename: 'index_bundle.js'
2353+
},
2354+
module: {
2355+
rules: [
2356+
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }
2357+
]
2358+
},
2359+
plugins: [
2360+
new MiniCssExtractPlugin({ filename: 'styles.css' }),
2361+
new HtmlWebpackPlugin({
2362+
scriptLoading: 'defer',
2363+
inject: true
2364+
})
2365+
]
2366+
}, ['<script defer="defer" src="index_bundle.js"></script><link href="styles.css" rel="stylesheet"></head>'], null, done);
2367+
});
2368+
23462369
it('should allow to use headTags and bodyTags directly in string literals', done => {
23472370
testHtmlPlugin({
23482371
mode: 'production',

0 commit comments

Comments
 (0)