Skip to content

Commit

Permalink
Add a reproduction for issue webpack#17747
Browse files Browse the repository at this point in the history
  • Loading branch information
ezzatron committed Feb 7, 2024
1 parent 51f0f0a commit b6afa32
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 0 deletions.
9 changes: 9 additions & 0 deletions test/__snapshots__/StatsTestCases.basictest.js.snap
Expand Up @@ -1392,6 +1392,15 @@ cacheable modules 101 bytes
webpack x.x.x compiled successfully in X ms"
`;

exports[`StatsTestCases should print correct stats for issue-17747 1`] = `
"asset issue-17747-chunk 1.73 KiB [emitted]
asset main.js 1.4 KiB [emitted] (name: main)
asset fe5639f39c635af0c4fa.json 36 bytes [emitted] [immutable] [from: entry.json]
asset 3ee037f347c64cc372ad.txt 4 bytes [emitted]
./index.js 20 bytes [built] [code generated]
webpack x.x.x compiled successfully in X ms"
`;

exports[`StatsTestCases should print correct stats for limit-chunk-count-plugin 1`] = `
"1 chunks:
asset bundle1.js 4.85 KiB [emitted] (name: main)
Expand Down
1 change: 1 addition & 0 deletions test/statsCases/issue-17747/asset.txt
@@ -0,0 +1 @@
foo
1 change: 1 addition & 0 deletions test/statsCases/issue-17747/entry.json
@@ -0,0 +1 @@
{"asset":"./asset.txt"}
1 change: 1 addition & 0 deletions test/statsCases/issue-17747/index.js
@@ -0,0 +1 @@
module.exports = 1;
25 changes: 25 additions & 0 deletions test/statsCases/issue-17747/loader.js
@@ -0,0 +1,25 @@
const { urlToRequest } = require("loader-utils");
const { createResolve } = require("./util.js");

/** @type {import("../../../types.js").LoaderDefinition<{ i: string }>} */
module.exports = function loader(entryJson) {
const callback = this.async();

main(this, entryJson)
.then((result) => {
callback(null, result);
})
.catch((error) => {
callback(error);
});
};

async function main(loader, entryJson) {
loader.cacheable();
const resolve = createResolve(loader);

const entry = JSON.parse(entryJson);
entry.asset = await resolve(urlToRequest(entry.asset));

return JSON.stringify(entry);
}
45 changes: 45 additions & 0 deletions test/statsCases/issue-17747/plugin.js
@@ -0,0 +1,45 @@
module.exports = function Issue17747Plugin() {
const loaderPath = require.resolve("./loader.js");

this.apply = (compiler) => {
const { context, webpack } = compiler;
const { EntryPlugin } = webpack;

compiler.hooks.make.tapPromise("Issue17747Plugin", handleMake);

async function handleMake(compilation) {
const {outputOptions: { publicPath: optionsPublicPath }} = compilation;
const publicPath = optionsPublicPath === "auto" ? "" : optionsPublicPath;
const outputOptions = { filename: "[name]", publicPath };

const childCompiler = compilation.createChildCompiler(
"Issue17747PluginChildCompiler",
outputOptions,
);
childCompiler.context = context;

const load = new EntryPlugin(
context,
`!!${loaderPath}!./entry.json`,
"issue-17747-chunk",
);
load.apply(childCompiler);

const [, childCompilation] = await new Promise(
(resolve, reject) => {
childCompiler.runAsChild((error, ...args) => {
error ? reject(error) : resolve(args);
});
},
);

if (childCompilation.errors.length > 0) {
const errorDetails = childCompilation.errors
.map(({ message, error }) => message + (error ? `:\n${error}` : ""))
.join("\n");

throw new Error(`Child compilation failed:\n${errorDetails}`);
}
}
};
};
67 changes: 67 additions & 0 deletions test/statsCases/issue-17747/util.js
@@ -0,0 +1,67 @@
const { interpolateName } = require("loader-utils");

module.exports = {
createResolve,
};

function createResolve(loader) {
return function resolve(request) {
return new Promise((resolve, reject) => {
loader.resolve(loader.context, request, (error, inputFilePath) => {
if (error) {
reject(error);

return;
}

loader.addDependency(inputFilePath);
loader.loadModule(inputFilePath, (error, source, sourceMap) => {
if (error) {
reject(error);

return;
}

let {
assetModuleFilename,
hashDigest,
hashDigestLength,
hashFunction,
} = loader._compilation.outputOptions;

assetModuleFilename = assetModuleFilename.replace(
/\[ext\]/gi,
".[ext]",
);
assetModuleFilename = assetModuleFilename.replace(
/\[(?:([^:\]]+):)?(hash|contenthash)(?::([a-z]+\d*))?(?::(\d+))?\]/gi,
(
_,
fn = hashFunction,
type,
digest = hashDigest,
length = hashDigestLength,
) => {
return `[${fn}:${type}:${digest}:${length}]`;
},
);

const outputFilePath = interpolateName(
{
resourcePath: inputFilePath,
},
assetModuleFilename,
{
context: loader.context,
content: source,
},
);

loader.emitFile(outputFilePath, source, sourceMap);

resolve(outputFilePath);
});
});
});
};
}
16 changes: 16 additions & 0 deletions test/statsCases/issue-17747/webpack.config.js
@@ -0,0 +1,16 @@
const Issue17747Plugin = require("./plugin.js");

/** @type {import("../../../").Configuration} */
module.exports = {
mode: "production",
entry: "./index.js",
plugins: [new Issue17747Plugin()],
module: {
rules: [
{
test: /\.(json|txt)$/,
type: "asset/resource"
}
]
}
};

0 comments on commit b6afa32

Please sign in to comment.