Skip to content

Commit a1d253f

Browse files
committed
add custom attributes to resource hints too
1 parent 23aa6c7 commit a1d253f

File tree

5 files changed

+94
-6
lines changed

5 files changed

+94
-6
lines changed

README.md

+21
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,23 @@ plugins: [
175175
]
176176
```
177177

178+
All scripts are preloaded with a ```crossorigin``` attribute set to enable CDN's:
179+
```javascript
180+
plugins: [
181+
new HtmlWebpackPlugin(),
182+
new ScriptExtHtmlWebpackPlugin({
183+
custom {
184+
test: /\.js$/,
185+
attribute: 'crossorigin'
186+
value: 'anonymous'
187+
}
188+
preload: {
189+
test: /\.js$/
190+
}
191+
})
192+
]
193+
```
194+
178195
All asynchronous scripts are added as `preload` resource hints. All other scripts are `async`:
179196
```javascript
180197
plugins: [
@@ -285,6 +302,7 @@ Possibly a more compelling use case is to preload/prefetch dynamically loaded sc
285302

286303

287304
Notes:
305+
- custom attributes will be added to resource hints with the same *script matching pattern*. This is useful for adding such attributes as ```crossorigin="anonymous"``` - see the Configuration Examples above;
288306
- for more on resource hints, see the [`w3c`](https://www.w3.org/TR/resource-hints) definition;
289307
- 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).
290308

@@ -293,6 +311,9 @@ Notes:
293311
Change History
294312
--------------
295313

314+
v2.1.x
315+
* custom attributes now added to resource hints too (see [pull request 53](https://github.com/numical/script-ext-html-webpack-plugin/pull/53) for discussion)
316+
296317
v2.0.x
297318
* support html-webpack-plugin 4.x - huge thanks to [@snadn](https://github.com/snadn)
298319
* support webpack 4.x - huge thanks to [@sherlock1982](https://github.com/sherlock1982)

lib/common.js

+21-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,27 @@ const separator = '/';
55

66
const isScript = (tag) => tag.tagName === 'script';
77

8-
const hasScriptName = tag => tag.attributes && tag.attributes.src;
8+
const isResourceLink = (tag) => tag.tagName === 'link' && tag.attributes && tag.attributes.as === 'script';
99

10-
const getRawScriptName = tag => (tag.attributes && tag.attributes.src) || '';
10+
const hasScriptName = tag => {
11+
if (isScript(tag)) {
12+
return tag.attributes && tag.attributes.src;
13+
} else if (isResourceLink(tag)) {
14+
return tag.attributes && tag.attributes.href;
15+
} else {
16+
return false;
17+
}
18+
};
19+
20+
const getRawScriptName = tag => {
21+
if (isScript(tag)) {
22+
return (tag.attributes && tag.attributes.src) || '';
23+
} else if (isResourceLink(tag)) {
24+
return (tag.attributes && tag.attributes.href) || '';
25+
} else {
26+
return '';
27+
}
28+
};
1129

1230
const getPublicPath = options => {
1331
const output = options.compilationOptions.output;
@@ -47,6 +65,7 @@ module.exports = {
4765
getRawScriptName,
4866
getScriptName,
4967
hasScriptName,
68+
isResourceLink,
5069
isScript,
5170
matches
5271
};

lib/custom-attributes.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const CONSTANTS = require('./constants.js');
55
const common = require('./common.js');
66
const debug = common.debug;
77
const getScriptName = common.getScriptName;
8+
const isResourceLink = common.isResourceLink;
89
const isScript = common.isScript;
910
const matches = common.matches;
1011

@@ -18,7 +19,7 @@ const add = (options, tags) => {
1819
};
1920

2021
const updateElement = (options, tag) => {
21-
return (isScript(tag))
22+
return (isScript(tag) || isResourceLink(tag))
2223
? updateScriptElement(options, tag)
2324
: tag;
2425
};

lib/elements.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const ATTRIBUTE_PRIORITIES = [SYNC, 'async', 'defer'];
66

77
const common = require('./common.js');
88
const debug = common.debug;
9+
const isScript = common.isScript;
910
const matches = common.matches;
1011
const getScriptName = common.getScriptName;
1112

@@ -31,8 +32,6 @@ const updateElement = (assets, options, tag) => {
3132
: tag;
3233
};
3334

34-
const isScript = (tag) => tag.tagName === 'script';
35-
3635
const updateScriptElement = (assets, options, tag) => {
3736
debug(`${CONSTANTS.EVENT}: processing <script> element: ${JSON.stringify(tag)}`);
3837
return (isInline(options, tag))

spec/core-spec.js

+49-1
Original file line numberDiff line numberDiff line change
@@ -695,7 +695,7 @@ describe(`Core functionality (webpack ${version.display})`, function () {
695695
testPlugin(config, expected, done);
696696
});
697697

698-
it('multiple customer attributes over multiple scripts', (done) => {
698+
it('multiple custom attributes over multiple scripts', (done) => {
699699
const config = baseConfig(
700700
{
701701
async: [/(a|c).*/, 'b'],
@@ -722,4 +722,52 @@ describe(`Core functionality (webpack ${version.display})`, function () {
722722
];
723723
testPlugin(config, expected, done);
724724
});
725+
726+
it('custom attributes also added to prefetch resource hints', (done) => {
727+
const config = baseConfig(
728+
{
729+
custom: {
730+
test: /.js$/,
731+
attribute: 'customAttribute',
732+
value: 'xyz'
733+
},
734+
prefetch: {
735+
test: /.js$/
736+
}
737+
},
738+
{},
739+
'index_bundle.js'
740+
);
741+
config.entry = path.join(__dirname, 'fixtures/script1.js');
742+
const expected = baseExpectations();
743+
expected.html = [
744+
/(<script (type="text\/javascript" )?src="index_bundle.js" customAttribute="xyz"><\/script>)/,
745+
/(<link rel="prefetch" href="index_bundle.js" as="script" customAttribute="xyz"((\/>)|(><\/link>)))/
746+
];
747+
testPlugin(config, expected, done);
748+
});
749+
it('custom attributes also added to preload resource hints', (done) => {
750+
const config = baseConfig(
751+
{
752+
custom: {
753+
test: /.js$/,
754+
attribute: 'customAttribute',
755+
value: 'xyz'
756+
},
757+
preload: {
758+
test: /.js$/
759+
}
760+
},
761+
{},
762+
'index_bundle.js'
763+
);
764+
config.entry = path.join(__dirname, 'fixtures/script1.js');
765+
const expected = baseExpectations();
766+
expected.html = [
767+
/(<script (type="text\/javascript" )?src="index_bundle.js" customAttribute="xyz"><\/script>)/,
768+
/(<link rel="preload" href="index_bundle.js" as="script" customAttribute="xyz"((\/>)|(><\/link>)))/
769+
770+
];
771+
testPlugin(config, expected, done);
772+
});
725773
});

0 commit comments

Comments
 (0)