Skip to content

Commit e889c7b

Browse files
committed
Merge branch 'main' into improve-runtime-template
2 parents 2b87b64 + 3eff82d commit e889c7b

File tree

63 files changed

+811
-327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+811
-327
lines changed

lib/ExternalModule.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -536,7 +536,7 @@ class ExternalModule extends Module {
536536
case "global":
537537
return getSourceForGlobalVariableExternal(
538538
request,
539-
runtimeTemplate.outputOptions.globalObject
539+
runtimeTemplate.globalObject
540540
);
541541
case "commonjs":
542542
case "commonjs2":

lib/FileSystemInfo.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,7 +2256,9 @@ class FileSystemInfo {
22562256
for (const path of managedItems) {
22572257
const cache = this._managedItems.get(path);
22582258
if (cache !== undefined) {
2259-
managedFiles.add(join(this.fs, path, "package.json"));
2259+
if (cache !== "missing") {
2260+
managedFiles.add(join(this.fs, path, "package.json"));
2261+
}
22602262
managedItemInfo.set(path, cache);
22612263
} else {
22622264
jobs++;
@@ -2269,7 +2271,9 @@ class FileSystemInfo {
22692271
}
22702272
jobError();
22712273
} else if (entry) {
2272-
managedFiles.add(join(this.fs, path, "package.json"));
2274+
if (entry !== "missing") {
2275+
managedFiles.add(join(this.fs, path, "package.json"));
2276+
}
22732277
managedItemInfo.set(path, entry);
22742278
jobDone();
22752279
} else {

lib/RuntimeTemplate.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,27 @@ Module has these incoming connections: ${Array.from(
5050
).join("")}`;
5151
};
5252

53+
/**
54+
* @param {string|undefined} definition global object definition
55+
* @returns {string} save to use global object
56+
*/
57+
function getGlobalObject(definition) {
58+
if (!definition) return definition;
59+
const trimmed = definition.trim();
60+
61+
if (
62+
// identifier, we do not need real identifier regarding ECMAScript/Unicode
63+
trimmed.match(/^[_\p{L}][_0-9\p{L}]*$/iu) ||
64+
// iife
65+
// call expression
66+
// expression in parentheses
67+
trimmed.match(/^([_\p{L}][_0-9\p{L}]*)?\(.*\)$/iu)
68+
)
69+
return trimmed;
70+
71+
return `Object(${trimmed})`;
72+
}
73+
5374
class RuntimeTemplate {
5475
/**
5576
* @param {Compilation} compilation the compilation
@@ -60,6 +81,7 @@ class RuntimeTemplate {
6081
this.compilation = compilation;
6182
this.outputOptions = outputOptions || {};
6283
this.requestShortener = requestShortener;
84+
this.globalObject = getGlobalObject(outputOptions.globalObject);
6385
}
6486

6587
isIIFE() {

lib/WatchIgnorePlugin.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,20 @@ class IgnoringWatchFileSystem {
8787
fileTimestamps.set(path, IGNORE_TIME_ENTRY);
8888
}
8989
return fileTimestamps;
90-
}
90+
},
91+
getInfo:
92+
watcher.getInfo &&
93+
(() => {
94+
const info = watcher.getInfo();
95+
const { fileTimeInfoEntries, contextTimeInfoEntries } = info;
96+
for (const path of ignoredFiles) {
97+
fileTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
98+
}
99+
for (const path of ignoredDirs) {
100+
contextTimeInfoEntries.set(path, IGNORE_TIME_ENTRY);
101+
}
102+
return info;
103+
})
91104
};
92105
}
93106
}

lib/Watching.js

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -109,30 +109,44 @@ class Watching {
109109
this.lastWatcherStartTime = Date.now();
110110
}
111111
this.compiler.fsStartTime = Date.now();
112-
this._mergeWithCollected(
113-
changedFiles ||
114-
(this.pausedWatcher &&
112+
if (
113+
changedFiles &&
114+
removedFiles &&
115+
fileTimeInfoEntries &&
116+
contextTimeInfoEntries
117+
) {
118+
this._mergeWithCollected(changedFiles, removedFiles);
119+
this.compiler.fileTimestamps = fileTimeInfoEntries;
120+
this.compiler.contextTimestamps = contextTimeInfoEntries;
121+
} else if (this.pausedWatcher) {
122+
if (this.pausedWatcher.getInfo) {
123+
const {
124+
changes,
125+
removals,
126+
fileTimeInfoEntries,
127+
contextTimeInfoEntries
128+
} = this.pausedWatcher.getInfo();
129+
this._mergeWithCollected(changes, removals);
130+
this.compiler.fileTimestamps = fileTimeInfoEntries;
131+
this.compiler.contextTimestamps = contextTimeInfoEntries;
132+
} else {
133+
this._mergeWithCollected(
115134
this.pausedWatcher.getAggregatedChanges &&
116-
this.pausedWatcher.getAggregatedChanges()),
117-
(this.compiler.removedFiles =
118-
removedFiles ||
119-
(this.pausedWatcher &&
135+
this.pausedWatcher.getAggregatedChanges(),
120136
this.pausedWatcher.getAggregatedRemovals &&
121-
this.pausedWatcher.getAggregatedRemovals()))
122-
);
123-
137+
this.pausedWatcher.getAggregatedRemovals()
138+
);
139+
this.compiler.fileTimestamps =
140+
this.pausedWatcher.getFileTimeInfoEntries();
141+
this.compiler.contextTimestamps =
142+
this.pausedWatcher.getContextTimeInfoEntries();
143+
}
144+
}
124145
this.compiler.modifiedFiles = this._collectedChangedFiles;
125146
this._collectedChangedFiles = undefined;
126147
this.compiler.removedFiles = this._collectedRemovedFiles;
127148
this._collectedRemovedFiles = undefined;
128149

129-
this.compiler.fileTimestamps =
130-
fileTimeInfoEntries ||
131-
(this.pausedWatcher && this.pausedWatcher.getFileTimeInfoEntries());
132-
this.compiler.contextTimestamps =
133-
contextTimeInfoEntries ||
134-
(this.pausedWatcher && this.pausedWatcher.getContextTimeInfoEntries());
135-
136150
const run = () => {
137151
if (this.compiler.idle) {
138152
return this.compiler.cache.endIdle(err => {

lib/container/ContainerEntryModule.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const AsyncDependenciesBlock = require("../AsyncDependenciesBlock");
1010
const Module = require("../Module");
1111
const RuntimeGlobals = require("../RuntimeGlobals");
1212
const Template = require("../Template");
13+
const StaticExportsDependency = require("../dependencies/StaticExportsDependency");
1314
const makeSerializable = require("../util/makeSerializable");
1415
const ContainerExposedDependency = require("./ContainerExposedDependency");
1516

@@ -104,6 +105,7 @@ class ContainerEntryModule extends Module {
104105
strict: true,
105106
topLevelDeclarations: new Set(["moduleMap", "get", "init"])
106107
};
108+
this.buildMeta.exportsType = "namespace";
107109

108110
this.clearDependenciesAndBlocks();
109111

@@ -127,6 +129,7 @@ class ContainerEntryModule extends Module {
127129
}
128130
this.addBlock(block);
129131
}
132+
this.addDependency(new StaticExportsDependency(["get", "init"], false));
130133

131134
callback();
132135
}

lib/esm/ModuleChunkFormatPlugin.js

Lines changed: 74 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,16 @@
55

66
"use strict";
77

8-
const { ConcatSource, RawSource } = require("webpack-sources");
8+
const { ConcatSource } = require("webpack-sources");
99
const { RuntimeGlobals } = require("..");
1010
const HotUpdateChunk = require("../HotUpdateChunk");
1111
const Template = require("../Template");
12+
const { getAllChunks } = require("../javascript/ChunkHelpers");
1213
const {
1314
getCompilationHooks,
1415
getChunkFilenameTemplate
1516
} = require("../javascript/JavascriptModulesPlugin");
16-
const {
17-
generateEntryStartup,
18-
updateHashForEntryStartup
19-
} = require("../javascript/StartupHelpers");
17+
const { updateHashForEntryStartup } = require("../javascript/StartupHelpers");
2018

2119
/** @typedef {import("../Compiler")} Compiler */
2220

@@ -84,63 +82,90 @@ class ModuleChunkFormatPlugin {
8482
}
8583
)
8684
.split("/");
87-
const runtimeOutputName = compilation
88-
.getPath(
89-
getChunkFilenameTemplate(
90-
runtimeChunk,
91-
compilation.outputOptions
92-
),
93-
{
94-
chunk: runtimeChunk,
95-
contentHashType: "javascript"
96-
}
97-
)
98-
.split("/");
9985

10086
// remove filename, we only need the directory
101-
const outputFilename = currentOutputName.pop();
87+
currentOutputName.pop();
10288

103-
// remove common parts
104-
while (
105-
currentOutputName.length > 0 &&
106-
runtimeOutputName.length > 0 &&
107-
currentOutputName[0] === runtimeOutputName[0]
108-
) {
109-
currentOutputName.shift();
110-
runtimeOutputName.shift();
111-
}
89+
const getRelativePath = chunk => {
90+
const baseOutputName = currentOutputName.slice();
91+
const chunkOutputName = compilation
92+
.getPath(
93+
getChunkFilenameTemplate(
94+
chunk,
95+
compilation.outputOptions
96+
),
97+
{
98+
chunk: chunk,
99+
contentHashType: "javascript"
100+
}
101+
)
102+
.split("/");
112103

113-
// create final path
114-
const runtimePath =
115-
(currentOutputName.length > 0
116-
? "../".repeat(currentOutputName.length)
117-
: "./") + runtimeOutputName.join("/");
104+
// remove common parts
105+
while (
106+
baseOutputName.length > 0 &&
107+
chunkOutputName.length > 0 &&
108+
baseOutputName[0] === chunkOutputName[0]
109+
) {
110+
baseOutputName.shift();
111+
chunkOutputName.shift();
112+
}
113+
// create final path
114+
return (
115+
(baseOutputName.length > 0
116+
? "../".repeat(baseOutputName.length)
117+
: "./") + chunkOutputName.join("/")
118+
);
119+
};
118120

119121
const entrySource = new ConcatSource();
120122
entrySource.add(source);
121123
entrySource.add(";\n\n// load runtime\n");
122124
entrySource.add(
123125
`import __webpack_require__ from ${JSON.stringify(
124-
runtimePath
125-
)};\n`
126-
);
127-
entrySource.add(
128-
`import * as __webpack_self_exports__ from ${JSON.stringify(
129-
"./" + outputFilename
126+
getRelativePath(runtimeChunk)
130127
)};\n`
131128
);
132-
entrySource.add(
133-
`${RuntimeGlobals.externalInstallChunk}(__webpack_self_exports__);\n`
134-
);
135-
const startupSource = new RawSource(
136-
generateEntryStartup(
137-
chunkGraph,
138-
runtimeTemplate,
139-
entries,
140-
chunk,
141-
false
142-
)
129+
130+
const startupSource = new ConcatSource();
131+
startupSource.add(
132+
`var __webpack_exec__ = ${runtimeTemplate.returningFunction(
133+
`__webpack_require__(${RuntimeGlobals.entryModuleId} = moduleId)`,
134+
"moduleId"
135+
)}\n`
143136
);
137+
138+
const loadedChunks = new Set();
139+
let index = 0;
140+
for (let i = 0; i < entries.length; i++) {
141+
const [module, entrypoint] = entries[i];
142+
const final = i + 1 === entries.length;
143+
const moduleId = chunkGraph.getModuleId(module);
144+
const chunks = getAllChunks(
145+
entrypoint,
146+
runtimeChunk,
147+
undefined
148+
);
149+
for (const chunk of chunks) {
150+
if (loadedChunks.has(chunk)) continue;
151+
loadedChunks.add(chunk);
152+
startupSource.add(
153+
`import * as __webpack_chunk_${index}__ from ${JSON.stringify(
154+
getRelativePath(chunk)
155+
)};\n`
156+
);
157+
startupSource.add(
158+
`${RuntimeGlobals.externalInstallChunk}(__webpack_chunk_${index}__);\n`
159+
);
160+
index++;
161+
}
162+
startupSource.add(
163+
`${
164+
final ? "var __webpack_exports__ = " : ""
165+
}__webpack_exec__(${JSON.stringify(moduleId)});\n`
166+
);
167+
}
168+
144169
entrySource.add(
145170
hooks.renderStartup.call(
146171
startupSource,

lib/javascript/ArrayPushCallbackChunkFormatPlugin.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class ArrayPushCallbackChunkFormatPlugin {
4545
const { chunk, chunkGraph, runtimeTemplate } = renderContext;
4646
const hotUpdateChunk =
4747
chunk instanceof HotUpdateChunk ? chunk : null;
48-
const globalObject = runtimeTemplate.outputOptions.globalObject;
48+
const globalObject = runtimeTemplate.globalObject;
4949
const source = new ConcatSource();
5050
const runtimeModules =
5151
chunkGraph.getChunkRuntimeModulesInOrder(chunk);
@@ -138,7 +138,7 @@ class ArrayPushCallbackChunkFormatPlugin {
138138
(chunk, hash, { chunkGraph, runtimeTemplate }) => {
139139
if (chunk.hasRuntime()) return;
140140
hash.update(
141-
`ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.outputOptions.globalObject}`
141+
`ArrayPushCallbackChunkFormatPlugin1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.globalObject}`
142142
);
143143
const entries = Array.from(
144144
chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)

lib/javascript/ChunkHelpers.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
MIT License http://www.opensource.org/licenses/mit-license.php
3+
Author Tobias Koppers @sokra
4+
*/
5+
6+
"use strict";
7+
8+
const Entrypoint = require("../Entrypoint");
9+
10+
/** @typedef {import("../Chunk")} Chunk */
11+
12+
/**
13+
* @param {Entrypoint} entrypoint a chunk group
14+
* @param {Chunk} excludedChunk1 current chunk which is excluded
15+
* @param {Chunk} excludedChunk2 runtime chunk which is excluded
16+
* @returns {Set<Chunk>} chunks
17+
*/
18+
const getAllChunks = (entrypoint, excludedChunk1, excludedChunk2) => {
19+
const queue = new Set([entrypoint]);
20+
const chunks = new Set();
21+
for (const entrypoint of queue) {
22+
for (const chunk of entrypoint.chunks) {
23+
if (chunk === excludedChunk1) continue;
24+
if (chunk === excludedChunk2) continue;
25+
chunks.add(chunk);
26+
}
27+
for (const parent of entrypoint.parentsIterable) {
28+
if (parent instanceof Entrypoint) queue.add(parent);
29+
}
30+
}
31+
return chunks;
32+
};
33+
exports.getAllChunks = getAllChunks;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy