Merge pull request #10139 from yurynix/relative-dir-runtime-chunk-loading

Make inner folder entrypoints able to require common chunks
This commit is contained in:
Tobias Koppers 2020-01-17 11:39:52 +01:00 committed by GitHub
commit 6400fd42b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 95 additions and 22 deletions

View File

@ -209,10 +209,11 @@ class JavascriptModulesPlugin {
chunk instanceof HotUpdateChunk ? chunk : null;
let render;
let filenameTemplate;
const filenameTemplate = JavascriptModulesPlugin.getChunkFilenameTemplate(
chunk,
outputOptions
);
if (hotUpdateChunk) {
filenameTemplate = outputOptions.hotUpdateChunkFilename;
render = () =>
this.renderChunk(
{
@ -226,9 +227,6 @@ class JavascriptModulesPlugin {
hooks
);
} else if (chunk.hasRuntime()) {
filenameTemplate =
chunk.filenameTemplate || outputOptions.filename;
render = () =>
this.renderMain(
{
@ -247,14 +245,6 @@ class JavascriptModulesPlugin {
return result;
}
if (chunk.filenameTemplate) {
filenameTemplate = chunk.filenameTemplate;
} else if (chunk.isOnlyInitial()) {
filenameTemplate = outputOptions.filename;
} else {
filenameTemplate = outputOptions.chunkFilename;
}
render = () =>
this.renderChunk(
{
@ -356,6 +346,18 @@ class JavascriptModulesPlugin {
);
}
static getChunkFilenameTemplate(chunk, outputOptions) {
if (chunk.filenameTemplate) {
return chunk.filenameTemplate;
} else if (chunk instanceof HotUpdateChunk) {
return outputOptions.hotUpdateChunkFilename;
} else if (chunk.hasRuntime() || chunk.isOnlyInitial()) {
return outputOptions.filename;
} else {
return outputOptions.chunkFilename;
}
}
/**
* @param {Module} module the rendered module
* @param {RenderContext} renderContext options object

View File

@ -7,7 +7,10 @@
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
const chunkHasJs = require("../javascript/JavascriptModulesPlugin").chunkHasJs;
const {
chunkHasJs,
getChunkFilenameTemplate
} = require("../javascript/JavascriptModulesPlugin");
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
class RequireChunkLoadingRuntimeModule extends RuntimeModule {
@ -35,6 +38,24 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
const hasJsMatcher = compileBooleanMatcher(
chunkGraph.getChunkConditionMap(chunk, chunkHasJs)
);
let rootOutputDir = "'./'";
const chunkHasEntryModule = chunkGraph.getNumberOfEntryModules(chunk) > 0;
if (chunkHasEntryModule) {
const outputName = this.compilation.getPath(
getChunkFilenameTemplate(chunk, this.compilation.outputOptions),
{
chunk,
contentHashType: "javascript"
}
);
const chunkInnerDirsCount = outputName.split("/").length - 1;
rootOutputDir =
chunkInnerDirsCount > 0
? JSON.stringify("../".repeat(chunkInnerDirsCount))
: '"./"';
}
return Template.asString([
"// object to store loaded chunks",
'// "1" means "loaded", otherwise not loaded yet',
@ -58,7 +79,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
? "if(true) { // all chunks have JS"
: `if(${hasJsMatcher("chunkId")}) {`,
Template.indent([
`var chunk = require("./" + ${RuntimeGlobals.getChunkScriptFilename}(chunkId));`,
`var chunk = require(${rootOutputDir} + ${RuntimeGlobals.getChunkScriptFilename}(chunkId));`,
"var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;",
"for(var moduleId in moreModules) {",
Template.indent([

View File

@ -124,7 +124,7 @@ class GetChunkFilenameRuntimeModule extends RuntimeModule {
return '" + chunkId + "';
}
const s = JSON.stringify(str);
return s.slice(1, s.length - 2);
return s.slice(1, s.length - 1);
};
const unquotedStringifyWithLength = value => length =>
unquotedStringify(`${value}`.slice(0, length));

View File

@ -201,13 +201,12 @@ describe("ConfigTestCases", () => {
let content;
let p;
if (Array.isArray(module)) {
p = path.join(currentDirectory, module[0]);
content = module
p = path.join(currentDirectory, ".array-require.js");
content = `module.exports = (${module
.map(arg => {
p = path.join(currentDirectory, arg);
return fs.readFileSync(p, "utf-8");
return `require(${JSON.stringify(`./${arg}`)})`;
})
.join("\n");
.join(", ")});`;
} else {
p = path.join(currentDirectory, module);
content = fs.readFileSync(p, "utf-8");

View File

@ -0,0 +1,8 @@
import dummy from "dummy_module";
it("should load", () => {
expect(dummy()).toBe("this is just a dummy function");
return import("./inner-dir/b").then(importedModule => {
expect(importedModule.dummy()).toBe("this is just a dummy function");
});
});

View File

@ -0,0 +1,10 @@
import dummy from "dummy_module";
it("should load", () => {
expect(dummy()).toBe("this is just a dummy function");
return import("./some-module").then(importedModule => {
expect(importedModule.dummy()).toBe("this is just a dummy function");
});
});
export { dummy };

View File

@ -0,0 +1,2 @@
import dummy from "dummy_module";
export { dummy };

View File

@ -0,0 +1,3 @@
export default function someDummyFunction() {
return "this is just a dummy function";
}

View File

@ -0,0 +1,5 @@
module.exports = {
findBundle: function() {
return ["./a.js", "./inner-dir/b.js", "./inner-dir/deep/deep/c.js"];
}
};

View File

@ -0,0 +1,23 @@
module.exports = {
mode: "none",
entry: {
a: "./a?1",
"inner-dir/b": "./inner-dir/b",
"inner-dir/deep/deep/c": "./a?2"
},
target: "node",
output: {
libraryTarget: "commonjs2",
pathinfo: true,
filename: "[name].js",
chunkFilename: "[name].chunk.min.js"
},
optimization: {
minimize: false,
concatenateModules: false,
splitChunks: {
chunks: "all",
minSize: 0
}
}
};