@codelet/inject-chunk-webpack-plugin
Version:
webpack plugin inject chunk
103 lines (102 loc) • 4.79 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const webpack_1 = require("webpack");
const NAME = 'InjectChunkWebpackPlugin';
class InjectChunkWebpackPlugin {
apply(compiler) {
compiler.hooks.thisCompilation.tap(NAME, (compilation) => {
// asset 处理
compilation.hooks.processAssets.tap({
name: NAME,
stage: webpack_1.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS,
}, () => {
const { globalObject, chunkLoadingGlobal } = compilation.outputOptions;
const chunkLoadingGlobalStr = JSON.stringify(chunkLoadingGlobal);
const processedChunk = new Set();
function getTargetFile(file) {
const queryStringIdx = file.indexOf('?');
if (queryStringIdx >= 0) {
file = file.substr(0, queryStringIdx);
}
return file;
}
function toPosix(path) {
return path.replace(/\\/g, '/');
}
function getChunkFile(chunk) {
return Array.from(chunk.files).find((item) => ['.js'].includes(path_1.default.extname(item)));
}
function processChunk(chunk, isRuntime, relativeChunks) {
const chunkFile = getChunkFile(chunk);
if (!chunkFile || processedChunk.has(chunk)) {
return;
}
const originalSource = compilation.assets[chunkFile];
const source = new webpack_1.sources.ConcatSource();
source.add(`\nvar ${globalObject} = {};\n`);
relativeChunks.forEach((relativeChunk, index) => {
const relativeChunkFile = relativeChunk.files.values().next().value;
if (!relativeChunkFile)
return;
const chunkPath = getTargetFile(chunkFile);
let relativePath = getTargetFile(relativeChunkFile);
relativePath = path_1.default.relative(path_1.default.dirname(chunkPath), relativePath);
relativePath = toPosix(relativePath);
if (index === 0) {
source.add(`${globalObject}[${chunkLoadingGlobalStr}] = require("${relativePath}");\n`);
}
else {
source.add(`require("${relativePath}");\n`);
}
});
if (isRuntime) {
source.add(originalSource);
source.add(`\nmodule.exports = ${globalObject}[${chunkLoadingGlobalStr}];\n`);
}
else {
source.add(originalSource);
}
compilation.assets[chunkFile] = source;
processedChunk.add(chunk);
}
compilation.chunkGroups.forEach((chunkGroup) => {
if (!chunkGroup.isInitial()) {
return;
}
let runtimeChunk;
let entryChunk;
const middleChunks = [];
const chunksLength = chunkGroup.chunks.length;
chunkGroup.chunks.forEach((chunk, index) => {
if (index === 0) {
runtimeChunk = chunk;
}
else if (index === chunksLength - 1) {
entryChunk = chunk;
}
else {
middleChunks.push(chunk);
}
});
if (runtimeChunk) {
processChunk(runtimeChunk, true, []);
if (middleChunks.length) {
middleChunks.forEach((middleChunk) => {
processChunk(middleChunk, false, [runtimeChunk]);
});
}
if (entryChunk) {
middleChunks.unshift(runtimeChunk);
processChunk(entryChunk, false, middleChunks);
}
}
});
});
});
}
}
exports.default = InjectChunkWebpackPlugin;