Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add integrity to link preload tags #118

Merged
merged 1 commit into from Oct 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 7 additions & 5 deletions README.md
Expand Up @@ -155,11 +155,13 @@ Webpack >= 4).

### Preloading

`<link rel="preload">` doesn't work as expected in current Chrome versions, even
if the integrity attribute is added to the `link tag (which the current version
of webpack-subresource-integrity does _not_ do.) The resource will be loaded
twice, defeating the purpose of preloading. This issue doesn't appear to exist
in Firefox or Safari. See issue #111 for more information.
This plugin adds the integrity attribute to `<link rel="preload">`
tags, but preloading with SRI doesn't work as expected in current
Chrome versions. The resource will be loaded twice, defeating the
purpose of preloading. This problem doesn't appear to exist in
Firefox or Safari. See [issue
#111](https://github.com/waysact/webpack-subresource-integrity/issues/111)
for more information.

### Proxies

Expand Down
3 changes: 3 additions & 0 deletions examples/webpack-preload/README.md
@@ -0,0 +1,3 @@
# With `/* webpackPreload: "true" */`

https://github.com/waysact/webpack-subresource-integrity/issues/111
1 change: 1 addition & 0 deletions examples/webpack-preload/index.js
@@ -0,0 +1 @@
import('./lazy-chunk-1.js');
5 changes: 5 additions & 0 deletions examples/webpack-preload/lazy-chunk-1.js
@@ -0,0 +1,5 @@
setTimeout(() => {
import(/* webpackPreload: true */ './lazy-chunk-2.js').then(mod =>
mod.test()
);
}, 750);
16 changes: 16 additions & 0 deletions examples/webpack-preload/lazy-chunk-2.js
@@ -0,0 +1,16 @@
module.exports.test = () => {
const linkTag = Array.from(document.getElementsByTagName('link')).find(
el => el.rel === 'preload'
);
const scriptTag = Array.from(document.getElementsByTagName('script')).find(
el => linkTag && el.src === linkTag.href
);
console.log(
scriptTag &&
linkTag &&
scriptTag.integrity &&
scriptTag.integrity === linkTag.integrity
? 'ok'
: 'error'
);
};
8 changes: 8 additions & 0 deletions examples/webpack-preload/test.js
@@ -0,0 +1,8 @@
var webpackVersion = Number(
require('webpack/package.json').version.split('.')[0]
);

module.exports.skip = function skip() {
// webpack-preload tag requires Webpack 4
return webpackVersion < 4;
};
18 changes: 18 additions & 0 deletions examples/webpack-preload/webpack.config.js
@@ -0,0 +1,18 @@
var SriPlugin = require('webpack-subresource-integrity');
var HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: {
index: './index.js'
},
output: {
crossOriginLoading: 'anonymous'
},
plugins: [
new SriPlugin({
hashFuncNames: ['sha256', 'sha384'],
enabled: true
}),
new HtmlWebpackPlugin()
]
};
12 changes: 7 additions & 5 deletions jmtp.js
Expand Up @@ -46,8 +46,8 @@ WebIntegrityJsonpMainTemplatePlugin.prototype.addSriHashes =
/*
* Patch jsonp-script code to add the integrity attribute.
*/
WebIntegrityJsonpMainTemplatePlugin.prototype.jsonpScriptPlugin =
function jsonpScriptPlugin(mainTemplate, source) {
WebIntegrityJsonpMainTemplatePlugin.prototype.addAttribute =
function addAttribute(mainTemplate, elName, source) {
if (!mainTemplate.outputOptions.crossOriginLoading) {
this.sriPlugin.errorOnce(
this.compilation,
Expand All @@ -56,22 +56,24 @@ WebIntegrityJsonpMainTemplatePlugin.prototype.jsonpScriptPlugin =
}
return (Template.asString || mainTemplate.asString)([
source,
'script.integrity = sriHashes[chunkId];',
'script.crossOrigin = ' + JSON.stringify(mainTemplate.outputOptions.crossOriginLoading) + ';',
elName + '.integrity = sriHashes[chunkId];',
elName + '.crossOrigin = ' + JSON.stringify(mainTemplate.outputOptions.crossOriginLoading) + ';',
]);
};

WebIntegrityJsonpMainTemplatePlugin.prototype.apply = function apply(
mainTemplate
) {
var jsonpScriptPlugin = this.jsonpScriptPlugin.bind(this, mainTemplate);
var jsonpScriptPlugin = this.addAttribute.bind(this, mainTemplate, "script");
var linkPreloadPlugin = this.addAttribute.bind(this, mainTemplate, "link");
var addSriHashes = this.addSriHashes.bind(this, mainTemplate);

if (!mainTemplate.hooks) {
mainTemplate.plugin('jsonp-script', jsonpScriptPlugin);
mainTemplate.plugin('local-vars', addSriHashes);
} else if (mainTemplate.hooks.jsonpScript && mainTemplate.hooks.localVars) {
mainTemplate.hooks.jsonpScript.tap('SriPlugin', jsonpScriptPlugin);
mainTemplate.hooks.linkPreload.tap('SriPlugin', linkPreloadPlugin);
mainTemplate.hooks.localVars.tap('SriPlugin', addSriHashes);
} else {
this.sriPlugin.warnOnce(
Expand Down