Skip to content
This repository was archived by the owner on Jan 21, 2021. It is now read-only.

Commit 89f6495

Browse files
committed
Add a runtime check for the HtmlWebpackPlugin
1 parent 76fb29e commit 89f6495

File tree

4 files changed

+96
-66
lines changed

4 files changed

+96
-66
lines changed

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@
187187
same "printed page" as the copyright notice for easier
188188
identification within third-party archives.
189189

190-
Copyright 2014 Google Inc.
190+
Copyright 2018 Google Inc.
191191

192192
Licensed under the Apache License, Version 2.0 (the "License");
193193
you may not use this file except in compliance with the License.
@@ -199,4 +199,4 @@
199199
distributed under the License is distributed on an "AS IS" BASIS,
200200
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201201
See the License for the specific language governing permissions and
202-
limitations under the License.
202+
limitations under the License.

README.md

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,18 @@
1-
preload-webpack-plugin
2-
============
1+
# preload-webpack-plugin
2+
33
[![NPM version][npm-img]][npm-url]
44
[![NPM downloads][npm-downloads-img]][npm-url]
55
[![Dependency Status][daviddm-img]][daviddm-url]
66

77
![preloads-plugin-compressor](https://cloud.githubusercontent.com/assets/110953/22451103/7700b812-e720-11e6-89e8-a6d4e3533159.png)
88

9-
A Webpack plugin for automatically wiring up asynchronous (and other types) of JavaScript
9+
A webpack plugin for automatically wiring up asynchronous (and other types) of JavaScript
1010
chunks using `<link rel='preload'>`. This helps with lazy-loading.
1111

12-
Note: This is an extension plugin for [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) - a plugin that
12+
Note: This is an extension plugin for [`html-webpack-plugin`](https://github.com/jantimon/html-webpack-plugin) - a plugin that
1313
simplifies the creation of HTML files to serve your webpack bundles.
1414

15-
This plugin is a stop-gap until we add support for asynchronous chunk wiring to
16-
[script-ext-html-webpack-plugin](https://github.com/numical/script-ext-html-webpack-plugin/pull/9).
17-
18-
Introduction
19-
------------
15+
## Introduction
2016

2117
[Preload](https://w3c.github.io/preload/) is a web standard aimed at improving performance
2218
and granular loading of resources. It is a declarative fetch that can tell a browser to start fetching a
@@ -33,36 +29,34 @@ For example, `chunk.31132ae6680e598f8879.js`.
3329
To make it easier to wire up async chunks for lazy-loading, this plugin offers a drop-in way to wire them up
3430
using `<link rel='preload'>`.
3531

36-
Pre-requisites
37-
--------------
38-
This module requires Webpack 2.2.0 and above. It also requires that you're using
39-
[html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin) in your Webpack project.
32+
## Prerequisites
33+
34+
This module requires webpack 2.2.0 and above. It also requires that you're using
35+
[`html-webpack-plugin`](https://github.com/ampedandwired/html-webpack-plugin) in your webpack project.
4036

41-
Installation
42-
---------------
37+
## Installation
4338

44-
First, install the package as a dependency in your package.json:
39+
First, install the package as a dependency in your `package.json`:
4540

4641
```sh
4742
$ npm install --save-dev preload-webpack-plugin
4843
```
4944

50-
Alternatively, using yarn:
45+
Alternatively, using `yarn`:
5146

5247
```sh
53-
yarn add -D preload-webpack-plugin
48+
$ yarn add -D preload-webpack-plugin
5449
```
5550

56-
Usage
57-
-----------------
51+
## Usage
5852

59-
Next, in your Webpack config, `require()` the preload plugin as follows:
53+
In your webpack config, `require()` the preload plugin as follows:
6054

6155
```js
6256
const PreloadWebpackPlugin = require('preload-webpack-plugin');
6357
```
6458

65-
and finally, configure the plugin in your Webpack `plugins` array after `HtmlWebpackPlugin`:
59+
and finally, configure the plugin in your webpack `plugins` array after `HtmlWebpackPlugin`:
6660

6761
```js
6862
plugins: [
@@ -145,6 +139,7 @@ plugins: [
145139
```
146140

147141
In case you work with named chunks, you can explicitly specify which ones to `include` by passing an array:
142+
148143
```js
149144
plugins: [
150145
new HtmlWebpackPlugin(),
@@ -161,8 +156,7 @@ will inject just this:
161156
<link rel="preload" as="script" href="home.31132ae6680e598f8879.js">
162157
```
163158

164-
Filtering chunks
165-
---------------------
159+
### Filtering chunks
166160

167161
There may be chunks that you don't want to have preloaded (sourcemaps, for example). Before preloading each chunk, this plugin checks that the file does not match any regex in the `fileBlacklist` option. The default value of this blacklist is `[/\.map/]`, meaning no sourcemaps will be preloaded. You can easily override this:
168162

@@ -180,8 +174,7 @@ new PreloadWebpackPlugin({
180174
})
181175
```
182176

183-
Resource Hints
184-
---------------------
177+
### Resource Hints
185178

186179
Should you wish to use Resource Hints (such as `prefetch`) instead of `preload`, this plugin also supports wiring those up.
187180

@@ -203,25 +196,23 @@ For the async chunks mentioned earlier, the plugin would update your HTML to the
203196
<link rel="prefetch" href="chunk.d15e7fdfc91b34bb78c4.js">
204197
```
205198

206-
Demo
207-
----------------------
199+
## Demo
208200

209201
A demo application implementing the [PRPL pattern](https://developers.google.com/web/fundamentals/performance/prpl-pattern/) with React that uses this plugin can be found in the `demo`
210202
directory.
211203

212-
Support
213-
-------
204+
## Support
214205

215-
If you've found an error in this sample, please file an issue:
206+
If you've found an error or run into problems, please file an issue:
216207
[https://github.com/googlechrome/preload-webpack-plugin/issues](https://github.com/googlechrome/preload-webpack-plugin/issues)
217208

218209
Patches are encouraged, and may be submitted by forking this project and
219210
submitting a pull request through GitHub.
220211

221-
Contributing workflow
222-
---------------------
212+
## Contributing workflow
223213

224-
`index.js` contains the primary source for the plugin, `test` contains tests and `demo` contains demo code.
214+
`index.js` and `lib/` contains the primary source for the plugin,
215+
`test` contains tests and `demo` contains demo code.
225216

226217
Test the plugin:
227218

@@ -230,35 +221,34 @@ $ npm install
230221
$ npm run test
231222
```
232223

233-
Lint the plugin:
234-
235-
```sh
236-
$ npm run lint
237-
$ npm run lint-fix # fix linting issues
238-
```
239-
240-
The project is written in ES2015, but does not use a build-step. This may change depending on
241-
any Node version support requests posted to the issue tracker.
224+
The project is written in ES2015, and is transpiled to support node 6 and above.
242225

243-
Additional Notes
244-
---------------------------
226+
## Additional notes
245227

246-
* Be careful not to `preload` resources a user is unlikely to need. This can waste their bandwidth.
247-
* Use `preload` for the current session if you think a user is likely to visit the next page. There is no
228+
- Be careful not to `preload` resources a user is unlikely to need. This can waste their bandwidth.
229+
- Use `preload` for the current session if you think a user is likely to visit the next page. There is no
248230
100% guarantee preloaded items will end up in the HTTP Cache and read locally beyond this session.
249-
* If optimising for future sessions, use `prefetch` and `preconnect`. Prefetched resources are maintained
231+
- If optimizing for future sessions, use `prefetch` and `preconnect`. Prefetched resources are maintained
250232
in the HTTP Cache for at least 5 minutes (in Chrome) regardless of the resource's cachability.
251233

252-
Related plugins
253-
--------------------------
234+
## Alternative tools
235+
236+
- webpack's native support:
237+
As of the [v4.6.0 release](https://github.com/webpack/webpack/releases/tag/v4.6.0)
238+
of webpack, there is native support for generating both prefetch and preload `<link>`s via ["magic" comments in your `import()` statements](https://medium.com/webpack/link-rel-prefetch-preload-in-webpack-51a52358f84c).
239+
240+
- [script-ext-html-webpack-plugin](https://github.com/numical/script-ext-html-webpack-plugin):
241+
Enhances `html-webpack-plugin` with options including 'async', 'defer', 'module' and 'preload'.
242+
As of [v1.7.0](https://github.com/numical/script-ext-html-webpack-plugin/pull/9#issuecomment-278239875),
243+
it supports async chunks.
254244

255-
* [script-ext-html-webpack-plugin](https://github.com/numical/script-ext-html-webpack-plugin) - Enhances html-webpack-plugin with options including 'async', 'defer', 'module' and preload (no async chunk support yet)
256-
* [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin) - Automatically wires resource hints for your resources (similarly no async chunk support)
245+
- [resource-hints-webpack-plugin](https://github.com/jantimon/resource-hints-webpack-plugin):
246+
Automatically wires resource hints for your resources. This plugin does does not currently
247+
support async chunks.
257248

258-
License
259-
-------
249+
## License
260250

261-
Copyright 2017 Google, Inc.
251+
Copyright 2018 Google, Inc.
262252

263253
Licensed to the Apache Software Foundation (ASF) under one or more contributor
264254
license agreements. See the NOTICE file distributed with this work for

src/index.js

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -120,16 +120,24 @@ class PreloadPlugin {
120120
compiler.hooks.compilation.tap(
121121
this.constructor.name,
122122
compilation => {
123-
compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync(
124-
this.constructor.name,
125-
(htmlPluginData, callback) => {
126-
try {
127-
callback(null, this.addLinks('v4', compilation, htmlPluginData));
128-
} catch (error) {
129-
callback(error);
123+
if ('htmlWebpackPluginBeforeHtmlProcessing' in compilation.hooks) {
124+
compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tapAsync(
125+
this.constructor.name,
126+
(htmlPluginData, callback) => {
127+
try {
128+
callback(null, this.addLinks('v4', compilation, htmlPluginData));
129+
} catch (error) {
130+
callback(error);
131+
}
130132
}
131-
}
132-
);
133+
);
134+
} else {
135+
const error = new Error(`Unable to tap into the ` +
136+
`HtmlWebpackPlugin's callbacks. Make sure to list ` +
137+
`${this.constructor.name} at some point after ` +
138+
`HtmlWebpackPlugin in webpack's plugins array.`);
139+
compilation.errors.push(error);
140+
}
133141
}
134142
);
135143
} else {

test/spec.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,4 +657,36 @@ module.exports = ({descriptionPrefix, webpack, HtmlWebpackPlugin}) => {
657657
compiler.outputFileSystem = new MemoryFileSystem();
658658
});
659659
});
660+
661+
describe(`${descriptionPrefix} When used in an invalid configuration,`, function() {
662+
// We can't detect this error in webpack 3.
663+
if (/webpack 3/.test(descriptionPrefix)) {
664+
return;
665+
}
666+
667+
it(`should trigger a compilation error when HtmlWebpackPlugin isn't also used`, function(done) {
668+
const compiler = webpack({
669+
entry: {
670+
js: path.join(__dirname, 'fixtures', 'file.js')
671+
},
672+
output: {
673+
path: OUTPUT_DIR,
674+
filename: 'bundle.js',
675+
chunkFilename: '[name].[chunkhash].js',
676+
publicPath: '/',
677+
},
678+
plugins: [
679+
new PreloadPlugin()
680+
]
681+
}, function(err, result) {
682+
expect(err).toBeFalsy(err);
683+
expect(result.compilation.errors.length).toBe(1,
684+
result.compilation.errors.join('\n=========\n'));
685+
expect(result.compilation.errors[0]).toMatch(new RegExp('HtmlWebpackPlugin'));
686+
687+
done();
688+
});
689+
compiler.outputFileSystem = new MemoryFileSystem();
690+
});
691+
});
660692
};

0 commit comments

Comments
 (0)