Initial boiler plate project
This commit is contained in:
267
node_modules/next/dist/esm/build/webpack/plugins/css-chunking-plugin.js
generated
vendored
Normal file
267
node_modules/next/dist/esm/build/webpack/plugins/css-chunking-plugin.js
generated
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
const PLUGIN_NAME = "CssChunkingPlugin";
|
||||
/**
|
||||
* Merge chunks until they are bigger than the target size.
|
||||
*/ const MIN_CSS_CHUNK_SIZE = 30 * 1024;
|
||||
/**
|
||||
* Avoid merging chunks when they would be bigger than this size.
|
||||
*/ const MAX_CSS_CHUNK_SIZE = 100 * 1024;
|
||||
function isGlobalCss(module) {
|
||||
return !/\.module\.(css|scss|sass)$/.test(module.nameForCondition() || "");
|
||||
}
|
||||
export class CssChunkingPlugin {
|
||||
constructor(strict){
|
||||
this.strict = strict;
|
||||
}
|
||||
apply(compiler) {
|
||||
const strict = this.strict;
|
||||
const summary = !!process.env.CSS_CHUNKING_SUMMARY;
|
||||
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation)=>{
|
||||
let once = false;
|
||||
compilation.hooks.optimizeChunks.tap({
|
||||
name: PLUGIN_NAME,
|
||||
stage: 5
|
||||
}, ()=>{
|
||||
if (once) {
|
||||
return;
|
||||
}
|
||||
once = true;
|
||||
const chunkGraph = compilation.chunkGraph;
|
||||
let changed = undefined;
|
||||
const chunkStates = new Map();
|
||||
const chunkStatesByModule = new Map();
|
||||
// Collect all css modules in chunks and the execpted order of them
|
||||
for (const chunk of compilation.chunks){
|
||||
var _chunk_name;
|
||||
if ((_chunk_name = chunk.name) == null ? void 0 : _chunk_name.startsWith("pages/")) continue;
|
||||
const modules = [];
|
||||
for (const module of chunkGraph.getChunkModulesIterable(chunk)){
|
||||
var _module_type;
|
||||
if (!((_module_type = module.type) == null ? void 0 : _module_type.startsWith("css"))) continue;
|
||||
modules.push(module);
|
||||
}
|
||||
if (!modules.length) continue;
|
||||
const chunkState = {
|
||||
chunk,
|
||||
modules,
|
||||
order: 0,
|
||||
requests: modules.length
|
||||
};
|
||||
chunkStates.set(chunk, chunkState);
|
||||
for(let i = 0; i < modules.length; i++){
|
||||
const module = modules[i];
|
||||
let moduleChunkStates = chunkStatesByModule.get(module);
|
||||
if (!moduleChunkStates) {
|
||||
moduleChunkStates = new Map();
|
||||
chunkStatesByModule.set(module, moduleChunkStates);
|
||||
}
|
||||
moduleChunkStates.set(chunkState, i);
|
||||
chunkStatesByModule.set(module, moduleChunkStates);
|
||||
}
|
||||
}
|
||||
// Sort modules by their index sum
|
||||
const orderedModules = [];
|
||||
for (const [module, moduleChunkStates] of chunkStatesByModule){
|
||||
let sum = 0;
|
||||
for (const i of moduleChunkStates.values()){
|
||||
sum += i;
|
||||
}
|
||||
orderedModules.push({
|
||||
module,
|
||||
sum
|
||||
});
|
||||
}
|
||||
orderedModules.sort((a, b)=>a.sum - b.sum);
|
||||
// A queue of modules that still need to be processed
|
||||
const remainingModules = new Set(orderedModules.map(({ module })=>module));
|
||||
// In loose mode we guess the dependents of modules from the order
|
||||
// assuming that when a module is a dependency of another module
|
||||
// it will always appear before it in every chunk.
|
||||
const allDependents = new Map();
|
||||
if (!this.strict) {
|
||||
for (const b of remainingModules){
|
||||
const dependent = new Set();
|
||||
loop: for (const a of remainingModules){
|
||||
if (a === b) continue;
|
||||
// check if a depends on b
|
||||
for (const [chunkState, ia] of chunkStatesByModule.get(a)){
|
||||
const bChunkStates = chunkStatesByModule.get(b);
|
||||
const ib = bChunkStates.get(chunkState);
|
||||
if (ib === undefined) {
|
||||
continue loop;
|
||||
}
|
||||
if (ib > ia) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
dependent.add(a);
|
||||
}
|
||||
if (dependent.size > 0) allDependents.set(b, dependent);
|
||||
}
|
||||
}
|
||||
// Stores the new chunk for every module
|
||||
const newChunksByModule = new Map();
|
||||
// Process through all modules
|
||||
for (const startModule of remainingModules){
|
||||
let globalCssMode = isGlobalCss(startModule);
|
||||
// The current position of processing in all selected chunks
|
||||
let allChunkStates = new Map(chunkStatesByModule.get(startModule));
|
||||
// The list of modules that goes into the new chunk
|
||||
const newChunkModules = new Set([
|
||||
startModule
|
||||
]);
|
||||
// The current size of the new chunk
|
||||
let currentSize = startModule.size();
|
||||
// A pool of potential modules where the next module is selected from.
|
||||
// It's filled from the next module of the selected modules in every chunk.
|
||||
// It also keeps some metadata to improve performance [size, chunkStates].
|
||||
const potentialNextModules = new Map();
|
||||
for (const [chunkState, i] of allChunkStates){
|
||||
const nextModule = chunkState.modules[i + 1];
|
||||
if (nextModule && remainingModules.has(nextModule)) {
|
||||
potentialNextModules.set(nextModule, [
|
||||
nextModule.size(),
|
||||
chunkStatesByModule.get(nextModule)
|
||||
]);
|
||||
}
|
||||
}
|
||||
// Try to add modules to the chunk until a break condition is met
|
||||
let cont;
|
||||
do {
|
||||
cont = false;
|
||||
// We try to select a module that reduces request count and
|
||||
// has the highest number of requests
|
||||
const orderedPotentialNextModules = [];
|
||||
for (const [nextModule, [size, nextChunkStates]] of potentialNextModules){
|
||||
let maxRequests = 0;
|
||||
for (const chunkState of nextChunkStates.keys()){
|
||||
// There is always some overlap
|
||||
if (allChunkStates.has(chunkState)) {
|
||||
maxRequests = Math.max(maxRequests, chunkState.requests);
|
||||
}
|
||||
}
|
||||
orderedPotentialNextModules.push([
|
||||
nextModule,
|
||||
size,
|
||||
nextChunkStates,
|
||||
maxRequests
|
||||
]);
|
||||
}
|
||||
orderedPotentialNextModules.sort((a, b)=>b[3] - a[3] || (a[0].identifier() < b[0].identifier() ? -1 : 1));
|
||||
// Try every potential module
|
||||
loop: for (const [nextModule, size, nextChunkStates] of orderedPotentialNextModules){
|
||||
if (currentSize + size > MAX_CSS_CHUNK_SIZE) {
|
||||
continue;
|
||||
}
|
||||
if (!strict) {
|
||||
// In loose mode we only check if the dependencies are not violated
|
||||
const dependent = allDependents.get(nextModule);
|
||||
if (dependent) {
|
||||
for (const dep of dependent){
|
||||
if (newChunkModules.has(dep)) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// In strict mode we check that none of the order in any chunk is changed by adding the module
|
||||
for (const [chunkState, i] of nextChunkStates){
|
||||
const prevState = allChunkStates.get(chunkState);
|
||||
if (prevState === undefined) {
|
||||
// New chunk group, can add it, but should we?
|
||||
// We only add that if below min size
|
||||
if (currentSize < MIN_CSS_CHUNK_SIZE) {
|
||||
continue;
|
||||
} else {
|
||||
continue loop;
|
||||
}
|
||||
} else if (prevState + 1 === i) {
|
||||
continue;
|
||||
} else {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Global CSS must not leak into unrelated chunks
|
||||
const nextIsGlobalCss = isGlobalCss(nextModule);
|
||||
if (nextIsGlobalCss && globalCssMode) {
|
||||
if (allChunkStates.size !== nextChunkStates.size) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (globalCssMode) {
|
||||
for (const chunkState of nextChunkStates.keys()){
|
||||
if (!allChunkStates.has(chunkState)) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nextIsGlobalCss) {
|
||||
for (const chunkState of allChunkStates.keys()){
|
||||
if (!nextChunkStates.has(chunkState)) {
|
||||
continue loop;
|
||||
}
|
||||
}
|
||||
}
|
||||
potentialNextModules.delete(nextModule);
|
||||
currentSize += size;
|
||||
if (nextIsGlobalCss) {
|
||||
globalCssMode = true;
|
||||
}
|
||||
for (const [chunkState, i] of nextChunkStates){
|
||||
if (allChunkStates.has(chunkState)) {
|
||||
// This reduces the request count of the chunk group
|
||||
chunkState.requests--;
|
||||
}
|
||||
allChunkStates.set(chunkState, i);
|
||||
const newNextModule = chunkState.modules[i + 1];
|
||||
if (newNextModule && remainingModules.has(newNextModule) && !newChunkModules.has(newNextModule)) {
|
||||
potentialNextModules.set(newNextModule, [
|
||||
newNextModule.size(),
|
||||
chunkStatesByModule.get(newNextModule)
|
||||
]);
|
||||
}
|
||||
}
|
||||
newChunkModules.add(nextModule);
|
||||
cont = true;
|
||||
break;
|
||||
}
|
||||
}while (cont);
|
||||
const newChunk = compilation.addChunk();
|
||||
newChunk.preventIntegration = true;
|
||||
newChunk.idNameHints.add("css");
|
||||
for (const module of newChunkModules){
|
||||
remainingModules.delete(module);
|
||||
chunkGraph.connectChunkAndModule(newChunk, module);
|
||||
newChunksByModule.set(module, newChunk);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
for (const { chunk, modules } of chunkStates.values()){
|
||||
const chunks = new Set();
|
||||
for (const module of modules){
|
||||
const newChunk = newChunksByModule.get(module);
|
||||
if (newChunk) {
|
||||
chunkGraph.disconnectChunkAndModule(chunk, module);
|
||||
if (chunks.has(newChunk)) continue;
|
||||
chunks.add(newChunk);
|
||||
chunk.split(newChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (summary) {
|
||||
console.log("Top 20 chunks by request count:");
|
||||
const orderedChunkStates = [
|
||||
...chunkStates.values()
|
||||
];
|
||||
orderedChunkStates.sort((a, b)=>b.requests - a.requests);
|
||||
for (const { chunk, modules, requests } of orderedChunkStates.slice(0, 20)){
|
||||
console.log(`- ${requests} requests for ${chunk.name} (has ${modules.length} modules)`);
|
||||
}
|
||||
}
|
||||
return changed;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
//# sourceMappingURL=css-chunking-plugin.js.map
|
||||
Reference in New Issue
Block a user