Skip to content

Commit

Permalink
fix: inject javascripts in the <head> tag for inject:true and scriptL…
Browse files Browse the repository at this point in the history
…oading:'defer'
  • Loading branch information
jantimon committed Jan 3, 2021
1 parent b3c290c commit 4f7064e
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 7 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ node_js:
- 6.9
env:
- WEBPACK_CORE=4
- WEBPACK_CORE=next
- WEBPACK_CORE=5
jobs:
exclude:
- node_js: 6.9
env: WEBPACK_CORE=next
env: WEBPACK_CORE=5
before_install:
- stty columns 120
install:
- travis_retry npm install --ignore-scripts
- travis_retry npm install "webpack@$WEBPACK_CORE" --ignore-scripts
- travis_retry npm install --ignore-scripts --force --legacy-peer-deps
- travis_retry npm install "webpack@$WEBPACK_CORE" --ignore-scripts --force --legacy-peer-deps
script:
- travis_retry npm test
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ Allowed values are as follows:
|**`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|
|**`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 |
|**`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) |
|**`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)|
|**`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)|
|**`publicPath`**|`{String\|'auto'}`|`'auto'`|The publicPath used for script and link tags|
|**`scriptLoading`**|`{'blocking'\|'defer'}`|`'blocking'`| Modern browsers support non blocking javascript loading (`'defer'`) to improve the page startup performance. |
|**`favicon`**|`{String}`|``|Adds the given favicon path to the output HTML|
Expand Down
8 changes: 7 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const { createHtmlTagObject, htmlTagObjectToString, HtmlTagArray } = require('./
const prettyError = require('./lib/errors.js');
const chunkSorter = require('./lib/chunksorter.js');
const getHtmlWebpackPluginHooks = require('./lib/hooks.js').getHtmlWebpackPluginHooks;
const { assert } = require('console');

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

// Assert correct option spelling
assert(this.options.scriptLoading === 'defer' || this.options.scriptLoading === 'blocking', 'scriptLoading needs to be set to "defer" or "blocking');
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');

// Default metaOptions if no template is provided
if (!userOptions.template && this.options.templateContent === false && this.options.meta) {
const defaultMeta = {
Expand Down Expand Up @@ -209,7 +214,8 @@ class HtmlWebpackPlugin {
}))
.then(({ assetTags }) => {
// Inject scripts to body unless it set explicitly to head
const scriptTarget = self.options.inject === 'head' ? 'head' : 'body';
const scriptTarget = self.options.inject === 'head' ||
(self.options.inject !== 'body' && self.options.scriptLoading === 'defer') ? 'head' : 'body';
// Group assets to `head` and `body` tag arrays
const assetGroups = this.generateAssetGroups(assetTags, scriptTarget);
// Allow third-party-plugin authors to reorder and change the assetTags once they are grouped
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
"@types/webpack": "^4.41.8",
"html-minifier-terser": "^5.0.1",
"loader-utils": "^1.2.3",
"lodash": "^4.17.15",
"lodash": "^4.17.20",
"pretty-error": "^2.1.1",
"tapable": "^1.1.3",
"util.promisify": "1.0.0"
Expand Down
23 changes: 23 additions & 0 deletions spec/basic.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2343,6 +2343,29 @@ describe('HtmlWebpackPlugin', () => {
}, [/<selfclosed\/>/], null, done);
});

it('should add the javascript assets to the head for inject:true with scriptLoading:defer', done => {
testHtmlPlugin({
mode: 'production',
entry: path.join(__dirname, 'fixtures/theme.js'),
output: {
path: OUTPUT_DIR,
filename: 'index_bundle.js'
},
module: {
rules: [
{ test: /\.css$/, use: [MiniCssExtractPlugin.loader, 'css-loader'] }
]
},
plugins: [
new MiniCssExtractPlugin({ filename: 'styles.css' }),
new HtmlWebpackPlugin({
scriptLoading: 'defer',
inject: true
})
]
}, ['<script defer="defer" src="index_bundle.js"></script><link href="styles.css" rel="stylesheet"></head>'], null, done);
});

it('should allow to use headTags and bodyTags directly in string literals', done => {
testHtmlPlugin({
mode: 'production',
Expand Down

0 comments on commit 4f7064e

Please sign in to comment.