@tarojs/webpack5-runner 3.5.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/dependencies/TaroSingleEntryDependency.js +18 -0
- package/dist/dependencies/TaroSingleEntryDependency.js.map +1 -0
- package/dist/index.h5.js +224 -0
- package/dist/index.h5.js.map +1 -0
- package/dist/index.mini.js +69 -0
- package/dist/index.mini.js.map +1 -0
- package/dist/loaders/miniTemplateLoader.js +63 -0
- package/dist/loaders/miniTemplateLoader.js.map +1 -0
- package/dist/plugins/BuildNativePlugin.js +124 -0
- package/dist/plugins/BuildNativePlugin.js.map +1 -0
- package/dist/plugins/H5Plugin.js +91 -0
- package/dist/plugins/H5Plugin.js.map +1 -0
- package/dist/plugins/MiniPlugin.js +1027 -0
- package/dist/plugins/MiniPlugin.js.map +1 -0
- package/dist/plugins/MiniSplitChunksPlugin.js +678 -0
- package/dist/plugins/MiniSplitChunksPlugin.js.map +1 -0
- package/dist/plugins/TaroLoadChunksPlugin.js +176 -0
- package/dist/plugins/TaroLoadChunksPlugin.js.map +1 -0
- package/dist/plugins/TaroNormalModule.js +51 -0
- package/dist/plugins/TaroNormalModule.js.map +1 -0
- package/dist/plugins/TaroNormalModulesPlugin.js +63 -0
- package/dist/plugins/TaroNormalModulesPlugin.js.map +1 -0
- package/dist/plugins/TaroSingleEntryPlugin.js +26 -0
- package/dist/plugins/TaroSingleEntryPlugin.js.map +1 -0
- package/dist/plugins/WebpackBarPlugin.js +26 -0
- package/dist/plugins/WebpackBarPlugin.js.map +1 -0
- package/dist/postcss/postcss.h5.js +70 -0
- package/dist/postcss/postcss.h5.js.map +1 -0
- package/dist/postcss/postcss.mini.js +75 -0
- package/dist/postcss/postcss.mini.js.map +1 -0
- package/dist/prebundle/bundle.js +167 -0
- package/dist/prebundle/bundle.js.map +1 -0
- package/dist/prebundle/constant.js +60 -0
- package/dist/prebundle/constant.js.map +1 -0
- package/dist/prebundle/index.js +234 -0
- package/dist/prebundle/index.js.map +1 -0
- package/dist/prebundle/scanImports.js +193 -0
- package/dist/prebundle/scanImports.js.map +1 -0
- package/dist/prebundle/utils.js +170 -0
- package/dist/prebundle/utils.js.map +1 -0
- package/dist/prebundle/webpack/TaroContainerEntryModule.js +76 -0
- package/dist/prebundle/webpack/TaroContainerEntryModule.js.map +1 -0
- package/dist/prebundle/webpack/TaroContainerPlugin.js +75 -0
- package/dist/prebundle/webpack/TaroContainerPlugin.js.map +1 -0
- package/dist/prebundle/webpack/TaroContainerReferencePlugin.js +124 -0
- package/dist/prebundle/webpack/TaroContainerReferencePlugin.js.map +1 -0
- package/dist/prebundle/webpack/index.js +1 -0
- package/dist/prebundle/webpack/index.js.map +1 -0
- package/dist/prerender/prerender.js +228 -0
- package/dist/prerender/prerender.js.map +1 -0
- package/dist/template/comp.js +4 -0
- package/dist/template/component.js +10 -0
- package/dist/template/component.js.map +1 -0
- package/dist/template/custom-wrapper.js +7 -0
- package/dist/template/custom-wrapper.js.map +1 -0
- package/dist/utils/H5AppInstance.js +110 -0
- package/dist/utils/H5AppInstance.js.map +1 -0
- package/dist/utils/index.js +53 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/logHelper.js +153 -0
- package/dist/utils/logHelper.js.map +1 -0
- package/dist/utils/types.js +3 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/webpack.js +12 -0
- package/dist/utils/webpack.js.map +1 -0
- package/dist/webpack/BaseConfig.js +155 -0
- package/dist/webpack/BaseConfig.js.map +1 -0
- package/dist/webpack/BuildNativePlugin.js +57 -0
- package/dist/webpack/BuildNativePlugin.js.map +1 -0
- package/dist/webpack/Combination.js +69 -0
- package/dist/webpack/Combination.js.map +1 -0
- package/dist/webpack/H5BaseConfig.js +30 -0
- package/dist/webpack/H5BaseConfig.js.map +1 -0
- package/dist/webpack/H5Combination.js +106 -0
- package/dist/webpack/H5Combination.js.map +1 -0
- package/dist/webpack/H5WebpackModule.js +261 -0
- package/dist/webpack/H5WebpackModule.js.map +1 -0
- package/dist/webpack/H5WebpackPlugin.js +85 -0
- package/dist/webpack/H5WebpackPlugin.js.map +1 -0
- package/dist/webpack/MiniBaseConfig.js +73 -0
- package/dist/webpack/MiniBaseConfig.js.map +1 -0
- package/dist/webpack/MiniCombination.js +115 -0
- package/dist/webpack/MiniCombination.js.map +1 -0
- package/dist/webpack/MiniWebpackModule.js +204 -0
- package/dist/webpack/MiniWebpackModule.js.map +1 -0
- package/dist/webpack/MiniWebpackPlugin.js +154 -0
- package/dist/webpack/MiniWebpackPlugin.js.map +1 -0
- package/dist/webpack/WebpackModule.js +174 -0
- package/dist/webpack/WebpackModule.js.map +1 -0
- package/dist/webpack/WebpackPlugin.js +84 -0
- package/dist/webpack/WebpackPlugin.js.map +1 -0
- package/index.js +7 -0
- package/package.json +103 -0
|
@@ -0,0 +1,678 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const path = require("path");
|
|
13
|
+
const md5 = require("md5");
|
|
14
|
+
const SplitChunksPlugin = require("webpack/lib/optimize/SplitChunksPlugin");
|
|
15
|
+
const webpack_sources_1 = require("webpack-sources");
|
|
16
|
+
const helper_1 = require("@tarojs/helper");
|
|
17
|
+
const shared_1 = require("@tarojs/shared");
|
|
18
|
+
const PLUGIN_NAME = 'MiniSplitChunkPlugin'; // 插件名
|
|
19
|
+
const SUB_COMMON_DIR = 'sub-common'; // 分包公共依赖目录
|
|
20
|
+
const SUB_VENDORS_NAME = 'sub-vendors'; // 分包 vendors 文件名
|
|
21
|
+
const FileExtsMap = {
|
|
22
|
+
JS: '.js',
|
|
23
|
+
JS_MAP: '.js.map',
|
|
24
|
+
STYLE: '.wxss'
|
|
25
|
+
}; // 默认支持的文件扩展名
|
|
26
|
+
const INITIAL_CHUNK_FILTER = chunk => chunk.canBeInitial();
|
|
27
|
+
const ASYNC_CHUNK_FILTER = chunk => !chunk.canBeInitial();
|
|
28
|
+
const ALL_CHUNK_FILTER = _ => true;
|
|
29
|
+
/**
|
|
30
|
+
* @param {OptimizationSplitChunksSizes} value the sizes
|
|
31
|
+
* @param {string[]} defaultSizeTypes the default size types
|
|
32
|
+
* @returns {SplitChunksSizes} normalized representation
|
|
33
|
+
*/
|
|
34
|
+
const normalizeSizes = (value, defaultSizeTypes) => {
|
|
35
|
+
if (typeof value === 'number') {
|
|
36
|
+
/** @type {Record<string, number>} */
|
|
37
|
+
const o = {};
|
|
38
|
+
for (const sizeType of defaultSizeTypes)
|
|
39
|
+
o[sizeType] = value;
|
|
40
|
+
return o;
|
|
41
|
+
}
|
|
42
|
+
else if (typeof value === 'object' && value !== null) {
|
|
43
|
+
return Object.assign({}, value);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
return {};
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* @param {...SplitChunksSizes} sizes the sizes
|
|
51
|
+
* @returns {SplitChunksSizes} the merged sizes
|
|
52
|
+
*/
|
|
53
|
+
const mergeSizes = (...sizes) => {
|
|
54
|
+
/** @type {SplitChunksSizes} */
|
|
55
|
+
let merged = {};
|
|
56
|
+
for (let i = sizes.length - 1; i >= 0; i--) {
|
|
57
|
+
merged = Object.assign(merged, sizes[i]);
|
|
58
|
+
}
|
|
59
|
+
return merged;
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* @param {false|string|Function} name the chunk name
|
|
63
|
+
* @returns {GetName} a function to get the name of the chunk
|
|
64
|
+
*/
|
|
65
|
+
const normalizeName = name => {
|
|
66
|
+
if (typeof name === 'string') {
|
|
67
|
+
return () => name;
|
|
68
|
+
}
|
|
69
|
+
if (typeof name === 'function') {
|
|
70
|
+
return /** @type {GetName} */ (name);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* @param {OptimizationSplitChunksCacheGroup["chunks"]} chunks the chunk filter option
|
|
75
|
+
* @returns {ChunkFilterFunction} the chunk filter function
|
|
76
|
+
*/
|
|
77
|
+
const normalizeChunksFilter = chunks => {
|
|
78
|
+
if (chunks === 'initial') {
|
|
79
|
+
return INITIAL_CHUNK_FILTER;
|
|
80
|
+
}
|
|
81
|
+
if (chunks === 'async') {
|
|
82
|
+
return ASYNC_CHUNK_FILTER;
|
|
83
|
+
}
|
|
84
|
+
if (chunks === 'all') {
|
|
85
|
+
return ALL_CHUNK_FILTER;
|
|
86
|
+
}
|
|
87
|
+
if (typeof chunks === 'function') {
|
|
88
|
+
return chunks;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* @param {undefined|boolean|string|RegExp|Function} test test option
|
|
93
|
+
* @param {Module} module the module
|
|
94
|
+
* @param {CacheGroupsContext} context context object
|
|
95
|
+
* @returns {boolean} true, if the module should be selected
|
|
96
|
+
*/
|
|
97
|
+
const checkTest = (test, module, context) => {
|
|
98
|
+
if (test === undefined)
|
|
99
|
+
return true;
|
|
100
|
+
if (typeof test === 'function') {
|
|
101
|
+
return test(module, context);
|
|
102
|
+
}
|
|
103
|
+
if (typeof test === 'boolean')
|
|
104
|
+
return test;
|
|
105
|
+
if (typeof test === 'string') {
|
|
106
|
+
const name = module.nameForCondition();
|
|
107
|
+
return name && name.startsWith(test);
|
|
108
|
+
}
|
|
109
|
+
if (test instanceof RegExp) {
|
|
110
|
+
const name = module.nameForCondition();
|
|
111
|
+
return name && test.test(name);
|
|
112
|
+
}
|
|
113
|
+
return false;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* @param {undefined|string|RegExp|Function} test type option
|
|
117
|
+
* @param {Module} module the module
|
|
118
|
+
* @returns {boolean} true, if the module should be selected
|
|
119
|
+
*/
|
|
120
|
+
const checkModuleType = (test, module) => {
|
|
121
|
+
if (test === undefined)
|
|
122
|
+
return true;
|
|
123
|
+
if (typeof test === 'function') {
|
|
124
|
+
return test(module.type);
|
|
125
|
+
}
|
|
126
|
+
if (typeof test === 'string') {
|
|
127
|
+
const type = module.type;
|
|
128
|
+
return test === type;
|
|
129
|
+
}
|
|
130
|
+
if (test instanceof RegExp) {
|
|
131
|
+
const type = module.type;
|
|
132
|
+
return test.test(type);
|
|
133
|
+
}
|
|
134
|
+
return false;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* @param {undefined|string|RegExp|Function} test type option
|
|
138
|
+
* @param {Module} module the module
|
|
139
|
+
* @returns {boolean} true, if the module should be selected
|
|
140
|
+
*/
|
|
141
|
+
const checkModuleLayer = (test, module) => {
|
|
142
|
+
if (test === undefined)
|
|
143
|
+
return true;
|
|
144
|
+
if (typeof test === 'function') {
|
|
145
|
+
return test(module.layer);
|
|
146
|
+
}
|
|
147
|
+
if (typeof test === 'string') {
|
|
148
|
+
const layer = module.layer;
|
|
149
|
+
return test === '' ? !layer : layer && layer.startsWith(test);
|
|
150
|
+
}
|
|
151
|
+
if (test instanceof RegExp) {
|
|
152
|
+
const layer = module.layer;
|
|
153
|
+
return test.test(layer);
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
};
|
|
157
|
+
/**
|
|
158
|
+
* @param {OptimizationSplitChunksCacheGroup} options the group options
|
|
159
|
+
* @param {string} key key of cache group
|
|
160
|
+
* @param {string[]} defaultSizeTypes the default size types
|
|
161
|
+
* @returns {CacheGroupSource} the normalized cached group
|
|
162
|
+
*/
|
|
163
|
+
const createCacheGroupSource = (options, key, defaultSizeTypes) => {
|
|
164
|
+
const minSize = normalizeSizes(options.minSize, defaultSizeTypes);
|
|
165
|
+
const minSizeReduction = normalizeSizes(options.minSizeReduction, defaultSizeTypes);
|
|
166
|
+
const maxSize = normalizeSizes(options.maxSize, defaultSizeTypes);
|
|
167
|
+
return {
|
|
168
|
+
key,
|
|
169
|
+
priority: options.priority,
|
|
170
|
+
getName: normalizeName(options.name),
|
|
171
|
+
chunksFilter: normalizeChunksFilter(options.chunks),
|
|
172
|
+
enforce: options.enforce,
|
|
173
|
+
minSize,
|
|
174
|
+
minSizeReduction,
|
|
175
|
+
minRemainingSize: mergeSizes(normalizeSizes(options.minRemainingSize, defaultSizeTypes), minSize),
|
|
176
|
+
enforceSizeThreshold: normalizeSizes(options.enforceSizeThreshold, defaultSizeTypes),
|
|
177
|
+
maxAsyncSize: mergeSizes(normalizeSizes(options.maxAsyncSize, defaultSizeTypes), maxSize),
|
|
178
|
+
maxInitialSize: mergeSizes(normalizeSizes(options.maxInitialSize, defaultSizeTypes), maxSize),
|
|
179
|
+
minChunks: options.minChunks,
|
|
180
|
+
maxAsyncRequests: options.maxAsyncRequests,
|
|
181
|
+
maxInitialRequests: options.maxInitialRequests,
|
|
182
|
+
filename: options.filename,
|
|
183
|
+
idHint: options.idHint,
|
|
184
|
+
automaticNameDelimiter: options.automaticNameDelimiter,
|
|
185
|
+
reuseExistingChunk: options.reuseExistingChunk,
|
|
186
|
+
usedExports: options.usedExports
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
/**
|
|
190
|
+
* @param {GetCacheGroups | Record<string, false|string|RegExp|OptimizationSplitChunksGetCacheGroups|OptimizationSplitChunksCacheGroup>} cacheGroups the cache group options
|
|
191
|
+
* @param {string[]} defaultSizeTypes the default size types
|
|
192
|
+
* @returns {GetCacheGroups} a function to get the cache groups
|
|
193
|
+
*/
|
|
194
|
+
const normalizeCacheGroups = (cacheGroups, defaultSizeTypes) => {
|
|
195
|
+
if (typeof cacheGroups === 'function') {
|
|
196
|
+
return cacheGroups;
|
|
197
|
+
}
|
|
198
|
+
if (typeof cacheGroups === 'object' && cacheGroups !== null) {
|
|
199
|
+
/** @type {(function(Module, CacheGroupsContext, CacheGroupSource[]): void)[]} */
|
|
200
|
+
const handlers = [];
|
|
201
|
+
for (const key of Object.keys(cacheGroups)) {
|
|
202
|
+
const option = cacheGroups[key];
|
|
203
|
+
if (option === false) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
if (typeof option === 'string' || option instanceof RegExp) {
|
|
207
|
+
const source = createCacheGroupSource({}, key, defaultSizeTypes);
|
|
208
|
+
handlers.push((module, context, results) => {
|
|
209
|
+
if (checkTest(option, module, context)) {
|
|
210
|
+
results.push(source);
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
else if (typeof option === 'function') {
|
|
215
|
+
const cache = new WeakMap();
|
|
216
|
+
handlers.push((module, _, results) => {
|
|
217
|
+
const result = option(module);
|
|
218
|
+
if (result) {
|
|
219
|
+
const groups = Array.isArray(result) ? result : [result];
|
|
220
|
+
for (const group of groups) {
|
|
221
|
+
const cachedSource = cache.get(group);
|
|
222
|
+
if (cachedSource !== undefined) {
|
|
223
|
+
results.push(cachedSource);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
const source = createCacheGroupSource(group, key, defaultSizeTypes);
|
|
227
|
+
cache.set(group, source);
|
|
228
|
+
results.push(source);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
const source = createCacheGroupSource(option, key, defaultSizeTypes);
|
|
236
|
+
handlers.push((module, context, results) => {
|
|
237
|
+
if (checkTest(option.test, module, context) &&
|
|
238
|
+
checkModuleType(option.type, module) &&
|
|
239
|
+
checkModuleLayer(option.layer, module)) {
|
|
240
|
+
results.push(source);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* @param {Module} module the current module
|
|
247
|
+
* @param {CacheGroupsContext} context the current context
|
|
248
|
+
* @returns {CacheGroupSource[]} the matching cache groups
|
|
249
|
+
*/
|
|
250
|
+
const fn = (module, context) => {
|
|
251
|
+
/** @type {CacheGroupSource[]} */
|
|
252
|
+
const results = [];
|
|
253
|
+
for (const fn of handlers) {
|
|
254
|
+
fn(module, context, results);
|
|
255
|
+
}
|
|
256
|
+
return results;
|
|
257
|
+
};
|
|
258
|
+
return fn;
|
|
259
|
+
}
|
|
260
|
+
return () => null;
|
|
261
|
+
};
|
|
262
|
+
/**
|
|
263
|
+
* 继承 SplitChunksPlugin 的插件,用于将分包公共依赖提取到单独的文件中
|
|
264
|
+
*/
|
|
265
|
+
class MiniSplitChunksPlugin extends SplitChunksPlugin {
|
|
266
|
+
constructor(options) {
|
|
267
|
+
super();
|
|
268
|
+
/**
|
|
269
|
+
* 自动驱动 tapAsync
|
|
270
|
+
*/
|
|
271
|
+
this.tryAsync = fn => (arg, callback) => __awaiter(this, void 0, void 0, function* () {
|
|
272
|
+
try {
|
|
273
|
+
yield fn(arg);
|
|
274
|
+
callback();
|
|
275
|
+
}
|
|
276
|
+
catch (err) {
|
|
277
|
+
callback(err);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
this.subCommonDeps = new Map();
|
|
281
|
+
this.subCommonChunks = new Map();
|
|
282
|
+
this.subPackagesVendors = new Map();
|
|
283
|
+
this.distPath = '';
|
|
284
|
+
this.exclude = options.exclude || [];
|
|
285
|
+
this.fileType = options.fileType || {
|
|
286
|
+
style: '.wxss',
|
|
287
|
+
config: '.json',
|
|
288
|
+
script: '.js',
|
|
289
|
+
templ: '.wxml',
|
|
290
|
+
xs: '.wxs'
|
|
291
|
+
};
|
|
292
|
+
FileExtsMap.STYLE = this.fileType.style;
|
|
293
|
+
}
|
|
294
|
+
apply(compiler) {
|
|
295
|
+
const { webpack, context, options } = compiler;
|
|
296
|
+
const { util, Compilation } = webpack;
|
|
297
|
+
this.context = context;
|
|
298
|
+
this.subPackages = this.getSubpackageConfig(compiler).map((subPackage) => (Object.assign(Object.assign({}, subPackage), { root: this.formatSubRoot(subPackage.root) })));
|
|
299
|
+
if (this.subPackages.length === 0) {
|
|
300
|
+
return;
|
|
301
|
+
}
|
|
302
|
+
this.subRoots = this.subPackages.map((subPackage) => subPackage.root);
|
|
303
|
+
this.subRootRegExps = this.subRoots.map((subRoot) => new RegExp(`^${subRoot}\\/`));
|
|
304
|
+
this.distPath = options.output.path || '';
|
|
305
|
+
this.isDevMode = options.mode === 'development';
|
|
306
|
+
/**
|
|
307
|
+
* 调用父类SplitChunksPlugin的apply方法,注册相关处理事件
|
|
308
|
+
*/
|
|
309
|
+
super.apply(compiler);
|
|
310
|
+
/**
|
|
311
|
+
* 当一个编译创建完成时,调用该方法
|
|
312
|
+
*/
|
|
313
|
+
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
|
314
|
+
/**
|
|
315
|
+
* 在chunk优化阶段的开始时,调用该方法
|
|
316
|
+
*/
|
|
317
|
+
compilation.hooks.optimizeChunks.tap(PLUGIN_NAME, (chunks) => {
|
|
318
|
+
var _a;
|
|
319
|
+
const splitChunksOriginConfig = Object.assign({}, (_a = options.optimization) === null || _a === void 0 ? void 0 : _a.splitChunks);
|
|
320
|
+
this.subCommonDeps = new Map();
|
|
321
|
+
this.subCommonChunks = new Map();
|
|
322
|
+
this.subPackagesVendors = new Map();
|
|
323
|
+
/**
|
|
324
|
+
* 找出分包入口chunks
|
|
325
|
+
*/
|
|
326
|
+
const subChunks = [];
|
|
327
|
+
for (const chunk of chunks) {
|
|
328
|
+
if (this.isSubChunk(chunk))
|
|
329
|
+
subChunks.push(chunk);
|
|
330
|
+
}
|
|
331
|
+
if (subChunks.length === 0) {
|
|
332
|
+
this.options = Object.assign(Object.assign({}, this.options), { maxInitialRequests: Infinity, getCacheGroups: normalizeCacheGroups(Object.assign({}, splitChunksOriginConfig.cacheGroups), this.options.defaultSizeTypes) });
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const chunkGraph = compilation.chunkGraph;
|
|
336
|
+
subChunks.forEach((subChunk) => {
|
|
337
|
+
const modulesIterable = chunkGraph.getOrderedChunkModulesIterable(subChunk, util.comparators.compareModulesByIdentifier);
|
|
338
|
+
for (const module of modulesIterable) {
|
|
339
|
+
if (this.isExternalModule(module)) {
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
if (!this.hasModuleId(module)) {
|
|
343
|
+
return;
|
|
344
|
+
}
|
|
345
|
+
if (this.hasExclude() && this.isExcludeModule(module)) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const chunks = Array.from(chunkGraph.getModuleChunks(module));
|
|
349
|
+
const chunkNames = chunks.map(chunk => chunk.name);
|
|
350
|
+
/**
|
|
351
|
+
* 找出没有被主包引用,且被多个分包引用的module,并记录在subCommonDeps中
|
|
352
|
+
*/
|
|
353
|
+
if (!this.hasMainChunk(chunkNames) && this.isSubsDep(chunkNames)) {
|
|
354
|
+
const { resource, _identifier: identifier } = module;
|
|
355
|
+
const depName = md5(resource !== null && resource !== void 0 ? resource : identifier);
|
|
356
|
+
if (!this.subCommonDeps.has(depName)) {
|
|
357
|
+
const subCommonDepChunks = new Set(chunkNames);
|
|
358
|
+
this.subCommonDeps.set(depName, {
|
|
359
|
+
identifier,
|
|
360
|
+
resource,
|
|
361
|
+
chunks: subCommonDepChunks
|
|
362
|
+
});
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
const subCommonDep = this.subCommonDeps.get(depName);
|
|
366
|
+
chunks.map(chunk => subCommonDep.chunks.add(chunk.name));
|
|
367
|
+
this.subCommonDeps.set(depName, subCommonDep);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
/**
|
|
373
|
+
* 用新的option配置生成新的cacheGroups配置
|
|
374
|
+
*/
|
|
375
|
+
this.options = Object.assign(Object.assign({}, this.options), { maxInitialRequests: Infinity, getCacheGroups: normalizeCacheGroups(Object.assign(Object.assign(Object.assign({}, (splitChunksOriginConfig === null || splitChunksOriginConfig === void 0 ? void 0 : splitChunksOriginConfig.cacheGroups) || {}), this.getSubPackageVendorsCacheGroup()), this.getSubCommonCacheGroup()), this.options.defaultSizeTypes) });
|
|
376
|
+
});
|
|
377
|
+
/**
|
|
378
|
+
* 收集分包下的sub-vendors和sub-common下的公共模块信息
|
|
379
|
+
*/
|
|
380
|
+
compilation.hooks.afterOptimizeChunks.tap(PLUGIN_NAME, chunks => {
|
|
381
|
+
const existSubCommonDeps = new Map();
|
|
382
|
+
for (const chunk of chunks) {
|
|
383
|
+
const chunkName = chunk.name;
|
|
384
|
+
if (this.matchSubVendors(chunk)) {
|
|
385
|
+
const subRoot = this.subRoots.find(subRoot => new RegExp(`^${subRoot}\\/`).test(chunkName));
|
|
386
|
+
this.subPackagesVendors.set(subRoot, chunk);
|
|
387
|
+
}
|
|
388
|
+
if (this.matchSubCommon(chunk)) {
|
|
389
|
+
const depName = chunkName.replace(new RegExp(`^${SUB_COMMON_DIR}\\/(.*)`), '$1');
|
|
390
|
+
if (this.subCommonDeps.has(depName)) {
|
|
391
|
+
existSubCommonDeps.set(depName, this.subCommonDeps.get(depName));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
this.setChunkSubCommons(existSubCommonDeps);
|
|
396
|
+
this.subCommonDeps = existSubCommonDeps;
|
|
397
|
+
});
|
|
398
|
+
compilation.hooks.processAssets.tap({
|
|
399
|
+
name: PLUGIN_NAME,
|
|
400
|
+
stage: Compilation.PROCESS_ASSETS_STAGE_ANALYSE // see below for more stages
|
|
401
|
+
}, (assets) => {
|
|
402
|
+
this.assets = assets;
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
compiler.hooks.emit.tapAsync(PLUGIN_NAME, this.tryAsync((compilation) => {
|
|
406
|
+
for (const entryName of compilation.entries.keys()) {
|
|
407
|
+
if (this.isSubEntry(entryName)) {
|
|
408
|
+
const subRoot = this.subRoots.find(subRoot => new RegExp(`^${subRoot}\\/`).test(entryName));
|
|
409
|
+
const subCommon = [...(this.subCommonChunks.get(entryName) || [])];
|
|
410
|
+
for (const key in FileExtsMap) {
|
|
411
|
+
const ext = FileExtsMap[key];
|
|
412
|
+
if (ext === FileExtsMap.JS || ext === FileExtsMap.STYLE) {
|
|
413
|
+
const source = new webpack_sources_1.ConcatSource();
|
|
414
|
+
const chunkName = `${entryName}${ext}`;
|
|
415
|
+
const chunkAbsulutePath = path.resolve(this.distPath, chunkName);
|
|
416
|
+
const subVendorsPath = path.join(subRoot, `${SUB_VENDORS_NAME}${ext}`);
|
|
417
|
+
// 将子包 vendors 插入到 entry 中
|
|
418
|
+
if (this.assets[helper_1.normalizePath(subVendorsPath)]) {
|
|
419
|
+
const subVendorsAbsolutePath = path.resolve(this.distPath, subVendorsPath);
|
|
420
|
+
const vendorsRelativePath = this.getRealRelativePath(chunkAbsulutePath, subVendorsAbsolutePath);
|
|
421
|
+
if (ext === FileExtsMap.STYLE) {
|
|
422
|
+
source.add(`@import ${JSON.stringify(`${vendorsRelativePath}`)};`);
|
|
423
|
+
}
|
|
424
|
+
if (ext === FileExtsMap.JS) {
|
|
425
|
+
source.add(`require(${JSON.stringify(`${vendorsRelativePath}`)});`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// 将子包下的 common 模块替换为父包下的 common 模块
|
|
429
|
+
subCommon.forEach(moduleName => {
|
|
430
|
+
const moduleFileName = `${moduleName}${ext}`;
|
|
431
|
+
const moduleFilePath = path.join(SUB_COMMON_DIR, moduleFileName);
|
|
432
|
+
const subRootModuleFilePath = path.join(subRoot, moduleFilePath);
|
|
433
|
+
const assetSource = this.assets[helper_1.normalizePath(moduleFilePath)];
|
|
434
|
+
if (assetSource) {
|
|
435
|
+
const moduleAbsulutePath = path.resolve(this.distPath, subRootModuleFilePath);
|
|
436
|
+
const chunkRelativePath = this.getRealRelativePath(path.resolve(this.distPath, chunkName), moduleAbsulutePath);
|
|
437
|
+
this.assets[helper_1.normalizePath(subRootModuleFilePath)] = {
|
|
438
|
+
size: () => assetSource.size(),
|
|
439
|
+
source: () => assetSource.source(),
|
|
440
|
+
updateHash: () => assetSource.updateHash,
|
|
441
|
+
buffer: () => assetSource.buffer(),
|
|
442
|
+
map: () => assetSource.map(),
|
|
443
|
+
sourceAndMap: () => assetSource.sourceAndMap()
|
|
444
|
+
};
|
|
445
|
+
if (ext === FileExtsMap.STYLE) {
|
|
446
|
+
source.add(`@import ${JSON.stringify(`${chunkRelativePath}`)};`);
|
|
447
|
+
}
|
|
448
|
+
if (ext === FileExtsMap.JS) {
|
|
449
|
+
source.add(`require(${JSON.stringify(`${chunkRelativePath}`)});`);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
});
|
|
453
|
+
if (this.assets[chunkName]) {
|
|
454
|
+
const originSource = this.assets[chunkName].source();
|
|
455
|
+
if (ext === FileExtsMap.STYLE && typeof originSource === 'string') {
|
|
456
|
+
if (originSource.indexOf('@charset') > -1) {
|
|
457
|
+
this.assets[chunkName] = new webpack_sources_1.RawSource(`@charset "UTF-8";${source.source()}${originSource.replace('@charset "UTF-8";', '')}`);
|
|
458
|
+
}
|
|
459
|
+
else {
|
|
460
|
+
this.assets[chunkName] = new webpack_sources_1.RawSource(`${source.source()}${originSource}`);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (ext === FileExtsMap.JS && typeof originSource === 'string') {
|
|
464
|
+
if (originSource.indexOf('use strict') > -1) {
|
|
465
|
+
this.assets[chunkName] = new webpack_sources_1.RawSource(`"use strict";${source.source()}${originSource.replace('"use strict";', '')}`);
|
|
466
|
+
}
|
|
467
|
+
else {
|
|
468
|
+
this.assets[chunkName] = new webpack_sources_1.RawSource(`${source.source()}${originSource}`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* 根目录下的sub-common资源删掉不输出
|
|
478
|
+
*/
|
|
479
|
+
for (const assetPath in this.assets) {
|
|
480
|
+
if (new RegExp(`^${SUB_COMMON_DIR}\\/.*`).test(assetPath)) {
|
|
481
|
+
delete this.assets[assetPath];
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
}));
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* 根据 webpack entry 配置获取入口文件路径
|
|
488
|
+
*/
|
|
489
|
+
getAppEntry(compiler) {
|
|
490
|
+
const { entry } = compiler.options;
|
|
491
|
+
if (shared_1.isFunction(entry)) {
|
|
492
|
+
return '';
|
|
493
|
+
}
|
|
494
|
+
function getEntryPath(entry) {
|
|
495
|
+
const app = entry.app;
|
|
496
|
+
if (Array.isArray(app)) {
|
|
497
|
+
return app[0];
|
|
498
|
+
}
|
|
499
|
+
else if (Array.isArray(app.import)) {
|
|
500
|
+
return app.import[0];
|
|
501
|
+
}
|
|
502
|
+
return app;
|
|
503
|
+
}
|
|
504
|
+
return getEntryPath(entry);
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* 获取分包配置
|
|
508
|
+
*/
|
|
509
|
+
getSubpackageConfig(compiler) {
|
|
510
|
+
const appEntry = this.getAppEntry(compiler);
|
|
511
|
+
const appConfigPath = this.getConfigFilePath(appEntry);
|
|
512
|
+
const appConfig = helper_1.readConfig(appConfigPath);
|
|
513
|
+
return appConfig.subPackages || appConfig.subpackages || [];
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* 根据 app、页面、组件的路径获取对应的 config 配置文件的路径
|
|
517
|
+
*/
|
|
518
|
+
getConfigFilePath(filePath) {
|
|
519
|
+
return helper_1.resolveMainFilePath(`${filePath.replace(path.extname(filePath), '')}.config`);
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* 去掉尾部的/
|
|
523
|
+
*/
|
|
524
|
+
formatSubRoot(subRoot) {
|
|
525
|
+
const lastApl = subRoot[subRoot.length - 1];
|
|
526
|
+
if (lastApl === '/') {
|
|
527
|
+
subRoot = subRoot.slice(0, subRoot.length - 1);
|
|
528
|
+
}
|
|
529
|
+
return subRoot;
|
|
530
|
+
}
|
|
531
|
+
isSubChunk(chunk) {
|
|
532
|
+
const isSubChunk = this.subRootRegExps.find(subRootRegExp => subRootRegExp.test(chunk.name));
|
|
533
|
+
return !!isSubChunk;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* 判断是否是子 entry & 排除.config entry
|
|
537
|
+
*/
|
|
538
|
+
isSubEntry(entry) {
|
|
539
|
+
return !!this.subRootRegExps.find(subRootRegExp => subRootRegExp.test(entry)) && entry.indexOf('.config') === -1;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* match *\/sub-vendors
|
|
543
|
+
*/
|
|
544
|
+
matchSubVendors(chunk) {
|
|
545
|
+
const subVendorsRegExps = this.subRoots.map(subRoot => new RegExp(`^${helper_1.normalizePath(path.join(subRoot, SUB_VENDORS_NAME))}$`));
|
|
546
|
+
const isSubVendors = subVendorsRegExps.find(subVendorsRegExp => subVendorsRegExp.test(chunk.name));
|
|
547
|
+
return !!isSubVendors;
|
|
548
|
+
}
|
|
549
|
+
/**
|
|
550
|
+
* match sub-common\/*
|
|
551
|
+
*/
|
|
552
|
+
matchSubCommon(chunk) {
|
|
553
|
+
return new RegExp(`^${SUB_COMMON_DIR}\\/`).test(chunk.name);
|
|
554
|
+
}
|
|
555
|
+
/**
|
|
556
|
+
* 判断module有没被主包引用
|
|
557
|
+
*/
|
|
558
|
+
hasMainChunk(chunkNames) {
|
|
559
|
+
/**
|
|
560
|
+
* 遍历chunk,如果其中有一个chunk,无法匹配分包root,则视为非分包的chunk
|
|
561
|
+
*/
|
|
562
|
+
return !!chunkNames.find((chunkName) => !(this.subRootRegExps.find(subRootRegExp => subRootRegExp.test(chunkName))));
|
|
563
|
+
}
|
|
564
|
+
/**
|
|
565
|
+
* 判断该module有没被多个分包引用
|
|
566
|
+
*/
|
|
567
|
+
isSubsDep(chunkNames) {
|
|
568
|
+
const chunkSubRoots = new Set();
|
|
569
|
+
chunkNames.forEach((chunkName) => {
|
|
570
|
+
this.subRoots.forEach((subRoot) => {
|
|
571
|
+
if (new RegExp(`^${subRoot}\\/`).test(chunkName)) {
|
|
572
|
+
chunkSubRoots.add(subRoot);
|
|
573
|
+
}
|
|
574
|
+
});
|
|
575
|
+
});
|
|
576
|
+
return chunkSubRoots.size > 1;
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* 仅分包有引用的module抽取到分包下的sub-vendors
|
|
580
|
+
*/
|
|
581
|
+
getSubPackageVendorsCacheGroup() {
|
|
582
|
+
const subPackageVendorsCacheGroup = {};
|
|
583
|
+
this.subRoots.forEach(subRoot => {
|
|
584
|
+
subPackageVendorsCacheGroup[subRoot] = {
|
|
585
|
+
test: (module, { chunkGraph }) => {
|
|
586
|
+
if (this.hasExclude() && this.isExcludeModule(module)) {
|
|
587
|
+
return false;
|
|
588
|
+
}
|
|
589
|
+
const chunks = Array.from(chunkGraph.getModuleChunksIterable(module));
|
|
590
|
+
return chunks.every(chunk => new RegExp(`^${subRoot}\\/`).test(chunk.name));
|
|
591
|
+
},
|
|
592
|
+
name: helper_1.normalizePath(path.join(subRoot, SUB_VENDORS_NAME)),
|
|
593
|
+
minChunks: 2,
|
|
594
|
+
priority: 10000
|
|
595
|
+
};
|
|
596
|
+
});
|
|
597
|
+
return subPackageVendorsCacheGroup;
|
|
598
|
+
}
|
|
599
|
+
/**
|
|
600
|
+
* 没有被主包引用, 且被多个分包引用, 提取成单个模块,输出到sub-common下
|
|
601
|
+
*/
|
|
602
|
+
getSubCommonCacheGroup() {
|
|
603
|
+
const subCommonCacheGroup = {};
|
|
604
|
+
this.subCommonDeps.forEach((depInfo, depName) => {
|
|
605
|
+
const cacheGroupName = helper_1.normalizePath(path.join(SUB_COMMON_DIR, depName));
|
|
606
|
+
subCommonCacheGroup[cacheGroupName] = {
|
|
607
|
+
name: cacheGroupName,
|
|
608
|
+
test: module => {
|
|
609
|
+
if (!module.resource) {
|
|
610
|
+
return !!module._identifier && module._identifier === depInfo.identifier;
|
|
611
|
+
}
|
|
612
|
+
return module.resource === depInfo.resource;
|
|
613
|
+
},
|
|
614
|
+
priority: 1000
|
|
615
|
+
};
|
|
616
|
+
});
|
|
617
|
+
return subCommonCacheGroup;
|
|
618
|
+
}
|
|
619
|
+
hasExclude() {
|
|
620
|
+
return shared_1.isArray(this.exclude) && this.exclude.length > 0;
|
|
621
|
+
}
|
|
622
|
+
isExcludeModule(module) {
|
|
623
|
+
const moduleResource = module.resource;
|
|
624
|
+
for (let i = 0; i < this.exclude.length; i++) {
|
|
625
|
+
const excludeItem = this.exclude[i];
|
|
626
|
+
if (shared_1.isString(excludeItem) && excludeItem === moduleResource) {
|
|
627
|
+
return true;
|
|
628
|
+
}
|
|
629
|
+
if (shared_1.isFunction(excludeItem) && excludeItem(module)) {
|
|
630
|
+
return true;
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return false;
|
|
634
|
+
}
|
|
635
|
+
setChunkSubCommons(subCommonDeps) {
|
|
636
|
+
const subCommonChunks = new Map();
|
|
637
|
+
subCommonDeps.forEach((depInfo, depName) => {
|
|
638
|
+
const chunks = [...depInfo.chunks];
|
|
639
|
+
chunks.forEach(chunk => {
|
|
640
|
+
if (subCommonChunks.has(chunk)) {
|
|
641
|
+
const chunkSubCommon = subCommonChunks.get(chunk);
|
|
642
|
+
chunkSubCommon.add(depName);
|
|
643
|
+
subCommonChunks.set(chunk, chunkSubCommon);
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
subCommonChunks.set(chunk, new Set([depName]));
|
|
647
|
+
}
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
this.subCommonChunks = subCommonChunks;
|
|
651
|
+
}
|
|
652
|
+
/**
|
|
653
|
+
* 获取page相对于公共模块的路径
|
|
654
|
+
*/
|
|
655
|
+
getRealRelativePath(from, to) {
|
|
656
|
+
return helper_1.promoteRelativePath(path.relative(from, to));
|
|
657
|
+
}
|
|
658
|
+
/**
|
|
659
|
+
* 判断module为external module
|
|
660
|
+
*/
|
|
661
|
+
isExternalModule(module) {
|
|
662
|
+
return !!module.external;
|
|
663
|
+
}
|
|
664
|
+
/**
|
|
665
|
+
* 判断是否存在resource和_identifier
|
|
666
|
+
*/
|
|
667
|
+
hasModuleId(module) {
|
|
668
|
+
if (module.resource) {
|
|
669
|
+
return true;
|
|
670
|
+
}
|
|
671
|
+
if (module._identifier) {
|
|
672
|
+
return true;
|
|
673
|
+
}
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
exports.default = MiniSplitChunksPlugin;
|
|
678
|
+
//# sourceMappingURL=MiniSplitChunksPlugin.js.map
|