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

Commit 99c5dab

Browse files
committed
add feature to preload fonts
1 parent edb0cc8 commit 99c5dab

3 files changed

Lines changed: 40 additions & 4 deletions

File tree

README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ plugins: [
7272
```
7373

7474
When preloading files, the plugin will use different `as` attribute depends on the type of each
75-
file. For each file ends with `.css`, the plugin will preload it with `as=style`, while for all
76-
other files, `as=script` will be used.
75+
file. For each file ends with `.css`, the plugin will preload it with `as=style`, for each file ends
76+
with `.woff`, `.woff2`, `.eot`, `.otf` or `.ttf`, the plugin will preload it with `as=font`, while
77+
for all other files, `as=script` will be used.
7778

7879
If you do not prefer to determine `as` attribute depends on suffix of filename, you can also
7980
explicitly name it using `as`:
@@ -106,6 +107,9 @@ plugins: [
106107
]
107108
```
108109

110+
Notice that if `as=font` is used in preload, crossorigin will be added, otherwise the font resource
111+
might be double fetched. Explains can be found in [this article](https://medium.com/reloading/preload-prefetch-and-priorities-in-chrome-776165961bbf).
112+
109113
By default, the plugin will assume async script chunks will be preloaded. This is the equivalent of:
110114

111115
```js

index.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,13 +75,16 @@ class PreloadPlugin {
7575
// value depends on suffix of filename. Otherwise use the given `as` value.
7676
let asValue;
7777
if (!options.as) {
78-
asValue = entry.match(/\.css$/) ? 'style' : 'script';
78+
if (entry.match(/\.css$/)) asValue = 'style';
79+
else if (entry.match(/\.(?:eot|otf|ttf|woff2?)$/)) asValue = 'font';
80+
else asValue = 'script';
7981
} else if (typeof options.as === 'function') {
8082
asValue = options.as(entry);
8183
} else {
8284
asValue = options.as;
8385
}
84-
filesToInclude+= `<link rel="${options.rel}" as="${asValue}" href="${entry}">\n`;
86+
const crossOrigin = asValue === 'font' ? 'crossorigin="crossorigin" ' : '';
87+
filesToInclude+= `<link rel="${options.rel}" as="${asValue}" ${crossOrigin}href="${entry}">\n`;
8588
} else {
8689
// If preload isn't specified, the only other valid entry is prefetch here
8790
// You could specify preconnect but as we're dealing with direct paths to resources

test/spec.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,35 @@ describe('PreloadPlugin preloads normal chunks', function() {
191191
compiler.outputFileSystem = new MemoryFileSystem();
192192
});
193193

194+
it('adds preload using "font" for fonts and add crossorigin attribute', (done) => {
195+
const compiler = webpack({
196+
entry: {
197+
js: path.join(__dirname, 'fixtures', 'file.js')
198+
},
199+
output: {
200+
path: OUTPUT_DIR,
201+
filename: 'bundle.js',
202+
chunkFilename: 'chunk.[chunkhash].woff2',
203+
publicPath: '/',
204+
},
205+
plugins: [
206+
new HtmlWebpackPlugin(),
207+
new PreloadPlugin({
208+
rel: 'preload',
209+
include: 'all'
210+
})
211+
]
212+
}, function(err, result) {
213+
expect(err).toBeFalsy();
214+
expect(JSON.stringify(result.compilation.errors)).toBe('[]');
215+
const html = result.compilation.assets['index.html'].source();
216+
expect(html).toContain('<link rel="preload" as="font" crossorigin="crossorigin" href="/chunk');
217+
expect(html).toContain('<link rel="preload" as="script" href="/bundle.js"');
218+
done();
219+
});
220+
compiler.outputFileSystem = new MemoryFileSystem();
221+
});
222+
194223
it('use custom as attribute based on return value of callback', (done) => {
195224
const compiler = webpack({
196225
entry: path.join(__dirname, 'fixtures', 'file.js'),

0 commit comments

Comments
 (0)