1 |
|
2 |
|
3 |
|
4 |
|
5 | "use strict";
|
6 |
|
7 | const Queue = require("./util/Queue");
|
8 |
|
9 | const addToSet = (a, b) => {
|
10 | let changed = false;
|
11 | for (const item of b) {
|
12 | if (!a.has(item)) {
|
13 | a.add(item);
|
14 | changed = true;
|
15 | }
|
16 | }
|
17 | return changed;
|
18 | };
|
19 |
|
20 | class FlagDependencyExportsPlugin {
|
21 | apply(compiler) {
|
22 | compiler.hooks.compilation.tap(
|
23 | "FlagDependencyExportsPlugin",
|
24 | compilation => {
|
25 | compilation.hooks.finishModules.tap(
|
26 | "FlagDependencyExportsPlugin",
|
27 | modules => {
|
28 | const dependencies = new Map();
|
29 |
|
30 | const queue = new Queue();
|
31 |
|
32 | let module;
|
33 | let moduleWithExports;
|
34 | let moduleProvidedExports;
|
35 | let providedExportsAreTemporary;
|
36 |
|
37 | const processDependenciesBlock = depBlock => {
|
38 | for (const dep of depBlock.dependencies) {
|
39 | if (processDependency(dep)) return true;
|
40 | }
|
41 | for (const variable of depBlock.variables) {
|
42 | for (const dep of variable.dependencies) {
|
43 | if (processDependency(dep)) return true;
|
44 | }
|
45 | }
|
46 | for (const block of depBlock.blocks) {
|
47 | if (processDependenciesBlock(block)) return true;
|
48 | }
|
49 | return false;
|
50 | };
|
51 |
|
52 | const processDependency = dep => {
|
53 | const exportDesc = dep.getExports && dep.getExports();
|
54 | if (!exportDesc) return;
|
55 | moduleWithExports = true;
|
56 | const exports = exportDesc.exports;
|
57 |
|
58 | if (module.buildMeta.providedExports === true) {
|
59 | return true;
|
60 | }
|
61 |
|
62 | if (exports === true) {
|
63 | module.buildMeta.providedExports = true;
|
64 | notifyDependencies();
|
65 | return true;
|
66 | }
|
67 |
|
68 | if (Array.isArray(exports)) {
|
69 | if (addToSet(moduleProvidedExports, exports)) {
|
70 | notifyDependencies();
|
71 | }
|
72 | }
|
73 |
|
74 | const exportDeps = exportDesc.dependencies;
|
75 | if (exportDeps) {
|
76 | providedExportsAreTemporary = true;
|
77 | for (const exportDependency of exportDeps) {
|
78 |
|
79 | const set = dependencies.get(exportDependency);
|
80 | if (set === undefined) {
|
81 | dependencies.set(exportDependency, new Set([module]));
|
82 | } else {
|
83 | set.add(module);
|
84 | }
|
85 | }
|
86 | }
|
87 | return false;
|
88 | };
|
89 |
|
90 | const notifyDependencies = () => {
|
91 | const deps = dependencies.get(module);
|
92 | if (deps !== undefined) {
|
93 | for (const dep of deps) {
|
94 | queue.enqueue(dep);
|
95 | }
|
96 | }
|
97 | };
|
98 |
|
99 |
|
100 | for (const module of modules) {
|
101 | if (module.buildInfo.temporaryProvidedExports) {
|
102 |
|
103 |
|
104 | module.buildMeta.providedExports = null;
|
105 | queue.enqueue(module);
|
106 | } else if (!module.buildMeta.providedExports) {
|
107 | queue.enqueue(module);
|
108 | }
|
109 | }
|
110 |
|
111 | while (queue.length > 0) {
|
112 | module = queue.dequeue();
|
113 |
|
114 | if (module.buildMeta.providedExports !== true) {
|
115 | moduleWithExports =
|
116 | module.buildMeta && module.buildMeta.exportsType;
|
117 | moduleProvidedExports = Array.isArray(
|
118 | module.buildMeta.providedExports
|
119 | )
|
120 | ? new Set(module.buildMeta.providedExports)
|
121 | : new Set();
|
122 | providedExportsAreTemporary = false;
|
123 | processDependenciesBlock(module);
|
124 | module.buildInfo.temporaryProvidedExports = providedExportsAreTemporary;
|
125 | if (!moduleWithExports) {
|
126 | module.buildMeta.providedExports = true;
|
127 | notifyDependencies();
|
128 | } else if (module.buildMeta.providedExports !== true) {
|
129 | module.buildMeta.providedExports = Array.from(
|
130 | moduleProvidedExports
|
131 | );
|
132 | }
|
133 | }
|
134 | }
|
135 | }
|
136 | );
|
137 | const providedExportsCache = new WeakMap();
|
138 | compilation.hooks.rebuildModule.tap(
|
139 | "FlagDependencyExportsPlugin",
|
140 | module => {
|
141 | providedExportsCache.set(module, module.buildMeta.providedExports);
|
142 | }
|
143 | );
|
144 | compilation.hooks.finishRebuildingModule.tap(
|
145 | "FlagDependencyExportsPlugin",
|
146 | module => {
|
147 | module.buildMeta.providedExports = providedExportsCache.get(module);
|
148 | }
|
149 | );
|
150 | }
|
151 | );
|
152 | }
|
153 | }
|
154 |
|
155 | module.exports = FlagDependencyExportsPlugin;
|