Skip to content

Commit 432cc68

Browse files
authored
Merge pull request #155 from waysact/chunk-multiple-files
Fix handling of chunks with multiple files
2 parents 50e743e + 82030ea commit 432cc68

File tree

6 files changed

+289
-46
lines changed

6 files changed

+289
-46
lines changed

examples/issue-154/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import "./style.css";
2+
3+
window.addEventListener("load", () => {
4+
const { integrity } = document.querySelector("link");
5+
const loaded = getComputedStyle(document.body).background.match(
6+
/rgb\(255, 0, 0\)/
7+
);
8+
9+
console.log(integrity && loaded ? "ok" : "error");
10+
});

examples/issue-154/package.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"name": "issue-154",
3+
"description": "Test case for https://github.com/waysact/webpack-subresource-integrity/issues/154",
4+
"version": "1.0.0",
5+
"license": "MIT",
6+
"private": true,
7+
"devDependencies": {
8+
"css-loader": "^5.1.0",
9+
"expect": "^26.6.2",
10+
"html-webpack-plugin": "^5.2.0",
11+
"mini-css-extract-plugin": "^1.3.8",
12+
"nyc": "*",
13+
"webpack": "^5.24.0",
14+
"webpack-cli": "4",
15+
"webpack-subresource-integrity": "*",
16+
"wsi-test-helper": "*"
17+
}
18+
}

examples/issue-154/style.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
body {
2+
background: red;
3+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
const HtmlWebpackPlugin = require("html-webpack-plugin");
2+
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
3+
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
4+
const expect = require("expect");
5+
const { RunInPuppeteerPlugin } = require("wsi-test-helper");
6+
7+
module.exports = {
8+
// mode: "development",
9+
devtool: "cheap-module-source-map",
10+
entry: "./index.js",
11+
output: {
12+
filename: "[contenthash].js",
13+
chunkFilename: "[contenthash].chunk.js",
14+
crossOriginLoading: "anonymous",
15+
},
16+
optimization: {
17+
moduleIds: "deterministic",
18+
realContentHash: true,
19+
chunkIds: "deterministic",
20+
runtimeChunk: "single",
21+
},
22+
module: {
23+
rules: [
24+
{
25+
test: /\.css$/i,
26+
use: [MiniCssExtractPlugin.loader, "css-loader"],
27+
},
28+
],
29+
},
30+
plugins: [
31+
new MiniCssExtractPlugin({
32+
filename: `[contenthash].css`,
33+
chunkFilename: `[contenthash].chunk.css`,
34+
}),
35+
new SubresourceIntegrityPlugin({ enabled: true }),
36+
new HtmlWebpackPlugin(),
37+
{
38+
apply: (compiler) => {
39+
compiler.hooks.done.tap("wsi-test", (stats) => {
40+
const cssAsset = stats
41+
.toJson()
42+
.assets.find((asset) => asset.name.match(/\.css$/));
43+
44+
expect(cssAsset.info.contenthash).toBeDefined();
45+
expect(
46+
cssAsset.info.contenthash.find((hash) => hash.match(/^sha/))
47+
).toBeDefined();
48+
expect(cssAsset.integrity).toBeDefined();
49+
});
50+
},
51+
},
52+
new RunInPuppeteerPlugin(),
53+
],
54+
};

webpack-subresource-integrity/index.ts

Lines changed: 52 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -298,49 +298,50 @@ export class SubresourceIntegrityPlugin {
298298
.forEach((childChunk: Chunk) => {
299299
const files = Array.from(childChunk.files);
300300

301-
let sourcePath = files[files.length - 1];
302-
if (!sourcePath) {
303-
return;
304-
}
301+
files.forEach((sourcePath) => {
302+
if (!sourcePath) {
303+
return;
304+
}
305305

306-
if (assets[sourcePath]) {
307-
this.warnIfHotUpdate(compilation, assets[sourcePath].source());
308-
const newAsset = this.replaceAsset(
309-
compilation.compiler,
310-
assets,
311-
hashByChunkId,
312-
sourcePath
313-
);
314-
const integrity = computeIntegrity(
315-
this.options.hashFuncNames,
316-
newAsset.source()
317-
);
318-
319-
if (childChunk.id !== null) {
320-
hashByChunkId.set(childChunk.id, integrity);
306+
if (assets[sourcePath]) {
307+
this.warnIfHotUpdate(compilation, assets[sourcePath].source());
308+
const newAsset = this.replaceAsset(
309+
compilation.compiler,
310+
assets,
311+
hashByChunkId,
312+
sourcePath
313+
);
314+
const integrity = computeIntegrity(
315+
this.options.hashFuncNames,
316+
newAsset.source()
317+
);
318+
319+
if (childChunk.id !== null) {
320+
hashByChunkId.set(childChunk.id, integrity);
321+
}
322+
this.updateAssetIntegrity(sourcePath, integrity);
323+
compilation.updateAsset(
324+
sourcePath,
325+
(x) => x,
326+
(assetInfo) =>
327+
assetInfo && {
328+
...assetInfo,
329+
contenthash: Array.isArray(assetInfo.contenthash)
330+
? [...new Set([...assetInfo.contenthash, integrity])]
331+
: assetInfo.contenthash
332+
? [assetInfo.contenthash, integrity]
333+
: integrity,
334+
}
335+
);
336+
} else {
337+
this.warnOnce(
338+
compilation,
339+
`No asset found for source path '${sourcePath}', options are ${Object.keys(
340+
assets
341+
).join(", ")}`
342+
);
321343
}
322-
this.updateAssetIntegrity(sourcePath, integrity);
323-
compilation.updateAsset(
324-
sourcePath,
325-
(x) => x,
326-
(assetInfo) =>
327-
assetInfo && {
328-
...assetInfo,
329-
contenthash: Array.isArray(assetInfo.contenthash)
330-
? [...new Set([...assetInfo.contenthash, integrity])]
331-
: assetInfo.contenthash
332-
? [assetInfo.contenthash, integrity]
333-
: integrity,
334-
}
335-
);
336-
} else {
337-
this.warnOnce(
338-
compilation,
339-
`No asset found for source path '${sourcePath}', options are ${Object.keys(
340-
assets
341-
).join(", ")}`
342-
);
343-
}
344+
});
344345
});
345346
};
346347

@@ -746,16 +747,21 @@ export class SubresourceIntegrityPlugin {
746747
);
747748

748749
compiler.hooks.compilation.tap(
749-
"DefaultStatsFactoryPlugin",
750+
thisPluginName,
750751
(compilation: Compilation) => {
751752
compilation.hooks.statsFactory.tap(thisPluginName, (statsFactory) => {
752753
statsFactory.hooks.extract
753754
.for("asset")
754755
.tap(thisPluginName, (object, asset) => {
755-
if (this.assetIntegrity.has(asset.name)) {
756-
(object as any).integrity = String(
757-
this.assetIntegrity.get(asset.name)
758-
);
756+
const contenthash = asset.info?.contenthash;
757+
if (contenthash) {
758+
const shaHashes = (Array.isArray(contenthash)
759+
? contenthash
760+
: [contenthash]
761+
).filter((hash: any) => String(hash).match(/^sha[0-9]+-/));
762+
if (shaHashes.length > 0) {
763+
(object as any).integrity = shaHashes.join(" ");
764+
}
759765
}
760766
});
761767
});

0 commit comments

Comments
 (0)