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

add target option #110

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,21 @@ will inject just this:
<link rel="preload" as="script" href="home.31132ae6680e598f8879.js">
```

### Specifying a target element

By default, `<link>`s are appended to the `<head>` of the `<html>` document. To append them to the `<body>`, supply the `target` option as follows:

```js
plugins: [
new HtmlWebpackPlugin(),
new PreloadWebpackPlugin({
rel: 'preload',
target: 'body'
})
]
```
This can be useful for fine-tuning loading behavior in some browser environments.

### Filtering chunks

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:
Expand Down
7 changes: 4 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const createHTMLElementString = require('./lib/create-html-element-string');
const defaultOptions = require('./lib/default-options');
const determineAsValue = require('./lib/determine-as-value');
const extractChunks = require('./lib/extract-chunks');
const insertLinksIntoHead = require('./lib/insert-links-into-head');
const insertLinksIntoHtml = require('./lib/insert-links-into-html');

class PreloadPlugin {
constructor(options) {
Expand Down Expand Up @@ -98,9 +98,10 @@ class PreloadPlugin {
links.push(linkElementString);
}

htmlPluginData.html = insertLinksIntoHead({
links,
htmlPluginData.html = insertLinksIntoHtml({
html: htmlPluginData.html,
links,
target: options.target,
});

return htmlPluginData;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/default-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ const defaultOptions = {
rel: 'preload',
include: 'asyncChunks',
excludeHtmlNames: [],
fileBlacklist: [/\.map/]
fileBlacklist: [/\.map/],
target: 'head',
};

module.exports = defaultOptions;
36 changes: 0 additions & 36 deletions src/lib/insert-links-into-head.js

This file was deleted.

49 changes: 49 additions & 0 deletions src/lib/insert-links-into-html.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* @license
* Copyright 2018 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

function insertLinksIntoHtml({html, links=[], target}) {
if (links.length === 0) {
return html;
}
if (target === 'head') {
if (html.includes('</head>')) {
// If a valid closing </head> is found, insert the new <link>s right before it.
return html.replace('</head>', `${links.join('')}</head>`);
}

if (html.includes('<body>')) {
// If there's a <body> but no valid closing </head>, create a <head> containing the <link>s.
return html.replace('<body>', `<head>${links.join('')}</head><body>`);
}
throw new Error(`The HTML provided did not contain a </head> or a <body>:\n\n${html}`);
}

if (target === 'body') {
if (html.includes('</body>')) {
// If a valid closing </body> is found, insert the new <link>s right before it.
return html.replace('</body>', `${links.join('')}</body>`);
}

if (html.includes('</head>')) {
// If there's a valid closing </head> but no valid closing <body>, create a <body> containing the <link>s.
return html.replace('</head>', `</head><body>${links.join('')}</body>`);
}
throw new Error(`The HTML provided did not contain a </head> or a </body>:\n\n${html}`);
}
}

module.exports = insertLinksIntoHtml;
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
* limitations under the License.
*/

const insertLinksIntoHead = require('../../src/lib/insert-links-into-head');
const insertLinksIntoHead = require('../../src/lib/insert-links-into-html');

describe(`Edge Conditions:`, function() {
it(`should throw when called with HTML lacking a </head> or <body>`, function(done) {
const html = '<html></html>';
expect(
() => insertLinksIntoHead({html, links: ['<link>']})
() => insertLinksIntoHead({html, links: ['<link>'], target: 'head'})
).toThrowError(`The HTML provided did not contain a </head> or a <body>:\n\n<html></html>`);

done();
Expand All @@ -43,6 +43,7 @@ describe(`Normal Conditions:`, function() {
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link>'],
target: 'head',
});

expect(updatedHtml).toEqual(`<html><head><link></head><body></body></html>`);
Expand All @@ -55,33 +56,89 @@ describe(`Normal Conditions:`, function() {
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>', '<link2>'],
target: 'head',
});

expect(updatedHtml).toEqual(`<html><head><link1><link2></head><body></body></html>`);

done();
});

it(`should support inserting a single link prior to the <body> when there is no </head>`, function(done) {
it(`should support creating a <head> and inserting a single link prior to the </head> when there is no <head>`, function(done) {
const html = '<html><body></body></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>'],
target: 'head',
});

expect(updatedHtml).toEqual(`<html><head><link1>\n</head><body></body></html>`);
expect(updatedHtml).toEqual(`<html><head><link1></head><body></body></html>`);

done();
});

it(`should support inserting multiple links prior to the <body> when there is no </head>`, function(done) {
it(`should support creating a head and inserting multiple links prior to the </head> when there is no <head>`, function(done) {
const html = '<html><body></body></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>', '<link2>'],
target: 'head',
});

expect(updatedHtml).toEqual(`<html><head><link1><link2>\n</head><body></body></html>`);
expect(updatedHtml).toEqual(`<html><head><link1><link2></head><body></body></html>`);

done();
});

// target: body
it(`should support inserting a single link prior to the </body>`, function(done) {
const html = '<html><head></head><body></body></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link>'],
target: 'body',
});

expect(updatedHtml).toEqual(`<html><head></head><body><link></body></html>`);

done();
});

it(`should support inserting multiple links prior to the </body>`, function(done) {
const html = '<html><head></head><body></body></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>', '<link2>'],
target: 'body',
});

expect(updatedHtml).toEqual(`<html><head></head><body><link1><link2></body></html>`);

done();
});

it(`should support creating a body and inserting a single link prior to the </body> when there is no <body>`, function(done) {
const html = '<html><head></head></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>'],
target: 'body',
});

expect(updatedHtml).toEqual(`<html><head></head><body><link1></body></html>`);

done();
});

it(`should support creating a body and inserting multiple links prior to the </body> when there is no </body>`, function(done) {
const html = '<html><head></head></html>';
const updatedHtml = insertLinksIntoHead({
html,
links: ['<link1>', '<link2>'],
target: 'body',
});

expect(updatedHtml).toEqual(`<html><head></head><body><link1><link2></body></html>`);

done();
});
Expand Down