UNPKG

11 kBMarkdownView Raw
1Script Extension for HTML Webpack Plugin
2========================================
3[![npm version](https://badge.fury.io/js/script-ext-html-webpack-plugin.svg)](http://badge.fury.io/js/script-ext-html-webpack-plugin) [![Dependency Status](https://david-dm.org/numical/script-ext-html-webpack-plugin.svg)](https://david-dm.org/numical/script-ext-html-webpack-plugin) [![Build status](https://travis-ci.org/numical/script-ext-html-webpack-plugin.svg)](https://travis-ci.org/numical/script-ext-html-webpack-plugin) [![js-semistandard-style](https://img.shields.io/badge/code%20style-semistandard-brightgreen.svg?style=flat-square)](https://github.com/Flet/semistandard)
4
5[![NPM](https://nodei.co/npm/script-ext-html-webpack-plugin.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/script-ext-html-webpack-plugin/)
6
7
8Enhances [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin)
9functionality with different deployment options for your scripts including:
10- [`async`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes) attribute;
11- [`defer`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes) attribute;
12- [`type="module"`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#Attributes) attribute;
13- inlining;
14- [`preload`](https://www.w3.org/TR/preload/) resource hint;
15- [`prefetch`](https://www.w3.org/TR/resource-hints/#dfn-prefetch) resource hint
16
17This is an extension plugin for the [webpack](http://webpack.github.io) plugin [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) - a plugin that simplifies the creation of HTML files to serve your webpack bundles.
18
19The raw [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) incorporates all webpack-generated javascipt as synchronous`<script>` elements in the generated html. This plugin allows you to:
20- add attributes to these elements;
21- inline the code in the elements;
22- add asynchronous scripts to prefetch and preload resource hints.
23
24Installation
25------------
26You must be running webpack (1.x or 2.x) )on node 4+.
27
28Install the plugin with npm:
29```shell
30$ npm install --save-dev script-ext-html-webpack-plugin
31```
32
33You may see an `UNMET PEER DEPENDENCY` warning for webpack.
34
35This is fine; in testing, we dynamically download multiple versions of webpack (via the [dynavers](https://github.com/numical/dynavers) module).
36
37
38Basic Usage
39-----------
40Add the plugin to your webpack config as follows:
41
42```javascript
43plugins: [
44 new HtmlWebpackPlugin(),
45 new ScriptExtHtmlWebpackPlugin()
46]
47```
48The above configuration will actually do nothing due to the configuration defaults. Some more useful scenarios:
49
50All scripts set to `async`:
51```javascript
52plugins: [
53 new HtmlWebpackPlugin(),
54 new ScriptExtHtmlWebpackPlugin({
55 defaultAttribute: 'async'
56 })
57]
58```
59
60All scripts set to `async` except 'first.js' which is sync:
61```javascript
62plugins: [
63 new HtmlWebpackPlugin(),
64 new ScriptExtHtmlWebpackPlugin({
65 sync: 'first.js',
66 defaultAttribute: 'async'
67 })
68]
69```
70
71Configuration offers much more complex options:
72
73Configuration
74-------------
75You must pass a hash of configuration options to the plugin to cause the addition of attributes:
76- `inline`: a __script matching pattern__ defining scripts that should be inlined in the html (default: `[]`);
77- `sync`: a __script matching pattern__ defining script names that should have no attribute (default: `[]`);
78- `async`: a __script matching pattern__ defining script names that should have an `async` attribute (default: `[]`);
79- `defer`: a __script matching pattern__ defining script names that should have a `defer` attribute (default: `[]`);
80- `defaultAttribute`: `'sync' | 'async' | 'defer'` The default attribute to set - `'sync'` actually results in no attribute (default: `'sync'`);
81- `module`: a __script matching pattern__ defining script names that should have a
82`type="module"` attribute (default: `[]`);
83- `preload`: a __script matching pattern__ defining scripts that should have accompanying preload resource hints (default: `[]`);
84- `prefetch`: a __script matching pattern__ defining scripts that should have accompanying prefetch resource hints (default: `[]`);
85
86A __script matching pattern__ matches against a script's name. It can be one of:
87- a `String`- matches if it is a substring of the script name;
88- a `RegExp`;
89- an array of `String`'s and/or `RegExp`'s - matches if any one element matches;
90- a hash with property `test` with a value of one of the above.
91
92In more complicated use cases it may prove difficult to ensure that the pattern matching for different attributes are mutually exclusive. To prevent confusion, the plugin operates a simple precedence model:
93
941. if a script name matches the`inline` script matching pattern, it will be inlined;
95
962. if a script name matches the `sync` script matching pattern, it will have no attribute, *unless* it matched condition 1;
97
983. if a script name the `async` script matching pattern, it will have the `async` attribute, *unless* it matched conditions 1 or 2;
99
1004. if a script name matches the `defer` script matching pattern, it will have the `defer` attribute, *unless* it matched conditions 1, 2 or 3;
101
1025. if a script name does not match any of the previous conditions, it will have the `defaultAttribute' attribute.
103
104The `module` attribute is independent of conditions 2-5, but will be ignored if the script isinlined.
105
106The `preload` and `prefetch` configuration also have allow an additional property in the hash form that can be passed to include dynamically loaded (asynchronous) scripts. This property is `chunks` and can have one of the following `String` values:
107- `initial`: default behaviour, no asynchronour scripts;
108- `async`: only asynchronouse scripts;
109- `all`: all scripts
110Note that you must still supply a `test` __script matching pattern__ which is also applied when selecting scripts.
111
112Some Examples:
113
114All scripts with 'important' in their name are sync and all others set to `defer`:
115```javascript
116plugins: [
117 new HtmlWebpackPlugin(),
118 new ScriptExtHtmlWebpackPlugin({
119 sync: 'important'
120 defaultAttribute: 'defer'
121 })
122]
123```
124
125Alternatively, using a regular expression:
126```javascript
127plugins: [
128 new HtmlWebpackPlugin(),
129 new ScriptExtHtmlWebpackPlugin({
130 sync: /important/,
131 defaultAttribute: 'defer'
132 })
133]
134```
135
136All scripts with 'mod' in their name are async and type 'module', all others are sync (no explicit setting for this as it is the default):
137```javascript
138plugins: [
139 new HtmlWebpackPlugin(),
140 new ScriptExtHtmlWebpackPlugin({
141 async: 'mod',
142 module: 'mod'
143 })
144]
145```
146
147Script 'startup.js' is inlined whilst all other scripts are async and preloaded:
148```javascript
149plugins: [
150 new HtmlWebpackPlugin(),
151 new ScriptExtHtmlWebpackPlugin({
152 inline: 'startup',
153 preload: /\.js$/,
154 defaultAttribute: 'async'
155 })
156]
157```
158
159All asynchronous scripts are added as `preload` resource hints. All other scripts are `async`:
160```javascript
161plugins: [
162 new HtmlWebpackPlugin(),
163 new ScriptExtHtmlWebpackPlugin({
164 async: /\.js$/
165 preload: {
166 test: /\.js$/,
167 chunks: 'async'
168 }
169 })
170]
171```
172
173
174
175And so on, to craziness:
176```javascript
177plugins: [
178 new HtmlWebpackPlugin(),
179 new ScriptExtHtmlWebpackPlugin({
180 inline: 'startup',
181 sync: [/imp(1|2){1,3}}/, 'initial'],
182 defer: ['slow', /big.*andslow/],
183 module: [/^((?!sync).)*/, 'mod'],
184 prefetch: 'indirectly-referenced.js',
185 defaultAttribute: 'async'
186 })
187]
188```
189
190Any problems with real-world examples, just raise an issue.
191
192
193A Note on Script Names
194----------------------
195In the above examples the actual script names are used to select the deployment option. You may not wish to couple asset names to your deployment like this. Instead you can use [Webpack's entry configuration](https://webpack.js.org/concepts/entry-points/#object-syntax) to create aliases that the plugin will then use for its pattern matching. Your `webpack.config.js` will look something like this:
196```javascript
197entry: {
198 a: path.join(__dirname, 'lib/myFunctions.js'),
199 b: path.join(__dirname, 'lib/otherFunctions.js'),
200 c: path.join(__dirname, 'lib/criticalFuntions.js')
201},
202output: {
203 ...
204 filename: '[name].js'
205}
206plugins: [
207 new HtmlWebpackPlugin(),
208 new ScriptExtHtmlWebpackPlugin({
209 inline: ['c'],
210 defer: ['a', 'b']
211 })
212]
213```
214
215
216Inlining
217--------
218Several notes and caveats apply:
219* This feature is for `<script>`'s only. If you wish to inline css please see the sister plugin
220[style-ext-html-webpack-plugin](https://github.com/numical/style-ext-html-webpack-plugin).
221* Even the simplest script will be wrapped with webpack boilerplate; ensure you minify your javascript if you want your output html to be legible!
222* Hot replacement of inlined scripts will only work if caching is [switched off](https://github.com/ampedandwired/html-webpack-plugin#configuration) for html-webpack-plugin:
223```javascript
224plugins: [
225 new HtmlWebpackPlugin({
226 cache: false
227 }),
228 new ScriptExtHtmlWebpackPlugin({
229 inline: ['myinlinedscript.js']
230 })
231]
232```
233* An alternative approach, based on jade templates is illustrated in the [HtmlWebpackPlugin inline example](https://github.com/ampedandwired/html-webpack-plugin/tree/master/examples/inline).
234
235
236Resource Hints
237--------------
238In most cases, modern browsers will intelligently preload referenced script assets.
239However if you wish, this plugin can add resource hint elements to the `<head>` element of the form:
240```html
241<link rel="[preload|prefetch]" href="[scriptname]" as="script">
242```
243Use the `preload` and `prefetch` configuration options.
244
245Where `preload` and `prefetch` patterns overlap, `preload` takes precedence.
246
247Notes:
248- for more on resource hints, see the [`w3c`](https://www.w3.org/TR/resource-hints) definition;
249- for a more complete solution that allows the preloading\fetching of assets other than scripts, see the [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin).
250
251
252
253Change History
254--------------
255
256v1.7.x
257* adds asynchronous script resource hints
258
259v1.6.x
260* works with webpack 2.2.1
261* enhanced API (no need to use array), fully backwardly compatible
262* refactor in preparation for v2
263
264v1.5.x
265* added resource hints
266* works with webpack 2.2.0
267
268v1.4.x
269* updated internal mechanism to use new(ish) [HtmlWebpackPlugin event](https://github.com/ampedandwired/html-webpack-plugin#events)
270* improved test mechanism and enhanced test coverage
271* added support for `publicPath` for inline scripts (thanks @JustAboutJeff)
272* works with 'webpack -p' (thanks @brandongoode)
273
274v1.3.x
275* added `type="text/javascript"` by default, in response to [Safari 9.1.1 bug](https://github.com/ampedandwired/html-webpack-plugin/issues/309)
276* removed experimental status of inline option
277* added weback 2.2.x beta support
278
279v1.2.x
280* added inline option
281
282v1.1.x
283* added `type="module"` option
284
285v1.0.x
286* initial release