first commit

This commit is contained in:
monjack
2025-06-20 18:01:48 +08:00
commit 6daa6d65c1
24611 changed files with 2512443 additions and 0 deletions

View File

@ -0,0 +1,46 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
class ChunkPrefetchFunctionRuntimeModule extends RuntimeModule {
/**
* @param {string} childType TODO
* @param {string} runtimeFunction TODO
* @param {string} runtimeHandlers TODO
*/
constructor(childType, runtimeFunction, runtimeHandlers) {
super(`chunk ${childType} function`);
this.childType = childType;
this.runtimeFunction = runtimeFunction;
this.runtimeHandlers = runtimeHandlers;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const { runtimeFunction, runtimeHandlers } = this;
const compilation = /** @type {Compilation} */ (this.compilation);
const { runtimeTemplate } = compilation;
return Template.asString([
`${runtimeHandlers} = {};`,
`${runtimeFunction} = ${runtimeTemplate.basicFunction("chunkId", [
// map is shorter than forEach
`Object.keys(${runtimeHandlers}).map(${runtimeTemplate.basicFunction(
"key",
`${runtimeHandlers}[key](chunkId);`
)});`
])}`
]);
}
}
module.exports = ChunkPrefetchFunctionRuntimeModule;

View File

@ -0,0 +1,97 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const ChunkPrefetchFunctionRuntimeModule = require("./ChunkPrefetchFunctionRuntimeModule");
const ChunkPrefetchStartupRuntimeModule = require("./ChunkPrefetchStartupRuntimeModule");
const ChunkPrefetchTriggerRuntimeModule = require("./ChunkPrefetchTriggerRuntimeModule");
const ChunkPreloadTriggerRuntimeModule = require("./ChunkPreloadTriggerRuntimeModule");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
/** @typedef {import("../Compiler")} Compiler */
const PLUGIN_NAME = "ChunkPrefetchPreloadPlugin";
class ChunkPrefetchPreloadPlugin {
/**
* @param {Compiler} compiler the compiler
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(PLUGIN_NAME, compilation => {
compilation.hooks.additionalChunkRuntimeRequirements.tap(
PLUGIN_NAME,
(chunk, set, { chunkGraph }) => {
if (chunkGraph.getNumberOfEntryModules(chunk) === 0) return;
const startupChildChunks = chunk.getChildrenOfTypeInOrder(
chunkGraph,
"prefetchOrder"
);
if (startupChildChunks) {
set.add(RuntimeGlobals.prefetchChunk);
set.add(RuntimeGlobals.onChunksLoaded);
set.add(RuntimeGlobals.exports);
compilation.addRuntimeModule(
chunk,
new ChunkPrefetchStartupRuntimeModule(startupChildChunks)
);
}
}
);
compilation.hooks.additionalTreeRuntimeRequirements.tap(
PLUGIN_NAME,
(chunk, set, { chunkGraph }) => {
const chunkMap = chunk.getChildIdsByOrdersMap(chunkGraph);
if (chunkMap.prefetch) {
set.add(RuntimeGlobals.prefetchChunk);
compilation.addRuntimeModule(
chunk,
new ChunkPrefetchTriggerRuntimeModule(chunkMap.prefetch)
);
}
if (chunkMap.preload) {
set.add(RuntimeGlobals.preloadChunk);
compilation.addRuntimeModule(
chunk,
new ChunkPreloadTriggerRuntimeModule(chunkMap.preload)
);
}
}
);
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.prefetchChunk)
.tap(PLUGIN_NAME, (chunk, set) => {
compilation.addRuntimeModule(
chunk,
new ChunkPrefetchFunctionRuntimeModule(
"prefetch",
RuntimeGlobals.prefetchChunk,
RuntimeGlobals.prefetchChunkHandlers
)
);
set.add(RuntimeGlobals.prefetchChunkHandlers);
});
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.preloadChunk)
.tap(PLUGIN_NAME, (chunk, set) => {
compilation.addRuntimeModule(
chunk,
new ChunkPrefetchFunctionRuntimeModule(
"preload",
RuntimeGlobals.preloadChunk,
RuntimeGlobals.preloadChunkHandlers
)
);
set.add(RuntimeGlobals.preloadChunkHandlers);
});
});
}
}
module.exports = ChunkPrefetchPreloadPlugin;

View File

@ -0,0 +1,55 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Chunk")} Chunk */
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
class ChunkPrefetchStartupRuntimeModule extends RuntimeModule {
/**
* @param {{ onChunks: Chunk[], chunks: Set<Chunk> }[]} startupChunks chunk ids to trigger when chunks are loaded
*/
constructor(startupChunks) {
super("startup prefetch", RuntimeModule.STAGE_TRIGGER);
this.startupChunks = startupChunks;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const { startupChunks } = this;
const compilation = /** @type {Compilation} */ (this.compilation);
const chunk = /** @type {Chunk} */ (this.chunk);
const { runtimeTemplate } = compilation;
return Template.asString(
startupChunks.map(
({ onChunks, chunks }) =>
`${RuntimeGlobals.onChunksLoaded}(0, ${JSON.stringify(
// This need to include itself to delay execution after this chunk has been fully loaded
onChunks.filter(c => c === chunk).map(c => c.id)
)}, ${runtimeTemplate.basicFunction(
"",
chunks.size < 3
? Array.from(
chunks,
c =>
`${RuntimeGlobals.prefetchChunk}(${JSON.stringify(c.id)});`
)
: `${JSON.stringify(Array.from(chunks, c => c.id))}.map(${
RuntimeGlobals.prefetchChunk
});`
)}, 5);`
)
);
}
}
module.exports = ChunkPrefetchStartupRuntimeModule;

View File

@ -0,0 +1,51 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
class ChunkPrefetchTriggerRuntimeModule extends RuntimeModule {
/**
* @param {Record<string|number, (string|number)[]>} chunkMap map from chunk to
*/
constructor(chunkMap) {
super("chunk prefetch trigger", RuntimeModule.STAGE_TRIGGER);
this.chunkMap = chunkMap;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const { chunkMap } = this;
const compilation = /** @type {Compilation} */ (this.compilation);
const { runtimeTemplate } = compilation;
const body = [
"var chunks = chunkToChildrenMap[chunkId];",
`Array.isArray(chunks) && chunks.map(${RuntimeGlobals.prefetchChunk});`
];
return Template.asString([
Template.asString([
`var chunkToChildrenMap = ${JSON.stringify(chunkMap, null, "\t")};`,
`${
RuntimeGlobals.ensureChunkHandlers
}.prefetch = ${runtimeTemplate.expressionFunction(
`Promise.all(promises).then(${runtimeTemplate.basicFunction(
"",
body
)})`,
"chunkId, promises"
)};`
])
]);
}
}
module.exports = ChunkPrefetchTriggerRuntimeModule;

View File

@ -0,0 +1,45 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../RuntimeTemplate")} RuntimeTemplate */
class ChunkPreloadTriggerRuntimeModule extends RuntimeModule {
/**
* @param {Record<string|number, (string|number)[]>} chunkMap map from chunk to chunks
*/
constructor(chunkMap) {
super("chunk preload trigger", RuntimeModule.STAGE_TRIGGER);
this.chunkMap = chunkMap;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const { chunkMap } = this;
const compilation = /** @type {Compilation} */ (this.compilation);
const { runtimeTemplate } = compilation;
const body = [
"var chunks = chunkToChildrenMap[chunkId];",
`Array.isArray(chunks) && chunks.map(${RuntimeGlobals.preloadChunk});`
];
return Template.asString([
Template.asString([
`var chunkToChildrenMap = ${JSON.stringify(chunkMap, null, "\t")};`,
`${
RuntimeGlobals.ensureChunkHandlers
}.preload = ${runtimeTemplate.basicFunction("chunkId", body)};`
])
]);
}
}
module.exports = ChunkPreloadTriggerRuntimeModule;