Skip to content

Commit

Permalink
perf(@angular-devkit/build-angular): change webpack hashing function …
Browse files Browse the repository at this point in the history
…to `xxhash64`

 `xxhash64` uses a faster WASM based hash mechanism.
  • Loading branch information
alan-agius4 authored and clydin committed Sep 29, 2021
1 parent 55be137 commit 4e0743c
Show file tree
Hide file tree
Showing 9 changed files with 42 additions and 42 deletions.
Expand Up @@ -143,7 +143,7 @@ async function _getServerModuleBundlePath(
throw new Error(`Could not find server output directory: ${outputPath}.`);
}

const re = /^main\.(?:[a-zA-Z0-9]{20}\.)?js$/;
const re = /^main\.(?:[a-zA-Z0-9]{16}\.)?js$/;
const maybeMain = fs.readdirSync(outputPath).find((x) => re.test(x));

if (!maybeMain) {
Expand Down
Expand Up @@ -58,7 +58,7 @@ describe('Browser Builder source map', () => {
outputHashing: OutputHashing.All,
});

expect(Object.keys(files).some((name) => /main\.[0-9a-f]{20}\.js.map/.test(name))).toBeTruthy();
expect(Object.keys(files).some((name) => /main\.[0-9a-f]{16}\.js.map/.test(name))).toBeTruthy();
});

it('does not output source map when disabled', async () => {
Expand Down
Expand Up @@ -120,7 +120,7 @@ describe('Browser Builder Web Worker support', () => {
// Worker bundle should have hash and minified code.
const workerBundle = host.fileMatchExists(
outputPath,
/src_app_app_worker_ts\.[0-9a-f]{20}\.js/,
/src_app_app_worker_ts\.[0-9a-f]{16}\.js/,
) as string;
expect(workerBundle).toBeTruthy('workerBundle should exist');
const workerContent = virtualFs.fileBufferToString(
Expand All @@ -131,7 +131,7 @@ describe('Browser Builder Web Worker support', () => {
expect(workerContent).toContain('"hello"===e&&postMessage');

// Main bundle should reference hashed worker bundle.
const mainBundle = host.fileMatchExists(outputPath, /main\.[0-9a-f]{20}\.js/) as string;
const mainBundle = host.fileMatchExists(outputPath, /main\.[0-9a-f]{16}\.js/) as string;
expect(mainBundle).toBeTruthy('mainBundle should exist');
const mainContent = virtualFs.fileBufferToString(
host.scopedSync().read(join(outputPath, mainBundle)),
Expand Down
Expand Up @@ -31,10 +31,10 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.css$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.css$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{20}\.png$/)).toBeTrue();
});

Expand All @@ -50,11 +50,11 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{20}\.png$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{16}\.png$/)).toBeFalse();
});

it(`doesn't hash any filenames when set to "none"`, async () => {
Expand All @@ -70,11 +70,11 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{20}\.png$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{16}\.png$/)).toBeFalse();
});

it(`hashes CSS resources filenames only when set to "media"`, async () => {
Expand All @@ -90,10 +90,10 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.css$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{20}\.png$/)).toBeTrue();
});

Expand All @@ -110,11 +110,11 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{20}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.css$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{20}\.png$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /runtime\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /main\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /polyfills\.[0-9a-f]{16}\.js$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.css$/)).toBeTrue();
expect(harness.hasFileMatch('dist', /spectrum\.[0-9a-f]{16}\.png$/)).toBeFalse();
});

it('does not hash non injected styles', async () => {
Expand All @@ -133,8 +133,8 @@ describeBuilder(buildWebpackBrowser, BROWSER_BUILDER_INFO, (harness) => {
const { result } = await harness.executeOnce();
expect(result?.success).toBe(true);

expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{20}\.js.map$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.js$/)).toBeFalse();
expect(harness.hasFileMatch('dist', /styles\.[0-9a-f]{16}\.js.map$/)).toBeFalse();
harness.expectFile('dist/styles.css').toExist();
harness.expectFile('dist/styles.css.map').toExist();
});
Expand Down
Expand Up @@ -342,6 +342,7 @@ export async function getCommonConfig(wco: WebpackConfigOptions): Promise<Config
context: root,
entry: entryPoints,
output: {
hashFunction: 'xxhash64', // todo: remove in webpack 6. This is part of `futureDefaults`.
clean: buildOptions.deleteOutputPath ?? true,
path: path.resolve(root, buildOptions.outputPath),
publicPath: buildOptions.deployUrl ?? '',
Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/basic/build.ts
Expand Up @@ -13,7 +13,7 @@ export default async function () {

// Production build
const { stderr: stderrProgress, stdout } = await ng('build', '--progress');
await expectFileToMatch('dist/test-project/index.html', /main\.[a-zA-Z0-9]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /main\.[a-zA-Z0-9]{16}\.js/);

if (!stdout.includes('Initial Total')) {
throw new Error(`Expected stdout to contain 'Initial Total' but it did not.\n${stdout}`);
Expand Down
17 changes: 8 additions & 9 deletions tests/legacy-cli/e2e/tests/build/output-hashing.ts
Expand Up @@ -2,7 +2,6 @@ import { copyProjectAsset } from '../../utils/assets';
import { expectFileMatchToExist, expectFileToMatch, writeMultipleFiles } from '../../utils/fs';
import { ng } from '../../utils/process';


async function verifyMedia(fileNameRe: RegExp, content: RegExp) {
const fileName = await expectFileMatchToExist('dist/test-project/', fileNameRe);
await expectFileToMatch(`dist/test-project/${fileName}`, content);
Expand All @@ -15,10 +14,10 @@ export default async function () {
// use image with file size >10KB to prevent inlining
await copyProjectAsset('images/spectrum.png', './src/assets/image.png');
await ng('build', '--output-hashing=all', '--configuration=development');
await expectFileToMatch('dist/test-project/index.html', /runtime\.[0-9a-f]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{20}\.(css|js)/);
await verifyMedia(/styles\.[0-9a-f]{20}\.(css|js)/, /image\.[0-9a-f]{20}\.png/);
await expectFileToMatch('dist/test-project/index.html', /runtime\.[0-9a-f]{16}\.js/);
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{16}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{16}\.(css|js)/);
await verifyMedia(/styles\.[0-9a-f]{16}\.(css|js)/, /image\.[0-9a-f]{20}\.png/);

await ng('build', '--output-hashing=none', '--configuration=development');
await expectFileToMatch('dist/test-project/index.html', /runtime\.js/);
Expand All @@ -33,8 +32,8 @@ export default async function () {
await verifyMedia(/styles\.(css|js)/, /image\.[0-9a-f]{20}\.png/);

await ng('build', '--output-hashing=bundles', '--configuration=development');
await expectFileToMatch('dist/test-project/index.html', /runtime\.[0-9a-f]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{20}\.(css|js)/);
await verifyMedia(/styles\.[0-9a-f]{20}\.(css|js)/, /image\.png/);
await expectFileToMatch('dist/test-project/index.html', /runtime\.[0-9a-f]{16}\.js/);
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{16}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{16}\.(css|js)/);
await verifyMedia(/styles\.[0-9a-f]{16}\.(css|js)/, /image\.png/);
}
4 changes: 2 additions & 2 deletions tests/legacy-cli/e2e/tests/build/prod-build.ts
Expand Up @@ -32,8 +32,8 @@ export default async function () {
await ng('build');
await expectFileToExist(join(process.cwd(), 'dist'));
// Check for cache busting hash script src
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{20}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{20}\.css/);
await expectFileToMatch('dist/test-project/index.html', /main\.[0-9a-f]{16}\.js/);
await expectFileToMatch('dist/test-project/index.html', /styles\.[0-9a-f]{16}\.css/);
await expectFileToMatch('dist/test-project/3rdpartylicenses.txt', /MIT/);

const indexContent = await readFile('dist/test-project/index.html');
Expand Down
2 changes: 1 addition & 1 deletion tests/legacy-cli/e2e/tests/update/update-9.ts
Expand Up @@ -50,5 +50,5 @@ export default async function () {

// Verify project now creates bundles
await noSilentNg('build', '--prod');
await expectFileMatchToExist('dist/nine-project/', /main\.[0-9a-f]{20}\.js/);
await expectFileMatchToExist('dist/nine-project/', /main\.[0-9a-f]{16}\.js/);
}

0 comments on commit 4e0743c

Please sign in to comment.