Skip to content

Commit 2665fb1

Browse files
committed
add baseUri entry option
1 parent dfdc8b1 commit 2665fb1

15 files changed

Lines changed: 167 additions & 46 deletions

declarations/WebpackOptions.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1042,6 +1042,10 @@ export interface EntryDescription {
10421042
* Enable/disable creating async chunks that are loaded on demand.
10431043
*/
10441044
asyncChunks?: boolean;
1045+
/**
1046+
* Base uri for this entry.
1047+
*/
1048+
baseUri?: string;
10451049
/**
10461050
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
10471051
*/
@@ -2756,6 +2760,10 @@ export interface EntryDescriptionNormalized {
27562760
* Enable/disable creating async chunks that are loaded on demand.
27572761
*/
27582762
asyncChunks?: boolean;
2763+
/**
2764+
* Base uri for this entry.
2765+
*/
2766+
baseUri?: string;
27592767
/**
27602768
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
27612769
*/

lib/EntryOptionPlugin.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ class EntryOptionPlugin {
6262
runtime: desc.runtime,
6363
layer: desc.layer,
6464
dependOn: desc.dependOn,
65+
baseUri: desc.baseUri,
6566
publicPath: desc.publicPath,
6667
chunkLoading: desc.chunkLoading,
6768
asyncChunks: desc.asyncChunks,

lib/config/normalization.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,7 @@ const getNormalizedEntryStatic = entry => {
488488
filename: value.filename,
489489
layer: value.layer,
490490
runtime: value.runtime,
491+
baseUri: value.baseUri,
491492
publicPath: value.publicPath,
492493
chunkLoading: value.chunkLoading,
493494
asyncChunks: value.asyncChunks,

lib/dependencies/LoaderPlugin.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const LoaderImportDependency = require("./LoaderImportDependency");
3232
* @typedef {Object} ImportModuleOptions
3333
* @property {string=} layer the target layer
3434
* @property {string=} publicPath the target public path
35+
* @property {string=} baseUri target base uri
3536
*/
3637

3738
class LoaderPlugin {
@@ -199,6 +200,7 @@ class LoaderPlugin {
199200
referencedModule,
200201
{
201202
entryOptions: {
203+
baseUri: options.baseUri,
202204
publicPath: options.publicPath
203205
}
204206
},

lib/esm/ModuleChunkLoadingRuntimeModule.js

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,27 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
5555
this._runtimeRequirements = runtimeRequirements;
5656
}
5757

58+
/**
59+
* @private
60+
* @param {Chunk} chunk chunk
61+
* @param {string} rootOutputDir root output directory
62+
* @returns {string} generated code
63+
*/
64+
_generateBaseUri(chunk, rootOutputDir) {
65+
const options = chunk.getEntryOptions();
66+
if (options && options.baseUri) {
67+
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)}`;
68+
}
69+
const {
70+
compilation: {
71+
outputOptions: { importMetaName }
72+
}
73+
} = this;
74+
return `${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
75+
rootOutputDir
76+
)}, ${importMetaName}.url);`;
77+
}
78+
5879
/**
5980
* @returns {string} runtime code
6081
*/
@@ -63,7 +84,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
6384
const {
6485
runtimeTemplate,
6586
chunkGraph,
66-
outputOptions: { importFunctionName, importMetaName }
87+
outputOptions: { importFunctionName }
6788
} = compilation;
6889
const fn = RuntimeGlobals.ensureChunkHandlers;
6990
const withBaseURI = this._runtimeRequirements.has(RuntimeGlobals.baseURI);
@@ -102,11 +123,7 @@ class ModuleChunkLoadingRuntimeModule extends RuntimeModule {
102123

103124
return Template.asString([
104125
withBaseURI
105-
? Template.asString([
106-
`${RuntimeGlobals.baseURI} = new URL(${JSON.stringify(
107-
rootOutputDir
108-
)}, ${importMetaName}.url);`
109-
])
126+
? this._generateBaseUri(chunk, rootOutputDir)
110127
: "// no baseURI",
111128
"",
112129
"// object to store loaded and loading chunks",

lib/node/ReadFileChunkLoadingRuntimeModule.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,33 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
1515
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
1616
const { getUndoPath } = require("../util/identifier");
1717

18+
/** @typedef {import("../Chunk")} Chunk */
19+
1820
class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
1921
constructor(runtimeRequirements) {
2022
super("readFile chunk loading", RuntimeModule.STAGE_ATTACH);
2123
this.runtimeRequirements = runtimeRequirements;
2224
}
2325

26+
/**
27+
* @private
28+
* @param {Chunk} chunk chunk
29+
* @param {string} rootOutputDir root output directory
30+
* @returns {string} generated code
31+
*/
32+
_generateBaseUri(chunk, rootOutputDir) {
33+
const options = chunk.getEntryOptions();
34+
if (options && options.baseUri) {
35+
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)}`;
36+
}
37+
38+
return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
39+
rootOutputDir
40+
? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
41+
: "__filename"
42+
});`;
43+
}
44+
2445
/**
2546
* @returns {string} runtime code
2647
*/
@@ -67,13 +88,7 @@ class ReadFileChunkLoadingRuntimeModule extends RuntimeModule {
6788

6889
return Template.asString([
6990
withBaseURI
70-
? Template.asString([
71-
`${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
72-
rootOutputDir
73-
? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
74-
: "__filename"
75-
});`
76-
])
91+
? this._generateBaseUri(chunk, rootOutputDir)
7792
: "// no baseURI",
7893
"",
7994
"// object to store loaded chunks",

lib/node/RequireChunkLoadingRuntimeModule.js

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,33 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
1515
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
1616
const { getUndoPath } = require("../util/identifier");
1717

18+
/** @typedef {import("../Chunk")} Chunk */
19+
1820
class RequireChunkLoadingRuntimeModule extends RuntimeModule {
1921
constructor(runtimeRequirements) {
2022
super("require chunk loading", RuntimeModule.STAGE_ATTACH);
2123
this.runtimeRequirements = runtimeRequirements;
2224
}
2325

26+
/**
27+
* @private
28+
* @param {Chunk} chunk chunk
29+
* @param {string} rootOutputDir root output directory
30+
* @returns {string} generated code
31+
*/
32+
_generateBaseUri(chunk, rootOutputDir) {
33+
const options = chunk.getEntryOptions();
34+
if (options && options.baseUri) {
35+
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)}`;
36+
}
37+
38+
return `${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
39+
rootOutputDir !== "./"
40+
? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
41+
: "__filename"
42+
});`;
43+
}
44+
2445
/**
2546
* @returns {string} runtime code
2647
*/
@@ -67,13 +88,7 @@ class RequireChunkLoadingRuntimeModule extends RuntimeModule {
6788

6889
return Template.asString([
6990
withBaseURI
70-
? Template.asString([
71-
`${RuntimeGlobals.baseURI} = require("url").pathToFileURL(${
72-
rootOutputDir !== "./"
73-
? `__dirname + ${JSON.stringify("/" + rootOutputDir)}`
74-
: "__filename"
75-
});`
76-
])
91+
? this._generateBaseUri(chunk, rootOutputDir)
7792
: "// no baseURI",
7893
"",
7994
"// object to store loaded chunks",

lib/web/JsonpChunkLoadingRuntimeModule.js

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,20 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
5151
this._runtimeRequirements = runtimeRequirements;
5252
}
5353

54+
/**
55+
* @private
56+
* @param {Chunk} chunk chunk
57+
* @returns {string} generated code
58+
*/
59+
_generateBaseUri(chunk) {
60+
const options = chunk.getEntryOptions();
61+
if (options && options.baseUri) {
62+
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)}`;
63+
} else {
64+
return `${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;`;
65+
}
66+
}
67+
5468
/**
5569
* @returns {string} runtime code
5670
*/
@@ -103,11 +117,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
103117
: undefined;
104118

105119
return Template.asString([
106-
withBaseURI
107-
? Template.asString([
108-
`${RuntimeGlobals.baseURI} = document.baseURI || self.location.href;`
109-
])
110-
: "// no baseURI",
120+
withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI",
111121
"",
112122
"// object to store loaded and loading chunks",
113123
"// undefined = chunk not loaded, null = chunk preloaded/prefetched",

lib/webworker/ImportScriptsChunkLoadingRuntimeModule.js

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,42 @@ const { getInitialChunkIds } = require("../javascript/StartupHelpers");
1515
const compileBooleanMatcher = require("../util/compileBooleanMatcher");
1616
const { getUndoPath } = require("../util/identifier");
1717

18+
/** @typedef {import("../Chunk")} Chunk */
19+
1820
class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
1921
constructor(runtimeRequirements, withCreateScriptUrl) {
2022
super("importScripts chunk loading", RuntimeModule.STAGE_ATTACH);
2123
this.runtimeRequirements = runtimeRequirements;
2224
this._withCreateScriptUrl = withCreateScriptUrl;
2325
}
2426

27+
/**
28+
* @private
29+
* @param {Chunk} chunk chunk
30+
* @returns {string} generated code
31+
*/
32+
_generateBaseUri(chunk) {
33+
const options = chunk.getEntryOptions();
34+
if (options && options.baseUri) {
35+
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)}`;
36+
}
37+
const outputName = this.compilation.getPath(
38+
getChunkFilenameTemplate(chunk, this.compilation.outputOptions),
39+
{
40+
chunk,
41+
contentHashType: "javascript"
42+
}
43+
);
44+
const rootOutputDir = getUndoPath(
45+
outputName,
46+
this.compilation.outputOptions.path,
47+
false
48+
);
49+
return `${RuntimeGlobals.baseURI} = self.location + ${JSON.stringify(
50+
rootOutputDir ? "/../" + rootOutputDir : ""
51+
)};`;
52+
}
53+
2554
/**
2655
* @returns {string} runtime code
2756
*/
@@ -55,31 +84,12 @@ class ImportScriptsChunkLoadingRuntimeModule extends RuntimeModule {
5584
);
5685
const initialChunkIds = getInitialChunkIds(chunk, chunkGraph, chunkHasJs);
5786

58-
const outputName = this.compilation.getPath(
59-
getChunkFilenameTemplate(chunk, this.compilation.outputOptions),
60-
{
61-
chunk,
62-
contentHashType: "javascript"
63-
}
64-
);
65-
const rootOutputDir = getUndoPath(
66-
outputName,
67-
this.compilation.outputOptions.path,
68-
false
69-
);
70-
7187
const stateExpression = withHmr
7288
? `${RuntimeGlobals.hmrRuntimeStatePrefix}_importScripts`
7389
: undefined;
7490

7591
return Template.asString([
76-
withBaseURI
77-
? Template.asString([
78-
`${RuntimeGlobals.baseURI} = self.location + ${JSON.stringify(
79-
rootOutputDir ? "/../" + rootOutputDir : ""
80-
)};`
81-
])
82-
: "// no baseURI",
92+
withBaseURI ? this._generateBaseUri(chunk) : "// no baseURI",
8393
"",
8494
"// object to store loaded chunks",
8595
'// "1" means "already loaded"',

schemas/WebpackOptions.check.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)