UNPKG

webpack-subresource-integrity

Version:
209 lines 8.1 kB
"use strict"; /** * 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. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.Plugin = void 0; const path_1 = require("path"); const fs_1 = require("fs"); const util_1 = require("./util"); const manifest_1 = require("./manifest"); const integrity_1 = require("./integrity"); const assetTypeIntegrityKeys = [ ["js", "jsIntegrity"], ["css", "cssIntegrity"], ]; class Plugin { constructor(compilation, options, reporter) { /** * @internal */ this.hwpPublicPath = null; /** * @internal */ this.sortedSccChunks = []; /** * @internal */ this.chunkManifest = new Map(); /** * @internal */ this.hashByPlaceholder = new Map(); /** * @internal */ this.addMissingIntegrityHashes = (assets) => { Object.entries(assets).forEach(([assetKey, asset]) => { const source = (0, util_1.tryGetSource)(asset); if (source && !this.assetIntegrity.has(assetKey)) { this.assetIntegrity.updateFromSource(assetKey, source); } }); }; /** * @internal */ this.replaceAsset = (compiler, assets, hashByPlaceholder, chunkFile) => { const asset = assets[chunkFile]; (0, util_1.assert)(asset, `Missing asset for file ${chunkFile}`); return (0, util_1.replaceInSource)(compiler, asset, chunkFile, hashByPlaceholder); }; this.warnAboutLongTermCaching = (assetInfo) => { if ((0, util_1.usesAnyHash)(assetInfo) && !(assetInfo.contenthash && this.compilation.compiler.options.optimization.realContentHash)) { this.reporter.warnContentHash(); } }; /** * @internal */ this.processChunk = (chunk, assets) => { Array.from((0, util_1.findChunks)(chunk)) .reverse() .forEach((chunk) => this.processChunkAssets(chunk, assets)); }; this.processChunkAssets = (childChunk, assets) => { Array.from(childChunk.files).forEach((sourcePath) => { const asset = assets[sourcePath]; if (asset) { this.warnIfHotUpdate(asset.source()); const newAsset = this.replaceAsset(this.compilation.compiler, assets, this.hashByPlaceholder, sourcePath); const integrity = this.assetIntegrity.updateFromSource(sourcePath, newAsset.source()); if (childChunk.id !== null) { this.hashByPlaceholder.set((0, util_1.makePlaceholder)(this.options.hashFuncNames, childChunk.id), integrity); } (0, util_1.updateAsset)(this.compilation, sourcePath, newAsset, integrity, this.warnAboutLongTermCaching); } else { this.reporter.warnNoAssetsFound(sourcePath, Object.keys(assets)); } }); }; /** * @internal */ this.addAttribute = (elName, source) => { if (!this.compilation.outputOptions.crossOriginLoading) { this.reporter.errorCrossOriginLoadingNotSet(); } return this.compilation.compiler.webpack.Template.asString([ source, elName + `.integrity = ${util_1.sriHashVariableReference}[chunkId];`, elName + ".crossOrigin = " + JSON.stringify(this.compilation.outputOptions.crossOriginLoading) + ";", ]); }; /** * @internal */ this.processAssets = (assets) => { if (this.options.hashLoading === "lazy") { for (const scc of this.sortedSccChunks) { for (const chunk of scc.nodes) { this.processChunkAssets(chunk, assets); } } } else { Array.from(this.compilation.chunks) .filter((chunk) => chunk.hasRuntime()) .forEach((chunk) => { this.processChunk(chunk, assets); }); } this.addMissingIntegrityHashes(assets); }; /** * @internal */ this.hwpAssetPath = (src) => { (0, util_1.assert)(this.hwpPublicPath !== null, "Missing HtmlWebpackPlugin publicPath"); return (0, path_1.relative)(this.hwpPublicPath, src); }; /** * @internal */ this.getIntegrityChecksumForAsset = (assets, src) => { if (this.assetIntegrity.has(src)) { return this.assetIntegrity.get(src); } const normalizedSrc = (0, util_1.normalizePath)(src); const normalizedKey = Object.keys(assets).find((assetKey) => (0, util_1.normalizePath)(assetKey) === normalizedSrc); return normalizedKey ? this.assetIntegrity.get(normalizedKey) : undefined; }; /** * @internal */ this.processTag = (tag) => { if (tag.attributes && Object.prototype.hasOwnProperty.call(tag.attributes, "integrity")) { return; } const tagSrc = (0, util_1.getTagSrc)(tag); if (!tagSrc) { return; } const src = this.hwpAssetPath(tagSrc); tag.attributes["integrity"] = this.getIntegrityChecksumForAsset(this.compilation.assets, src) || (0, util_1.computeIntegrity)(this.options.hashFuncNames, (0, fs_1.readFileSync)((0, path_1.join)(this.compilation.compiler.outputPath, src))); tag.attributes["crossorigin"] = this.compilation.compiler.options.output.crossOriginLoading || "anonymous"; }; /** * @internal */ this.beforeRuntimeRequirements = () => { if (this.options.hashLoading === "lazy") { const [sortedSccChunks, chunkManifest] = (0, manifest_1.getChunkToManifestMap)(this.compilation.chunks); this.sortedSccChunks = sortedSccChunks; this.chunkManifest = chunkManifest; } this.hashByPlaceholder.clear(); }; this.handleHwpPluginArgs = ({ assets }) => { this.hwpPublicPath = assets.publicPath; assetTypeIntegrityKeys.forEach(([a, b]) => { if (b) { assets[b] = assets[a] .map((filePath) => this.getIntegrityChecksumForAsset(this.compilation.assets, this.hwpAssetPath(filePath))) .filter(util_1.notNil); } }); }; this.handleHwpBodyTags = ({ headTags, bodyTags, }) => { this.addMissingIntegrityHashes(this.compilation.assets); headTags.concat(bodyTags).forEach(this.processTag); }; this.compilation = compilation; this.options = options; this.reporter = reporter; this.assetIntegrity = new integrity_1.AssetIntegrity(this.options.hashFuncNames); } /** * @internal */ warnIfHotUpdate(source) { if (source.indexOf("webpackHotUpdate") >= 0) { this.reporter.warnHotReloading(); } } getChildChunksToAddToChunkManifest(chunk) { var _a; return (_a = this.chunkManifest.get(chunk)) !== null && _a !== void 0 ? _a : new Set(); } updateHash(input, oldHash) { return this.assetIntegrity.updateHash(input, oldHash); } } exports.Plugin = Plugin; //# sourceMappingURL=plugin.js.map