mirror of https://github.com/webpack/webpack.git
Merge 5e51e31eb8
into c7dd066327
This commit is contained in:
commit
59deb897c5
|
@ -11,6 +11,7 @@ const mime = require("mime-types");
|
||||||
const Chunk = require("./Chunk");
|
const Chunk = require("./Chunk");
|
||||||
const Module = require("./Module");
|
const Module = require("./Module");
|
||||||
const { parseResource } = require("./util/identifier");
|
const { parseResource } = require("./util/identifier");
|
||||||
|
const nonNumericOnlyHash = require("./util/nonNumericOnlyHash");
|
||||||
|
|
||||||
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
/** @typedef {import("./ChunkGraph")} ChunkGraph */
|
||||||
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
|
/** @typedef {import("./ChunkGraph").ModuleId} ModuleId */
|
||||||
|
@ -63,7 +64,7 @@ const hashLength = (replacer, handler, assetInfo, hashName) => {
|
||||||
} else {
|
} else {
|
||||||
const hash = replacer(match, arg, input);
|
const hash = replacer(match, arg, input);
|
||||||
|
|
||||||
result = length ? hash.slice(0, length) : hash;
|
result = length ? nonNumericOnlyHash(hash, length) : hash;
|
||||||
}
|
}
|
||||||
if (assetInfo) {
|
if (assetInfo) {
|
||||||
assetInfo.immutable = true;
|
assetInfo.immutable = true;
|
||||||
|
|
|
@ -0,0 +1,143 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const TemplatedPathPlugin = require("../lib/TemplatedPathPlugin");
|
||||||
|
|
||||||
|
describe("TemplatedPathPlugin", () => {
|
||||||
|
describe("hash should be non-numeric", () => {
|
||||||
|
// Move capturedPathReplacer to higher scope to be accessible in all describe blocks
|
||||||
|
let capturedPathReplacer;
|
||||||
|
|
||||||
|
// Set up capturedPathReplacer for all tests
|
||||||
|
beforeEach(() => {
|
||||||
|
const mockCompilation = {
|
||||||
|
hooks: {
|
||||||
|
assetPath: {
|
||||||
|
tap: jest.fn((pluginName, pathReplacerFn) => {
|
||||||
|
capturedPathReplacer = pathReplacerFn;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mockCompiler = {
|
||||||
|
hooks: {
|
||||||
|
compilation: {
|
||||||
|
tap: jest.fn((pluginName, compilationFn) => {
|
||||||
|
compilationFn(mockCompilation);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply the plugin to capture the path replacer function
|
||||||
|
const plugin = new TemplatedPathPlugin();
|
||||||
|
plugin.apply(mockCompiler);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should prevent numeric-only chunkhash in filename templates", () => {
|
||||||
|
const mockChunk = {
|
||||||
|
id: "test-chunk",
|
||||||
|
name: "test-chunk",
|
||||||
|
renderedHash: "123456789012345678901234567890",
|
||||||
|
hash: "123456789012345678901234567890"
|
||||||
|
};
|
||||||
|
|
||||||
|
const pathData = {
|
||||||
|
chunk: mockChunk,
|
||||||
|
chunkGraph: {},
|
||||||
|
runtime: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = capturedPathReplacer("[name].[chunkhash:8].js", pathData);
|
||||||
|
|
||||||
|
// Should convert numeric-only hash to include letter prefix
|
||||||
|
expect(result).toBe("test-chunk.b2345678.js");
|
||||||
|
expect(result).toMatch(/^test-chunk\.[a-f]\d{7}\.js$/);
|
||||||
|
expect(result).not.toMatch(/^test-chunk\.\d{8}\.js$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should prevent numeric-only contenthash in filename templates", () => {
|
||||||
|
const mockChunk = {
|
||||||
|
id: "content-chunk",
|
||||||
|
name: "content-chunk",
|
||||||
|
renderedHash: "abc123def456",
|
||||||
|
hash: "abc123def456",
|
||||||
|
contentHash: {
|
||||||
|
javascript: "987654321098765432109876543210"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const pathData = {
|
||||||
|
chunk: mockChunk,
|
||||||
|
contentHashType: "javascript",
|
||||||
|
chunkGraph: {},
|
||||||
|
runtime: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = capturedPathReplacer(
|
||||||
|
"[name].[contenthash:6].js",
|
||||||
|
pathData
|
||||||
|
);
|
||||||
|
|
||||||
|
// Should convert numeric-only hash to include letter prefix
|
||||||
|
expect(result).toBe("content-chunk.d87654.js");
|
||||||
|
expect(result).toMatch(/^content-chunk\.[a-f]\d{5}\.js$/);
|
||||||
|
expect(result).not.toMatch(/^content-chunk\.\d{6}\.js$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should prevent numeric-only fullhash in filename templates", () => {
|
||||||
|
const pathData = {
|
||||||
|
hash: "111111111111111111111111111111",
|
||||||
|
chunkGraph: {},
|
||||||
|
runtime: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = capturedPathReplacer("bundle.[fullhash:10].js", pathData);
|
||||||
|
|
||||||
|
// Should convert numeric-only hash to include letter prefix
|
||||||
|
expect(result).toBe("bundle.b111111111.js");
|
||||||
|
expect(result).toMatch(/^bundle\.[a-f]\d{9}\.js$/);
|
||||||
|
expect(result).not.toMatch(/^bundle\.\d{10}\.js$/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should preserve alphanumeric hashes unchanged", () => {
|
||||||
|
const mockChunk = {
|
||||||
|
id: "mixed-chunk",
|
||||||
|
name: "mixed-chunk",
|
||||||
|
renderedHash: "abc123def456ghi789jkl012mno345",
|
||||||
|
hash: "abc123def456ghi789jkl012mno345"
|
||||||
|
};
|
||||||
|
|
||||||
|
const pathData = {
|
||||||
|
chunk: mockChunk,
|
||||||
|
chunkGraph: {},
|
||||||
|
runtime: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = capturedPathReplacer("[name].[chunkhash:8].js", pathData);
|
||||||
|
|
||||||
|
// Should preserve original hash since it contains non-numeric chars
|
||||||
|
expect(result).toBe("mixed-chunk.abc123de.js");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should handle zero-length hash parameter", () => {
|
||||||
|
const mockChunk = {
|
||||||
|
id: "zero-chunk",
|
||||||
|
name: "zero-chunk",
|
||||||
|
renderedHash: "123456789012345678901234567890",
|
||||||
|
hash: "123456789012345678901234567890"
|
||||||
|
};
|
||||||
|
|
||||||
|
const pathData = {
|
||||||
|
chunk: mockChunk,
|
||||||
|
chunkGraph: {},
|
||||||
|
runtime: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const result = capturedPathReplacer("[name].[chunkhash:0].js", pathData);
|
||||||
|
|
||||||
|
// When length is 0, it's treated as falsy and returns the full hash
|
||||||
|
expect(result).toBe("zero-chunk.123456789012345678901234567890.js");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue