You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.4 KiB
103 lines
3.4 KiB
/**
|
|
* Copyright (c) 2015-present, Waysact Pty Ltd
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
var Template = require('webpack/lib/Template');
|
|
var util = require('./util');
|
|
var webpackVersionComponents = require('webpack/package.json').version.split(
|
|
'.'
|
|
);
|
|
var webpackVersionMajor = Number(webpackVersionComponents[0]);
|
|
|
|
function WebIntegrityJsonpMainTemplatePlugin(sriPlugin, compilation) {
|
|
this.sriPlugin = sriPlugin;
|
|
this.compilation = compilation;
|
|
}
|
|
|
|
WebIntegrityJsonpMainTemplatePlugin.prototype.addSriHashes =
|
|
function addSriHashes(mainTemplate, source, chunk) {
|
|
var allChunks = util.findChunks(chunk);
|
|
var includedChunks = chunk.getChunkMaps().hash;
|
|
var hashFuncNames = this.sriPlugin.options.hashFuncNames;
|
|
|
|
if (Object.keys(includedChunks).length > 0) {
|
|
return (Template.asString || mainTemplate.asString)([
|
|
source,
|
|
'__webpack_require__.sriHashes = ' +
|
|
JSON.stringify(
|
|
Array.from(allChunks).reduce(function chunkIdReducer(
|
|
sriHashes,
|
|
depChunk
|
|
) {
|
|
if (includedChunks[depChunk.id.toString()]) {
|
|
// eslint-disable-next-line no-param-reassign
|
|
sriHashes[depChunk.id] = util.makePlaceholder(hashFuncNames, depChunk.id);
|
|
}
|
|
return sriHashes;
|
|
},
|
|
{})
|
|
) +
|
|
';'
|
|
]);
|
|
}
|
|
|
|
return source;
|
|
};
|
|
|
|
/*
|
|
* Patch jsonp-script code to add the integrity attribute.
|
|
*/
|
|
WebIntegrityJsonpMainTemplatePlugin.prototype.addAttribute =
|
|
function addAttribute(mainTemplate, elName, source) {
|
|
const outputOptions = this.compilation.outputOptions || mainTemplate.outputOptions;
|
|
if (!outputOptions.crossOriginLoading) {
|
|
this.sriPlugin.errorOnce(
|
|
this.compilation,
|
|
'webpack option output.crossOriginLoading not set, code splitting will not work!'
|
|
);
|
|
}
|
|
|
|
return (Template.asString || mainTemplate.asString)([
|
|
source,
|
|
elName + '.integrity = __webpack_require__.sriHashes[' +
|
|
((webpackVersionMajor >= 5 && elName === 'script') ? 'key.match(/^chunk-(.+)$/)[1]' : 'chunkId') +
|
|
'];',
|
|
elName + '.crossOrigin = ' + JSON.stringify(outputOptions.crossOriginLoading) + ';',
|
|
]);
|
|
};
|
|
|
|
WebIntegrityJsonpMainTemplatePlugin.prototype.apply = function apply(
|
|
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 (
|
|
this.compilation.outputOptions.chunkLoading
|
|
? ['require', 'async-node'].includes(
|
|
this.compilation.outputOptions.chunkLoading
|
|
)
|
|
: this.compilation.compiler.options.target !== 'web'
|
|
) {
|
|
this.sriPlugin.warnOnce(
|
|
this.compilation,
|
|
'This plugin is not useful for non-web targets.'
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (mainTemplate.hooks) {
|
|
mainTemplate.hooks.jsonpScript.tap('SriPlugin', jsonpScriptPlugin);
|
|
mainTemplate.hooks.linkPreload.tap('SriPlugin', linkPreloadPlugin);
|
|
mainTemplate.hooks.localVars.tap('SriPlugin', addSriHashes);
|
|
} else {
|
|
mainTemplate.plugin('jsonp-script', jsonpScriptPlugin);
|
|
mainTemplate.plugin('local-vars', addSriHashes);
|
|
}
|
|
};
|
|
|
|
module.exports = WebIntegrityJsonpMainTemplatePlugin;
|