WXL
5 天以前 871522ed7e06fd9c62a87c178d7f5c88d7853a20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
    MIT License http://www.opensource.org/licenses/mit-license.php
    Author Tobias Koppers @sokra
*/
 
"use strict";
 
const { ConcatSource, PrefixSource, RawSource } = require("webpack-sources");
const { RuntimeGlobals } = require("..");
const HotUpdateChunk = require("../HotUpdateChunk");
const Template = require("../Template");
const { getCompilationHooks } = require("./JavascriptModulesPlugin");
const {
    generateEntryStartup,
    updateHashForEntryStartup
} = require("./StartupHelpers");
 
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../ChunkGraph").EntryModuleWithChunkGroup} EntryModuleWithChunkGroup */
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
 
const PLUGIN_NAME = "ArrayPushCallbackChunkFormatPlugin";
 
class ArrayPushCallbackChunkFormatPlugin {
    /**
     * Apply the plugin
     * @param {Compiler} compiler the compiler instance
     * @returns {void}
     */
    apply(compiler) {
        compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
            compilation.hooks.additionalChunkRuntimeRequirements.tap(
                PLUGIN_NAME,
                (chunk, set, { chunkGraph }) => {
                    if (chunk.hasRuntime()) return;
                    if (chunkGraph.getNumberOfEntryModules(chunk) > 0) {
                        set.add(RuntimeGlobals.onChunksLoaded);
                        set.add(RuntimeGlobals.exports);
                        set.add(RuntimeGlobals.require);
                    }
                    set.add(RuntimeGlobals.chunkCallback);
                }
            );
            const hooks = getCompilationHooks(compilation);
            hooks.renderChunk.tap(PLUGIN_NAME, (modules, renderContext) => {
                const { chunk, chunkGraph, runtimeTemplate } = renderContext;
                const hotUpdateChunk = chunk instanceof HotUpdateChunk ? chunk : null;
                const globalObject = runtimeTemplate.globalObject;
                const source = new ConcatSource();
                const runtimeModules = chunkGraph.getChunkRuntimeModulesInOrder(chunk);
                if (hotUpdateChunk) {
                    const hotUpdateGlobal = runtimeTemplate.outputOptions.hotUpdateGlobal;
                    source.add(`${globalObject}[${JSON.stringify(hotUpdateGlobal)}](`);
                    source.add(`${JSON.stringify(chunk.id)},`);
                    source.add(modules);
                    if (runtimeModules.length > 0) {
                        source.add(",\n");
                        const runtimePart = Template.renderChunkRuntimeModules(
                            runtimeModules,
                            renderContext
                        );
                        source.add(runtimePart);
                    }
                    source.add(")");
                } else {
                    const chunkLoadingGlobal =
                        runtimeTemplate.outputOptions.chunkLoadingGlobal;
                    source.add(
                        `(${globalObject}[${JSON.stringify(
                            chunkLoadingGlobal
                        )}] = ${globalObject}[${JSON.stringify(
                            chunkLoadingGlobal
                        )}] || []).push([`
                    );
                    source.add(`${JSON.stringify(chunk.ids)},`);
                    source.add(modules);
                    /** @type {EntryModuleWithChunkGroup[]} */
                    const entries = [
                        ...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
                    ];
                    if (runtimeModules.length > 0 || entries.length > 0) {
                        const runtime = new ConcatSource(
                            `${
                                runtimeTemplate.supportsArrowFunction()
                                    ? `${RuntimeGlobals.require} =>`
                                    : `function(${RuntimeGlobals.require})`
                            } { // webpackRuntimeModules\n`
                        );
                        if (runtimeModules.length > 0) {
                            runtime.add(
                                Template.renderRuntimeModules(runtimeModules, {
                                    ...renderContext,
                                    codeGenerationResults:
                                        /** @type {CodeGenerationResults} */
                                        (compilation.codeGenerationResults)
                                })
                            );
                        }
                        if (entries.length > 0) {
                            const startupSource = new RawSource(
                                generateEntryStartup(
                                    chunkGraph,
                                    runtimeTemplate,
                                    entries,
                                    chunk,
                                    true
                                )
                            );
                            runtime.add(
                                hooks.renderStartup.call(
                                    startupSource,
                                    entries[entries.length - 1][0],
                                    {
                                        ...renderContext,
                                        inlined: false
                                    }
                                )
                            );
                            if (
                                chunkGraph
                                    .getChunkRuntimeRequirements(chunk)
                                    .has(RuntimeGlobals.returnExportsFromRuntime)
                            ) {
                                runtime.add(`return ${RuntimeGlobals.exports};\n`);
                            }
                        }
                        runtime.add("}\n");
                        source.add(",\n");
                        source.add(new PrefixSource("/******/ ", runtime));
                    }
                    source.add("])");
                }
                return source;
            });
            hooks.chunkHash.tap(
                PLUGIN_NAME,
                (chunk, hash, { chunkGraph, runtimeTemplate }) => {
                    if (chunk.hasRuntime()) return;
                    hash.update(
                        `${PLUGIN_NAME}1${runtimeTemplate.outputOptions.chunkLoadingGlobal}${runtimeTemplate.outputOptions.hotUpdateGlobal}${runtimeTemplate.globalObject}`
                    );
                    /** @type {EntryModuleWithChunkGroup[]} */
                    const entries = [
                        ...chunkGraph.getChunkEntryModulesWithChunkGroupIterable(chunk)
                    ];
                    updateHashForEntryStartup(hash, chunkGraph, entries, chunk);
                }
            );
        });
    }
}
 
module.exports = ArrayPushCallbackChunkFormatPlugin;