Skip to content

Commit

Permalink
Merge 09610ce into 3d93750
Browse files Browse the repository at this point in the history
  • Loading branch information
MLoughry committed Dec 20, 2021
2 parents 3d93750 + 09610ce commit 76ee0b0
Show file tree
Hide file tree
Showing 32 changed files with 783 additions and 83 deletions.
10 changes: 6 additions & 4 deletions examples/hwp-custom-template/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,16 @@ module.exports = {

const jsIntegrity = stats
.toJson()
.assets.find((asset) => asset.name === "subdir/bundle.js")
.integrity;
.assets.find(
(asset) => asset.name === "subdir/bundle.js"
).integrity;
expect(jsIntegrity).toMatch(/^sha/);

const cssIntegrity = stats
.toJson()
.assets.find((asset) => asset.name === "subdir/styles.css")
.integrity;
.assets.find(
(asset) => asset.name === "subdir/styles.css"
).integrity;
expect(cssIntegrity).toMatch(/^sha/);

return new Promise((resolve, reject) => {
Expand Down
5 changes: 5 additions & 0 deletions examples/lazy-hashes-cycles/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import("./2.js");
import("./leaf.js");
export default {
chunk: 1,
};
4 changes: 4 additions & 0 deletions examples/lazy-hashes-cycles/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import("./3.js");
export default {
chunk: 2,
};
4 changes: 4 additions & 0 deletions examples/lazy-hashes-cycles/3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import("./1.js");
export default {
chunk: 3,
};
3 changes: 3 additions & 0 deletions examples/lazy-hashes-cycles/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sourcemap and code splitting

Test case for lazy hashes where there is a chunk dependency cycle
3 changes: 3 additions & 0 deletions examples/lazy-hashes-cycles/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import("./1.js");
import("./2.js");
console.log("ok");
3 changes: 3 additions & 0 deletions examples/lazy-hashes-cycles/leaf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
chunk: "leaf",
};
16 changes: 16 additions & 0 deletions examples/lazy-hashes-cycles/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "lazy-hashes-cycles",
"description": "Test case for lazy hashes where there is a chunk dependency cycle",
"version": "1.0.0",
"license": "MIT",
"private": true,
"devDependencies": {
"expect": "^26.6.2",
"html-webpack-plugin": ">= 5.0.0-beta.1",
"nyc": "*",
"webpack": "^5.44.0",
"webpack-cli": "4",
"webpack-subresource-integrity": "*",
"wsi-test-helper": "*"
}
}
71 changes: 71 additions & 0 deletions examples/lazy-hashes-cycles/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { readFileSync } = require("fs");
const { join } = require("path");
const expect = require("expect");

module.exports = {
entry: {
index: "./index.js",
},
output: {
crossOriginLoading: "anonymous",
},
plugins: [
new SubresourceIntegrityPlugin({
enabled: true,
lazyHashes: true,
}),
new HtmlWebpackPlugin(),
{
apply: (compiler) => {
compiler.hooks.done.tap("wsi-test", (stats) => {
if (stats && stats.hasErrors()) {
throw new Error(
stats
.toJson()
.errors.map((error) => error.message)
.join(", ")
);
}
function getSriHashes(chunkName, isEntry) {
const fileContent = readFileSync(
join(__dirname, "dist", `${chunkName}.js`),
"utf-8"
);
const sriRegex = new RegExp(
`${
isEntry ? "self.sriHashes=" : "Object.assign\\(self.sriHashes,"
}(?<sriHashJson>\{.*?\})`
);
const regexMatch = sriRegex.exec(fileContent);
const sriHashJson = regexMatch ? regexMatch.groups.sriHashJson : null;
if (!sriHashJson) {
return null;
}
try {
// The hashes are not *strict* JSON, since they can have numerical keys
return JSON.parse(
sriHashJson.replace(/\d+(?=:)/g, (num) => `"${num}"`)
);
} catch (err) {
throw new Error(
`Could not parse SRI hashes \n\t${sriHashJson}\n in asset: ${err}`
);
}
}

const indexHashes = getSriHashes("index", true);
expect(Object.keys(indexHashes).length).toEqual(3);

expect(
stats
.toJson()
.assets.filter(({ name }) => /\.js$/.test(name))
.every(({ integrity }) => !!integrity)
).toEqual(true);
});
},
},
],
};
4 changes: 4 additions & 0 deletions examples/lazy-hashes-multiple-parents/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import("./leaf.js");
export default {
chunk: 1,
};
4 changes: 4 additions & 0 deletions examples/lazy-hashes-multiple-parents/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import("./leaf.js");
export default {
chunk: 2,
};
3 changes: 3 additions & 0 deletions examples/lazy-hashes-multiple-parents/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sourcemap and code splitting

Test case for sourcemap and code splitting
3 changes: 3 additions & 0 deletions examples/lazy-hashes-multiple-parents/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import("./1.js");
import("./2.js");
console.log("ok");
3 changes: 3 additions & 0 deletions examples/lazy-hashes-multiple-parents/leaf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
chunk: "leaf",
};
16 changes: 16 additions & 0 deletions examples/lazy-hashes-multiple-parents/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "lazy-hashes-multiple-parents",
"description": "Test case for lazy hashes where a chunk has multiple parents",
"version": "1.0.0",
"license": "MIT",
"private": true,
"devDependencies": {
"expect": "^26.6.2",
"html-webpack-plugin": ">= 5.0.0-beta.1",
"nyc": "*",
"webpack": "^5.44.0",
"webpack-cli": "4",
"webpack-subresource-integrity": "*",
"wsi-test-helper": "*"
}
}
82 changes: 82 additions & 0 deletions examples/lazy-hashes-multiple-parents/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { readFileSync } = require("fs");
const { join } = require("path");
const expect = require("expect");

module.exports = {
entry: {
index: "./index.js",
},
output: {
crossOriginLoading: "anonymous",
},
plugins: [
new SubresourceIntegrityPlugin({
enabled: true,
lazyHashes: true,
}),
new HtmlWebpackPlugin(),
{
apply: (compiler) => {
compiler.hooks.done.tap("wsi-test", (stats) => {
if (stats && stats.hasErrors()) {
throw new Error(
stats
.toJson()
.errors.map((error) => error.message)
.join(", ")
);
}
function getSriHashes(chunkName, isEntry) {
const fileContent = readFileSync(
join(__dirname, "dist", `${chunkName}.js`),
"utf-8"
);
const sriRegex = new RegExp(
`${
isEntry ? "self.sriHashes=" : "Object.assign\\(self.sriHashes,"
}(?<sriHashJson>\{.*?\})`
);
const regexMatch = sriRegex.exec(fileContent);
const sriHashJson = regexMatch ? regexMatch.groups.sriHashJson : null;
if (!sriHashJson) {
return null;
}
try {
// The hashes are not *strict* JSON, since they can have numerical keys
return JSON.parse(
sriHashJson.replace(/\d+(?=:)/g, (num) => `"${num}"`)
);
} catch (err) {
throw new Error(
`Could not parse SRI hashes \n\t${sriHashJson}\n in asset: ${err}`
);
}
}

const indexHashes = getSriHashes("index", true);
expect(Object.keys(indexHashes).length).toEqual(2);

const chunkHashes = Object.fromEntries(
Object.keys(indexHashes).map((chunkId) => [
chunkId,
getSriHashes(chunkId, false),
])
);

for (const [, intermediateChunkHash] of Object.entries(chunkHashes)) {
expect(Object.keys(intermediateChunkHash).length).toEqual(1);
}

expect(
stats
.toJson()
.assets.filter(({ name }) => /\.js$/.test(name))
.every(({ integrity }) => !!integrity)
).toEqual(true);
});
},
},
],
};
4 changes: 4 additions & 0 deletions examples/lazy-hashes-simple/1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import("./2.js");
export default {
chunk: 1,
};
3 changes: 3 additions & 0 deletions examples/lazy-hashes-simple/2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export default {
chunk: 2,
};
3 changes: 3 additions & 0 deletions examples/lazy-hashes-simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Sourcemap and code splitting

Simple test case for lazy hashes
2 changes: 2 additions & 0 deletions examples/lazy-hashes-simple/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import("./1.js");
console.log("ok");
16 changes: 16 additions & 0 deletions examples/lazy-hashes-simple/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "lazy-hashes-simple",
"description": "Simple test case for lazy hashes",
"version": "1.0.0",
"license": "MIT",
"private": true,
"devDependencies": {
"expect": "^26.6.2",
"html-webpack-plugin": ">= 5.0.0-beta.1",
"nyc": "*",
"webpack": "^5.44.0",
"webpack-cli": "4",
"webpack-subresource-integrity": "*",
"wsi-test-helper": "*"
}
}
77 changes: 77 additions & 0 deletions examples/lazy-hashes-simple/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
const { SubresourceIntegrityPlugin } = require("webpack-subresource-integrity");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const { readFileSync } = require("fs");
const { join } = require("path");
const expect = require("expect");

module.exports = {
entry: {
index: "./index.js",
},
output: {
crossOriginLoading: "anonymous",
},
plugins: [
new SubresourceIntegrityPlugin({
enabled: true,
lazyHashes: true,
}),
new HtmlWebpackPlugin(),
{
apply: (compiler) => {
compiler.hooks.done.tap("wsi-test", (stats) => {
if (stats && stats.hasErrors()) {
throw new Error(
stats
.toJson()
.errors.map((error) => error.message)
.join(", ")
);
}
function getSriHashes(chunkName, isEntry) {
const fileContent = readFileSync(
join(__dirname, "dist", `${chunkName}.js`),
"utf-8"
);
const sriRegex = new RegExp(
`${
isEntry ? "self.sriHashes=" : "Object.assign\\(self.sriHashes,"
}(?<sriHashJson>\{.*?\})`
);
const regexMatch = sriRegex.exec(fileContent);
const sriHashJson = regexMatch ? regexMatch.groups.sriHashJson : null;
if (!sriHashJson) {
return null;
}
try {
// The hashes are not *strict* JSON, since they can have numerical keys
return JSON.parse(
sriHashJson.replace(/\d+(?=:)/g, (num) => `"${num}"`)
);
} catch (err) {
throw new Error(
`Could not parse SRI hashes \n\t${sriHashJson}\n in asset: ${err}`
);
}
}

const indexHashes = getSriHashes("index", true);
expect(Object.keys(indexHashes).length).toEqual(1);

const _1jsHashes = getSriHashes(Object.keys(indexHashes)[0], false);
expect(Object.keys(_1jsHashes).length).toEqual(1);

const _2jsHashes = getSriHashes(Object.keys(_1jsHashes)[0], false);
expect(_2jsHashes).toEqual(null);

expect(
stats
.toJson()
.assets.filter(({ name }) => /\.js$/.test(name))
.every(({ integrity }) => !!integrity)
).toEqual(true);
});
},
},
],
};
2 changes: 1 addition & 1 deletion examples/sourcemap-code-splitting/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ module.exports = {
);
const sriHashesInMap = findAndStripSriHashString(
"dist/index.js.map",
"__webpack_require__.sriHashes = "
"self.sriHashes = "
);
expect(sriHashesInSource.length).toEqual(sriHashesInMap.length);
});
Expand Down
12 changes: 12 additions & 0 deletions webpack-subresource-integrity/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,18 @@ One of `"auto"`, `true`, or `false`.
mode](https://webpack.js.org/configuration/mode/) is `production` or
`none` and disable it when it is `development`.

#### lazyHashes

Default value: `false`

A boolean used to control where the integrity hashes will be defined.

`false` means that integrity hashes for all assets will be defined in the entry chunk.

`true` means that integrity hashes for any given asset will be defined in its direct parents
in the chunk graph. This can lead to duplication of hashes across assets, but can significantly
reduce the size of your entry chunk(s) if you have a large number of async chunks.

## Exporting `integrity` values

You might want to export generated integrity hashes, perhaps for use
Expand Down

0 comments on commit 76ee0b0

Please sign in to comment.