@mpxjs/webpack-plugin 2.6.115 → 2.7.0-alpha
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/LICENSE +433 -0
- package/README.md +1 -1
- package/lib/config.js +14 -0
- package/lib/dependencies/AddEntryDependency.js +24 -0
- package/lib/dependencies/AppEntryDependency.js +58 -0
- package/lib/dependencies/CommonJsAsyncDependency.js +51 -0
- package/lib/dependencies/CommonJsVariableDependency.js +81 -0
- package/lib/dependencies/DynamicEntryDependency.js +171 -0
- package/lib/dependencies/FlagPluginDependency.js +24 -0
- package/lib/dependencies/InjectDependency.js +43 -0
- package/lib/dependencies/RecordGlobalComponentsDependency.js +50 -0
- package/lib/dependencies/RecordIndependentDependency.js +44 -0
- package/lib/dependencies/RecordResourceMapDependency.js +62 -0
- package/lib/dependencies/RemoveEntryDependency.js +40 -0
- package/lib/{dependency → dependencies}/ReplaceDependency.js +19 -2
- package/lib/dependencies/ResolveDependency.js +88 -0
- package/lib/extractor.js +82 -178
- package/lib/file-loader.js +7 -19
- package/lib/helpers.js +39 -334
- package/lib/independent-loader.js +52 -0
- package/lib/index.js +889 -525
- package/lib/json-compiler/helper.js +156 -0
- package/lib/json-compiler/index.js +245 -451
- package/lib/json-compiler/plugin.js +150 -0
- package/lib/json-compiler/{theme-loader.js → theme.js} +5 -3
- package/lib/loader.js +178 -241
- package/lib/native-loader.js +71 -133
- package/lib/parser.js +1 -2
- package/lib/partial-compile/index.js +35 -0
- package/lib/platform/json/wx/index.js +1 -1
- package/lib/platform/template/normalize-component-rules.js +2 -3
- package/lib/platform/template/wx/component-config/button.js +14 -2
- package/lib/platform/template/wx/component-config/image.js +4 -0
- package/lib/platform/template/wx/component-config/input.js +4 -0
- package/lib/platform/template/wx/component-config/rich-text.js +4 -0
- package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
- package/lib/platform/template/wx/component-config/switch.js +4 -0
- package/lib/platform/template/wx/component-config/text.js +4 -0
- package/lib/platform/template/wx/component-config/textarea.js +5 -0
- package/lib/platform/template/wx/component-config/view.js +4 -0
- package/lib/platform/template/wx/index.js +149 -3
- package/lib/record-loader.js +11 -0
- package/lib/resolve-loader.js +6 -0
- package/lib/resolver/AddEnvPlugin.js +4 -3
- package/lib/resolver/AddModePlugin.js +4 -3
- package/lib/resolver/FixDescriptionInfoPlugin.js +28 -0
- package/lib/resolver/PackageEntryPlugin.js +23 -36
- package/lib/runtime/base.styl +5 -0
- package/lib/runtime/components/tenon/getInnerListeners.js +317 -0
- package/lib/runtime/components/tenon/tenon-button.vue +305 -0
- package/lib/runtime/components/tenon/tenon-image.vue +61 -0
- package/lib/runtime/components/tenon/tenon-input.vue +99 -0
- package/lib/runtime/components/tenon/tenon-rich-text.vue +21 -0
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +124 -0
- package/lib/runtime/components/tenon/tenon-switch.vue +91 -0
- package/lib/runtime/components/tenon/tenon-text-area.vue +64 -0
- package/lib/runtime/components/tenon/tenon-text.vue +64 -0
- package/lib/runtime/components/tenon/tenon-view.vue +93 -0
- package/lib/runtime/components/tenon/util.js +44 -0
- package/lib/runtime/components/web/getInnerListeners.js +1 -3
- package/lib/runtime/components/web/mpx-image.vue +20 -5
- package/lib/runtime/components/web/mpx-movable-view.vue +6 -2
- package/lib/runtime/components/web/mpx-swiper.vue +18 -3
- package/lib/runtime/i18n.wxs +31 -11
- package/lib/runtime/optionProcessor.js +48 -3
- package/lib/runtime/optionProcessor.tenon.js +386 -0
- package/lib/selector.js +29 -10
- package/lib/style-compiler/index.js +16 -24
- package/lib/style-compiler/load-postcss-config.js +3 -1
- package/lib/style-compiler/plugins/conditional-strip.js +68 -65
- package/lib/style-compiler/plugins/hm.js +20 -0
- package/lib/style-compiler/plugins/rpx.js +43 -37
- package/lib/style-compiler/plugins/scope-id.js +79 -72
- package/lib/style-compiler/plugins/trans-special.js +25 -18
- package/lib/style-compiler/plugins/trim.js +13 -7
- package/lib/style-compiler/plugins/vw.js +22 -16
- package/lib/template-compiler/compiler.js +106 -199
- package/lib/template-compiler/index.js +52 -139
- package/lib/template-compiler/trans-dynamic-class-expr.js +18 -13
- package/lib/tenon/index.js +105 -0
- package/lib/tenon/processJSON.js +356 -0
- package/lib/tenon/processScript.js +261 -0
- package/lib/tenon/processStyles.js +21 -0
- package/lib/tenon/processTemplate.js +133 -0
- package/lib/url-loader.js +11 -29
- package/lib/utils/add-query.js +1 -1
- package/lib/utils/const.js +10 -0
- package/lib/utils/emit-file.js +10 -0
- package/lib/utils/eval-json-js.js +31 -0
- package/lib/utils/get-entry-name.js +13 -0
- package/lib/utils/get-json-content.js +42 -0
- package/lib/utils/get-relative-path.js +25 -0
- package/lib/utils/is-url-request.js +10 -1
- package/lib/utils/match-condition.js +4 -1
- package/lib/utils/normalize.js +4 -15
- package/lib/utils/parse-request.js +3 -3
- package/lib/utils/resolve.js +13 -0
- package/lib/utils/set.js +47 -0
- package/lib/utils/stringify-loaders-resource.js +25 -0
- package/lib/utils/stringify-query.js +4 -0
- package/lib/web/processJSON.js +113 -144
- package/lib/web/processScript.js +47 -34
- package/lib/web/processTemplate.js +57 -40
- package/lib/wxml/{wxml-loader.js → loader.js} +21 -62
- package/lib/wxs/WxsModuleIdsPlugin.js +29 -0
- package/lib/wxs/WxsParserPlugin.js +2 -2
- package/lib/wxs/WxsPlugin.js +4 -8
- package/lib/wxs/WxsTemplatePlugin.js +46 -92
- package/lib/wxs/{wxs-i18n-loader.js → i18n-loader.js} +5 -4
- package/lib/wxs/loader.js +142 -0
- package/lib/wxs/{wxs-pre-loader.js → pre-loader.js} +20 -5
- package/lib/wxss/loader.js +31 -43
- package/lib/wxss/localsLoader.js +1 -5
- package/lib/wxss/processCss.js +107 -103
- package/package.json +21 -18
- package/lib/built-in-loader.js +0 -49
- package/lib/content-loader.js +0 -13
- package/lib/dependency/ChildCompileDependency.js +0 -24
- package/lib/dependency/InjectDependency.js +0 -26
- package/lib/dependency/RemovedModuleDependency.js +0 -23
- package/lib/dependency/ResolveDependency.js +0 -49
- package/lib/path-loader.js +0 -3
- package/lib/plugin-loader.js +0 -287
- package/lib/staticConfig.js +0 -4
- package/lib/utils/get-main-compilation.js +0 -6
- package/lib/utils/read-json-for-src.js +0 -34
- package/lib/utils/try-require.js +0 -16
- package/lib/wxs/wxs-loader.js +0 -117
- package/lib/wxss/getImportPrefix.js +0 -30
package/lib/index.js
CHANGED
|
@@ -1,68 +1,89 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const path = require('path')
|
|
4
|
-
const ConcatSource = require('webpack
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const ReplaceDependency = require('./dependency/ReplaceDependency')
|
|
9
|
-
const ChildCompileDependency = require('./dependency/ChildCompileDependency')
|
|
4
|
+
const { ConcatSource, RawSource } = require('webpack').sources
|
|
5
|
+
const ResolveDependency = require('./dependencies/ResolveDependency')
|
|
6
|
+
const InjectDependency = require('./dependencies/InjectDependency')
|
|
7
|
+
const ReplaceDependency = require('./dependencies/ReplaceDependency')
|
|
10
8
|
const NullFactory = require('webpack/lib/NullFactory')
|
|
9
|
+
const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
|
|
10
|
+
const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
|
|
11
|
+
const harmonySpecifierTag = require('webpack/lib/dependencies/HarmonyImportDependencyParserPlugin').harmonySpecifierTag
|
|
12
|
+
const NormalModule = require('webpack/lib/NormalModule')
|
|
13
|
+
const EntryPlugin = require('webpack/lib/EntryPlugin')
|
|
14
|
+
const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
|
|
15
|
+
const FlagEntryExportAsUsedPlugin = require('webpack/lib/FlagEntryExportAsUsedPlugin')
|
|
16
|
+
const FileSystemInfo = require('webpack/lib/FileSystemInfo')
|
|
11
17
|
const normalize = require('./utils/normalize')
|
|
12
18
|
const toPosix = require('./utils/to-posix')
|
|
13
19
|
const addQuery = require('./utils/add-query')
|
|
20
|
+
const { every } = require('./utils/set')
|
|
14
21
|
const DefinePlugin = require('webpack/lib/DefinePlugin')
|
|
15
22
|
const ExternalsPlugin = require('webpack/lib/ExternalsPlugin')
|
|
16
23
|
const AddModePlugin = require('./resolver/AddModePlugin')
|
|
17
24
|
const AddEnvPlugin = require('./resolver/AddEnvPlugin')
|
|
18
25
|
const PackageEntryPlugin = require('./resolver/PackageEntryPlugin')
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
26
|
+
const FixDescriptionInfoPlugin = require('./resolver/FixDescriptionInfoPlugin')
|
|
27
|
+
// const CommonJsRequireDependency = require('webpack/lib/dependencies/CommonJsRequireDependency')
|
|
28
|
+
// const HarmonyImportSideEffectDependency = require('webpack/lib/dependencies/HarmonyImportSideEffectDependency')
|
|
29
|
+
// const RequireHeaderDependency = require('webpack/lib/dependencies/RequireHeaderDependency')
|
|
30
|
+
// const RemovedModuleDependency = require('./dependencies/RemovedModuleDependency')
|
|
31
|
+
const AppEntryDependency = require('./dependencies/AppEntryDependency')
|
|
32
|
+
const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
|
|
33
|
+
const RecordGlobalComponentsDependency = require('./dependencies/RecordGlobalComponentsDependency')
|
|
34
|
+
const RecordIndependentDependency = require('./dependencies/RecordIndependentDependency')
|
|
35
|
+
const DynamicEntryDependency = require('./dependencies/DynamicEntryDependency')
|
|
36
|
+
const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
|
|
37
|
+
const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
|
|
23
38
|
const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
|
|
39
|
+
const PartialCompilePlugin = require('./partial-compile/index')
|
|
24
40
|
const fixRelative = require('./utils/fix-relative')
|
|
25
41
|
const parseRequest = require('./utils/parse-request')
|
|
26
|
-
const matchCondition = require('./utils/match-condition')
|
|
42
|
+
const { matchCondition } = require('./utils/match-condition')
|
|
27
43
|
const { preProcessDefs } = require('./utils/index')
|
|
44
|
+
const config = require('./config')
|
|
28
45
|
const hash = require('hash-sum')
|
|
46
|
+
const wxssLoaderPath = normalize.lib('wxss/loader')
|
|
47
|
+
const wxmlLoaderPath = normalize.lib('wxml/loader')
|
|
48
|
+
const wxsLoaderPath = normalize.lib('wxs/loader')
|
|
49
|
+
const styleCompilerPath = normalize.lib('style-compiler/index')
|
|
50
|
+
const templateCompilerPath = normalize.lib('template-compiler/index')
|
|
51
|
+
const jsonCompilerPath = normalize.lib('json-compiler/index')
|
|
52
|
+
const jsonThemeCompilerPath = normalize.lib('json-compiler/theme')
|
|
53
|
+
const jsonPluginCompilerPath = normalize.lib('json-compiler/plugin')
|
|
54
|
+
const extractorPath = normalize.lib('extractor')
|
|
55
|
+
const async = require('async')
|
|
56
|
+
const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
|
|
57
|
+
const emitFile = require('./utils/emit-file')
|
|
58
|
+
const { MPX_PROCESSED_FLAG, MPX_DISABLE_EXTRACTOR_CACHE, MPX_CURRENT_CHUNK } = require('./utils/const')
|
|
59
|
+
const isEmptyObject = require('./utils/is-empty-object')
|
|
29
60
|
|
|
30
61
|
const isProductionLikeMode = options => {
|
|
31
62
|
return options.mode === 'production' || !options.mode
|
|
32
63
|
}
|
|
33
64
|
|
|
65
|
+
const isStaticModule = module => {
|
|
66
|
+
if (!module.resource) return false
|
|
67
|
+
const { queryObj } = parseRequest(module.resource)
|
|
68
|
+
let isStatic = queryObj.isStatic || false
|
|
69
|
+
if (module.loaders) {
|
|
70
|
+
for (const loader of module.loaders) {
|
|
71
|
+
if (/(url-loader|file-loader)/.test(loader.loader)) {
|
|
72
|
+
isStatic = true
|
|
73
|
+
break
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
return isStatic
|
|
78
|
+
}
|
|
79
|
+
|
|
34
80
|
const outputFilename = '[name].js'
|
|
35
81
|
const publicPath = '/'
|
|
36
82
|
|
|
37
|
-
|
|
83
|
+
const isChunkInPackage = (chunkName, packageName) => {
|
|
38
84
|
return (new RegExp(`^${packageName}\\/`)).test(chunkName)
|
|
39
85
|
}
|
|
40
86
|
|
|
41
|
-
function getPackageCacheGroup (packageName) {
|
|
42
|
-
if (packageName === 'main') {
|
|
43
|
-
return {
|
|
44
|
-
name: 'bundle',
|
|
45
|
-
minChunks: 2,
|
|
46
|
-
chunks: 'all'
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
return {
|
|
50
|
-
test: (module, chunks) => {
|
|
51
|
-
return chunks.every((chunk) => {
|
|
52
|
-
return isChunkInPackage(chunk.name, packageName)
|
|
53
|
-
})
|
|
54
|
-
},
|
|
55
|
-
name: `${packageName}/bundle`,
|
|
56
|
-
minChunks: 2,
|
|
57
|
-
minSize: 1000,
|
|
58
|
-
priority: 100,
|
|
59
|
-
chunks: 'all'
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
let loaderOptions
|
|
65
|
-
|
|
66
87
|
const externalsMap = {
|
|
67
88
|
weui: /^weui-miniprogram/
|
|
68
89
|
}
|
|
@@ -71,10 +92,9 @@ const warnings = []
|
|
|
71
92
|
const errors = []
|
|
72
93
|
|
|
73
94
|
class EntryNode {
|
|
74
|
-
constructor (
|
|
75
|
-
this.
|
|
76
|
-
this.type =
|
|
77
|
-
this.module = null
|
|
95
|
+
constructor (module, type) {
|
|
96
|
+
this.module = module
|
|
97
|
+
this.type = type
|
|
78
98
|
this.parents = new Set()
|
|
79
99
|
this.children = new Set()
|
|
80
100
|
}
|
|
@@ -102,7 +122,6 @@ class MpxWebpackPlugin {
|
|
|
102
122
|
options.writeMode = options.writeMode || 'changed'
|
|
103
123
|
options.autoScopeRules = options.autoScopeRules || {}
|
|
104
124
|
options.autoVirtualHostRules = options.autoVirtualHostRules || {}
|
|
105
|
-
options.forceDisableInject = options.forceDisableInject || false
|
|
106
125
|
options.forceDisableProxyCtor = options.forceDisableProxyCtor || false
|
|
107
126
|
options.transMpxRules = options.transMpxRules || {
|
|
108
127
|
include: () => true
|
|
@@ -124,12 +143,8 @@ class MpxWebpackPlugin {
|
|
|
124
143
|
options.forceUsePageCtor = options.forceUsePageCtor || false
|
|
125
144
|
options.postcssInlineConfig = options.postcssInlineConfig || {}
|
|
126
145
|
options.transRpxRules = options.transRpxRules || null
|
|
127
|
-
options.webConfig = options.webConfig || {}
|
|
128
146
|
options.auditResource = options.auditResource || false
|
|
129
147
|
options.decodeHTMLText = options.decodeHTMLText || false
|
|
130
|
-
options.nativeOptions = Object.assign({
|
|
131
|
-
cssLangs: ['css', 'less', 'stylus', 'scss', 'sass']
|
|
132
|
-
}, options.nativeOptions)
|
|
133
148
|
options.i18n = options.i18n || null
|
|
134
149
|
options.checkUsingComponents = options.checkUsingComponents || false
|
|
135
150
|
options.reportSize = options.reportSize || null
|
|
@@ -144,31 +159,103 @@ class MpxWebpackPlugin {
|
|
|
144
159
|
include: () => true
|
|
145
160
|
}
|
|
146
161
|
options.customOutputPath = options.customOutputPath || null
|
|
162
|
+
options.nativeConfig = Object.assign({
|
|
163
|
+
cssLangs: ['css', 'less', 'stylus', 'scss', 'sass']
|
|
164
|
+
}, options.nativeConfig)
|
|
165
|
+
options.webConfig = options.webConfig || {}
|
|
166
|
+
options.partialCompile = options.mode !== 'web' && options.partialCompile
|
|
167
|
+
let proxyComponentEventsRules = []
|
|
168
|
+
const proxyComponentEventsRulesRaw = options.proxyComponentEventsRules
|
|
169
|
+
if (proxyComponentEventsRulesRaw) {
|
|
170
|
+
proxyComponentEventsRules = Array.isArray(proxyComponentEventsRulesRaw) ? proxyComponentEventsRulesRaw : [proxyComponentEventsRulesRaw]
|
|
171
|
+
}
|
|
172
|
+
options.proxyComponentEventsRules = proxyComponentEventsRules
|
|
147
173
|
this.options = options
|
|
174
|
+
// Hack for buildDependencies
|
|
175
|
+
const rawResolveBuildDependencies = FileSystemInfo.prototype.resolveBuildDependencies
|
|
176
|
+
FileSystemInfo.prototype.resolveBuildDependencies = function (context, deps, rawCallback) {
|
|
177
|
+
return rawResolveBuildDependencies.call(this, context, deps, (err, result) => {
|
|
178
|
+
if (result && typeof options.hackResolveBuildDependencies === 'function') options.hackResolveBuildDependencies(result)
|
|
179
|
+
return rawCallback(err, result)
|
|
180
|
+
})
|
|
181
|
+
}
|
|
148
182
|
}
|
|
149
183
|
|
|
150
184
|
static loader (options = {}) {
|
|
151
|
-
|
|
152
|
-
if (loaderOptions.transRpx) {
|
|
185
|
+
if (options.transRpx) {
|
|
153
186
|
warnings.push('Mpx loader option [transRpx] is deprecated now, please use mpx webpack plugin config [transRpxRules] instead!')
|
|
154
187
|
}
|
|
155
|
-
return {
|
|
188
|
+
return {
|
|
189
|
+
loader: normalize.lib('loader'),
|
|
190
|
+
options
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
static nativeLoader (options = {}) {
|
|
195
|
+
return {
|
|
196
|
+
loader: normalize.lib('native-loader'),
|
|
197
|
+
options
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
static wxssLoader (options) {
|
|
202
|
+
return {
|
|
203
|
+
loader: normalize.lib('wxss/loader'),
|
|
204
|
+
options
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
static wxmlLoader (options) {
|
|
209
|
+
return {
|
|
210
|
+
loader: normalize.lib('wxml/loader'),
|
|
211
|
+
options
|
|
212
|
+
}
|
|
156
213
|
}
|
|
157
214
|
|
|
158
215
|
static pluginLoader (options = {}) {
|
|
159
|
-
return {
|
|
216
|
+
return {
|
|
217
|
+
loader: normalize.lib('json-compiler/plugin'),
|
|
218
|
+
options
|
|
219
|
+
}
|
|
160
220
|
}
|
|
161
221
|
|
|
162
222
|
static wxsPreLoader (options = {}) {
|
|
163
|
-
return {
|
|
223
|
+
return {
|
|
224
|
+
loader: normalize.lib('wxs/pre-loader'),
|
|
225
|
+
options
|
|
226
|
+
}
|
|
164
227
|
}
|
|
165
228
|
|
|
166
229
|
static urlLoader (options = {}) {
|
|
167
|
-
return {
|
|
230
|
+
return {
|
|
231
|
+
loader: normalize.lib('url-loader'),
|
|
232
|
+
options
|
|
233
|
+
}
|
|
168
234
|
}
|
|
169
235
|
|
|
170
236
|
static fileLoader (options = {}) {
|
|
171
|
-
return {
|
|
237
|
+
return {
|
|
238
|
+
loader: normalize.lib('file-loader'),
|
|
239
|
+
options
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
static getPageEntry (request) {
|
|
244
|
+
return addQuery(request, { isPage: true })
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
static getComponentEntry (request) {
|
|
248
|
+
return addQuery(request, { isComponent: true })
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
static getPluginEntry (request) {
|
|
252
|
+
return addQuery(request, {
|
|
253
|
+
mpx: true,
|
|
254
|
+
extract: true,
|
|
255
|
+
isPlugin: true,
|
|
256
|
+
asScript: true,
|
|
257
|
+
type: 'json'
|
|
258
|
+
})
|
|
172
259
|
}
|
|
173
260
|
|
|
174
261
|
runModeRules (data) {
|
|
@@ -194,6 +281,9 @@ class MpxWebpackPlugin {
|
|
|
194
281
|
errors.push('Multiple MpxWebpackPlugin instances exist in webpack compiler, please check webpack plugins config!')
|
|
195
282
|
}
|
|
196
283
|
|
|
284
|
+
// 将entry export标记为used且不可mangle,避免require.async生成的js chunk在生产环境下报错
|
|
285
|
+
new FlagEntryExportAsUsedPlugin(true, 'entry').apply(compiler)
|
|
286
|
+
|
|
197
287
|
if (this.options.mode !== 'web') {
|
|
198
288
|
// 强制设置publicPath为'/'
|
|
199
289
|
if (compiler.options.output.publicPath && compiler.options.output.publicPath !== publicPath) {
|
|
@@ -209,12 +299,11 @@ class MpxWebpackPlugin {
|
|
|
209
299
|
if (!compiler.options.node || !compiler.options.node.global) {
|
|
210
300
|
compiler.options.node = compiler.options.node || {}
|
|
211
301
|
compiler.options.node.global = true
|
|
212
|
-
warnings.push(`webpack options: MpxWebpackPlugin strongly depends options.node.globel to be true, custom options.node will be ignored!`)
|
|
213
302
|
}
|
|
214
303
|
|
|
215
304
|
const addModePlugin = new AddModePlugin('before-file', this.options.mode, this.options.fileConditionRules, 'file')
|
|
216
305
|
const addEnvPlugin = new AddEnvPlugin('before-file', this.options.env, this.options.fileConditionRules, 'file')
|
|
217
|
-
const packageEntryPlugin = new PackageEntryPlugin('before-
|
|
306
|
+
const packageEntryPlugin = new PackageEntryPlugin('before-file', this.options.miniNpmPackages, 'file')
|
|
218
307
|
if (Array.isArray(compiler.options.resolve.plugins)) {
|
|
219
308
|
compiler.options.resolve.plugins.push(addModePlugin)
|
|
220
309
|
} else {
|
|
@@ -224,12 +313,14 @@ class MpxWebpackPlugin {
|
|
|
224
313
|
compiler.options.resolve.plugins.push(addEnvPlugin)
|
|
225
314
|
}
|
|
226
315
|
compiler.options.resolve.plugins.push(packageEntryPlugin)
|
|
316
|
+
compiler.options.resolve.plugins.push(new FixDescriptionInfoPlugin())
|
|
227
317
|
|
|
228
318
|
let splitChunksPlugin
|
|
229
319
|
let splitChunksOptions
|
|
230
320
|
|
|
231
|
-
if (this.options.mode !== 'web') {
|
|
232
|
-
compiler.options.optimization
|
|
321
|
+
if (this.options.mode !== 'web' && this.options.mode !== 'tenon') {
|
|
322
|
+
const optimization = compiler.options.optimization
|
|
323
|
+
optimization.runtimeChunk = {
|
|
233
324
|
name: (entrypoint) => {
|
|
234
325
|
for (let packageName in mpx.independentSubpackagesMap) {
|
|
235
326
|
if (mpx.independentSubpackagesMap.hasOwnProperty(packageName) && isChunkInPackage(entrypoint.name, packageName)) {
|
|
@@ -239,8 +330,18 @@ class MpxWebpackPlugin {
|
|
|
239
330
|
return 'bundle'
|
|
240
331
|
}
|
|
241
332
|
}
|
|
242
|
-
splitChunksOptions =
|
|
243
|
-
|
|
333
|
+
splitChunksOptions = Object.assign({
|
|
334
|
+
defaultSizeTypes: ['javascript', 'unknown'],
|
|
335
|
+
chunks: 'all',
|
|
336
|
+
usedExports: optimization.usedExports === true,
|
|
337
|
+
minChunks: 1,
|
|
338
|
+
minSize: 1000,
|
|
339
|
+
enforceSizeThreshold: Infinity,
|
|
340
|
+
maxAsyncRequests: 30,
|
|
341
|
+
maxInitialRequests: 30,
|
|
342
|
+
automaticNameDelimiter: '-'
|
|
343
|
+
}, optimization.splitChunks)
|
|
344
|
+
delete optimization.splitChunks
|
|
244
345
|
splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
|
|
245
346
|
splitChunksPlugin.apply(compiler)
|
|
246
347
|
}
|
|
@@ -258,8 +359,11 @@ class MpxWebpackPlugin {
|
|
|
258
359
|
originalWriteFile(filePath, content, callback)
|
|
259
360
|
}
|
|
260
361
|
}
|
|
362
|
+
|
|
261
363
|
const defs = this.options.defs
|
|
262
364
|
|
|
365
|
+
const typeExtMap = config[this.options.mode].typeExtMap
|
|
366
|
+
|
|
263
367
|
const defsOpt = {
|
|
264
368
|
'__mpx_wxs__': DefinePlugin.runtimeValue(({ module }) => {
|
|
265
369
|
return JSON.stringify(!!module.wxs)
|
|
@@ -277,12 +381,92 @@ class MpxWebpackPlugin {
|
|
|
277
381
|
|
|
278
382
|
let mpx
|
|
279
383
|
|
|
384
|
+
if (this.options.partialCompile) {
|
|
385
|
+
new PartialCompilePlugin(this.options.partialCompile).apply(compiler)
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
const getPackageCacheGroup = packageName => {
|
|
389
|
+
if (packageName === 'main') {
|
|
390
|
+
return {
|
|
391
|
+
// 对于独立分包模块不应用该cacheGroup
|
|
392
|
+
test: (module) => {
|
|
393
|
+
let isIndependent = false
|
|
394
|
+
if (module.resource) {
|
|
395
|
+
const { queryObj } = parseRequest(module.resource)
|
|
396
|
+
isIndependent = !!queryObj.independent
|
|
397
|
+
} else {
|
|
398
|
+
const identifier = module.identifier()
|
|
399
|
+
isIndependent = /\|independent=/.test(identifier)
|
|
400
|
+
}
|
|
401
|
+
return !isIndependent
|
|
402
|
+
},
|
|
403
|
+
name: 'bundle',
|
|
404
|
+
minChunks: 2,
|
|
405
|
+
chunks: 'all'
|
|
406
|
+
}
|
|
407
|
+
} else {
|
|
408
|
+
return {
|
|
409
|
+
test: (module, { chunkGraph }) => {
|
|
410
|
+
const chunks = chunkGraph.getModuleChunksIterable(module)
|
|
411
|
+
return chunks.size && every(chunks, (chunk) => {
|
|
412
|
+
return isChunkInPackage(chunk.name, packageName)
|
|
413
|
+
})
|
|
414
|
+
},
|
|
415
|
+
name: `${packageName}/bundle`,
|
|
416
|
+
minChunks: 2,
|
|
417
|
+
minSize: 1000,
|
|
418
|
+
priority: 100,
|
|
419
|
+
chunks: 'all'
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
const processSubpackagesEntriesMap = (compilation, callback) => {
|
|
425
|
+
const mpx = compilation.__mpx__
|
|
426
|
+
if (mpx && !isEmptyObject(mpx.subpackagesEntriesMap)) {
|
|
427
|
+
const subpackagesEntriesMap = mpx.subpackagesEntriesMap
|
|
428
|
+
// 执行分包队列前清空mpx.subpackagesEntriesMap
|
|
429
|
+
mpx.subpackagesEntriesMap = {}
|
|
430
|
+
async.eachOfSeries(subpackagesEntriesMap, (deps, packageRoot, callback) => {
|
|
431
|
+
mpx.currentPackageRoot = packageRoot
|
|
432
|
+
mpx.componentsMap[packageRoot] = mpx.componentsMap[packageRoot] || {}
|
|
433
|
+
mpx.staticResourcesMap[packageRoot] = mpx.staticResourcesMap[packageRoot] || {}
|
|
434
|
+
mpx.subpackageModulesMap[packageRoot] = mpx.subpackageModulesMap[packageRoot] || {}
|
|
435
|
+
async.each(deps, (dep, callback) => {
|
|
436
|
+
dep.addEntry(compilation, (err, { resultPath }) => {
|
|
437
|
+
if (err) return callback(err)
|
|
438
|
+
dep.resultPath = mpx.replacePathMap[dep.key] = resultPath
|
|
439
|
+
callback()
|
|
440
|
+
})
|
|
441
|
+
}, callback)
|
|
442
|
+
}, (err) => {
|
|
443
|
+
if (err) return callback(err)
|
|
444
|
+
// 如果执行完当前队列后产生了新的分包执行队列(一般由异步分包组件造成),则继续执行
|
|
445
|
+
processSubpackagesEntriesMap(compilation, callback)
|
|
446
|
+
})
|
|
447
|
+
} else {
|
|
448
|
+
callback()
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// 构建分包队列,在finishMake钩子当中最先执行,stage传递-1000
|
|
453
|
+
compiler.hooks.finishMake.tapAsync({
|
|
454
|
+
name: 'MpxWebpackPlugin',
|
|
455
|
+
stage: -1000
|
|
456
|
+
}, (compilation, callback) => {
|
|
457
|
+
processSubpackagesEntriesMap(compilation, callback)
|
|
458
|
+
})
|
|
459
|
+
|
|
280
460
|
compiler.hooks.compilation.tap('MpxWebpackPlugin ', (compilation, { normalModuleFactory }) => {
|
|
281
|
-
compilation.
|
|
461
|
+
NormalModule.getCompilationHooks(compilation).loader.tap('MpxWebpackPlugin', (loaderContext) => {
|
|
282
462
|
// 设置loaderContext的minimize
|
|
283
463
|
if (isProductionLikeMode(compiler.options)) {
|
|
284
464
|
loaderContext.minimize = true
|
|
285
465
|
}
|
|
466
|
+
|
|
467
|
+
loaderContext.getMpx = () => {
|
|
468
|
+
return mpx
|
|
469
|
+
}
|
|
286
470
|
})
|
|
287
471
|
compilation.dependencyFactories.set(ResolveDependency, new NullFactory())
|
|
288
472
|
compilation.dependencyTemplates.set(ResolveDependency, new ResolveDependency.Template())
|
|
@@ -293,161 +477,92 @@ class MpxWebpackPlugin {
|
|
|
293
477
|
compilation.dependencyFactories.set(ReplaceDependency, new NullFactory())
|
|
294
478
|
compilation.dependencyTemplates.set(ReplaceDependency, new ReplaceDependency.Template())
|
|
295
479
|
|
|
296
|
-
compilation.dependencyFactories.set(
|
|
297
|
-
compilation.dependencyTemplates.set(
|
|
298
|
-
|
|
299
|
-
compilation.dependencyFactories.set(RemovedModuleDependency, normalModuleFactory)
|
|
300
|
-
compilation.dependencyTemplates.set(RemovedModuleDependency, new RemovedModuleDependency.Template())
|
|
301
|
-
|
|
302
|
-
// hack cacheGroup参数往addModule中传递当前module的issuer
|
|
303
|
-
const rawAddModuleDependencies = compilation.addModuleDependencies
|
|
304
|
-
compilation.addModuleDependencies = (
|
|
305
|
-
module,
|
|
306
|
-
dependencies,
|
|
307
|
-
bail,
|
|
308
|
-
cacheGroup,
|
|
309
|
-
recursive,
|
|
310
|
-
callback
|
|
311
|
-
) => {
|
|
312
|
-
const hackedCacheGroup = {
|
|
313
|
-
module,
|
|
314
|
-
cacheGroup
|
|
315
|
-
}
|
|
316
|
-
return rawAddModuleDependencies.call(
|
|
317
|
-
compilation,
|
|
318
|
-
module,
|
|
319
|
-
dependencies,
|
|
320
|
-
bail,
|
|
321
|
-
hackedCacheGroup,
|
|
322
|
-
recursive,
|
|
323
|
-
callback
|
|
324
|
-
)
|
|
325
|
-
}
|
|
480
|
+
compilation.dependencyFactories.set(AppEntryDependency, new NullFactory())
|
|
481
|
+
compilation.dependencyTemplates.set(AppEntryDependency, new AppEntryDependency.Template())
|
|
326
482
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
const rawAddModule = compilation.addModule
|
|
330
|
-
compilation.addModule = (module, cacheGroup) => {
|
|
331
|
-
let issuerResource
|
|
332
|
-
if (cacheGroup && cacheGroup.module) {
|
|
333
|
-
issuerResource = cacheGroup.module.resource
|
|
334
|
-
cacheGroup = cacheGroup.cacheGroup
|
|
335
|
-
}
|
|
336
|
-
// 避免context module报错
|
|
337
|
-
if (module.request && module.resource) {
|
|
338
|
-
const { queryObj, resourcePath } = parseRequest(module.resource)
|
|
339
|
-
let isStatic = queryObj.isStatic
|
|
340
|
-
if (module.loaders) {
|
|
341
|
-
module.loaders.forEach((loader) => {
|
|
342
|
-
if (/(url-loader|file-loader)/.test(loader.loader)) {
|
|
343
|
-
isStatic = true
|
|
344
|
-
}
|
|
345
|
-
})
|
|
346
|
-
}
|
|
347
|
-
const isIndependent = mpx.independentSubpackagesMap[mpx.currentPackageRoot]
|
|
483
|
+
compilation.dependencyFactories.set(DynamicEntryDependency, new NullFactory())
|
|
484
|
+
compilation.dependencyTemplates.set(DynamicEntryDependency, new DynamicEntryDependency.Template())
|
|
348
485
|
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
needPackageQuery = true
|
|
352
|
-
}
|
|
486
|
+
compilation.dependencyFactories.set(FlagPluginDependency, new NullFactory())
|
|
487
|
+
compilation.dependencyTemplates.set(FlagPluginDependency, new FlagPluginDependency.Template())
|
|
353
488
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
resource: module.resource,
|
|
357
|
-
resourceType: isStatic ? 'staticResources' : 'subpackageModules',
|
|
358
|
-
issuerResource,
|
|
359
|
-
warn (e) {
|
|
360
|
-
compilation.warnings.push(e)
|
|
361
|
-
},
|
|
362
|
-
error (e) {
|
|
363
|
-
compilation.errors.push(e)
|
|
364
|
-
}
|
|
365
|
-
})
|
|
366
|
-
const queryObj = {}
|
|
367
|
-
if (packageRoot) queryObj.packageRoot = packageRoot
|
|
368
|
-
// todo 后续可以考虑用module.layer来隔离独立分包的模块
|
|
369
|
-
if (isIndependent) queryObj.isIndependent = true
|
|
370
|
-
module.request = addQuery(module.request, queryObj)
|
|
371
|
-
module.resource = addQuery(module.resource, queryObj)
|
|
372
|
-
}
|
|
373
|
-
}
|
|
489
|
+
compilation.dependencyFactories.set(RemoveEntryDependency, new NullFactory())
|
|
490
|
+
compilation.dependencyTemplates.set(RemoveEntryDependency, new RemoveEntryDependency.Template())
|
|
374
491
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
492
|
+
compilation.dependencyFactories.set(RecordResourceMapDependency, new NullFactory())
|
|
493
|
+
compilation.dependencyTemplates.set(RecordResourceMapDependency, new RecordResourceMapDependency.Template())
|
|
494
|
+
|
|
495
|
+
compilation.dependencyFactories.set(RecordGlobalComponentsDependency, new NullFactory())
|
|
496
|
+
compilation.dependencyTemplates.set(RecordGlobalComponentsDependency, new RecordGlobalComponentsDependency.Template())
|
|
497
|
+
|
|
498
|
+
compilation.dependencyFactories.set(RecordIndependentDependency, new NullFactory())
|
|
499
|
+
compilation.dependencyTemplates.set(RecordIndependentDependency, new RecordIndependentDependency.Template())
|
|
500
|
+
|
|
501
|
+
compilation.dependencyFactories.set(CommonJsVariableDependency, normalModuleFactory)
|
|
502
|
+
compilation.dependencyTemplates.set(CommonJsVariableDependency, new CommonJsVariableDependency.Template())
|
|
503
|
+
|
|
504
|
+
compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
|
|
505
|
+
compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
|
|
387
506
|
})
|
|
388
507
|
|
|
389
508
|
compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
|
|
390
509
|
compilation.warnings = compilation.warnings.concat(warnings)
|
|
391
510
|
compilation.errors = compilation.errors.concat(errors)
|
|
392
|
-
|
|
393
|
-
const additionalAssets = {}
|
|
511
|
+
const moduleGraph = compilation.moduleGraph
|
|
394
512
|
if (!compilation.__mpx__) {
|
|
395
513
|
// init mpx
|
|
396
514
|
mpx = compilation.__mpx__ = {
|
|
515
|
+
// app信息,便于获取appName
|
|
516
|
+
appInfo: {},
|
|
397
517
|
// pages全局记录,无需区分主包分包
|
|
398
518
|
pagesMap: {},
|
|
399
|
-
//
|
|
400
|
-
pagesEntryMap: {},
|
|
401
|
-
// 组件资源记录,依照所属包进行记录,冗余存储,只要某个包有引用会添加对应记录,不管其会不会在当前包输出,这样设计主要是为了在resolve时能够以较低成本找到特定资源的输出路径
|
|
519
|
+
// 组件资源记录,依照所属包进行记录
|
|
402
520
|
componentsMap: {
|
|
403
521
|
main: {}
|
|
404
522
|
},
|
|
405
|
-
// 静态资源(图片,字体,独立样式)
|
|
523
|
+
// 静态资源(图片,字体,独立样式)等,依照所属包进行记录
|
|
406
524
|
staticResourcesMap: {
|
|
407
525
|
main: {}
|
|
408
526
|
},
|
|
409
|
-
// 用于记录命中subpackageModulesRules的js
|
|
527
|
+
// 用于记录命中subpackageModulesRules的js模块分包归属,用于js多分包冗余输出
|
|
410
528
|
subpackageModulesMap: {
|
|
411
529
|
main: {}
|
|
412
530
|
},
|
|
531
|
+
// 记录其他资源,如pluginMain、pluginExport,无需区分主包分包
|
|
532
|
+
otherResourcesMap: {},
|
|
413
533
|
// 记录独立分包
|
|
414
534
|
independentSubpackagesMap: {},
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
appScriptPromiseResolve: null,
|
|
419
|
-
// 记录entry依赖关系,用于体积分析
|
|
420
|
-
entryNodesMap: {},
|
|
535
|
+
subpackagesEntriesMap: {},
|
|
536
|
+
replacePathMap: {},
|
|
537
|
+
exportModules: new Set(),
|
|
421
538
|
// 记录entryModule与entryNode的对应关系,用于体积分析
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
539
|
+
entryNodeModulesMap: new Map(),
|
|
540
|
+
// 记录与asset相关联的modules,用于体积分析
|
|
541
|
+
assetsModulesMap: new Map(),
|
|
542
|
+
// 记录与asset相关联的ast,用于体积分析和esCheck,避免重复parse
|
|
543
|
+
assetsASTsMap: new Map(),
|
|
425
544
|
usingComponents: {},
|
|
426
|
-
hasApp: false,
|
|
427
545
|
// todo es6 map读写性能高于object,之后会逐步替换
|
|
428
546
|
vueContentCache: new Map(),
|
|
547
|
+
wxsAssetsCache: new Map(),
|
|
429
548
|
currentPackageRoot: '',
|
|
430
|
-
wxsMap: {},
|
|
431
549
|
wxsContentMap: {},
|
|
432
|
-
assetsInfo: new Map(),
|
|
433
|
-
forceDisableInject: this.options.forceDisableInject,
|
|
434
550
|
forceUsePageCtor: this.options.forceUsePageCtor,
|
|
435
551
|
resolveMode: this.options.resolveMode,
|
|
436
552
|
mode: this.options.mode,
|
|
437
553
|
srcMode: this.options.srcMode,
|
|
438
554
|
env: this.options.env,
|
|
439
|
-
// deprecated option
|
|
440
|
-
globalMpxAttrsFilter: this.options.globalMpxAttrsFilter,
|
|
441
555
|
externalClasses: this.options.externalClasses,
|
|
442
556
|
projectRoot: this.options.projectRoot,
|
|
443
557
|
autoScopeRules: this.options.autoScopeRules,
|
|
444
558
|
autoVirtualHostRules: this.options.autoVirtualHostRules,
|
|
445
559
|
transRpxRules: this.options.transRpxRules,
|
|
446
|
-
webConfig: this.options.webConfig,
|
|
447
560
|
postcssInlineConfig: this.options.postcssInlineConfig,
|
|
448
561
|
decodeHTMLText: this.options.decodeHTMLText,
|
|
449
|
-
// native
|
|
450
|
-
|
|
562
|
+
// native文件专用配置
|
|
563
|
+
nativeConfig: this.options.nativeConfig,
|
|
564
|
+
// 输出web专用配置
|
|
565
|
+
webConfig: this.options.webConfig,
|
|
451
566
|
tabBarMap: {},
|
|
452
567
|
defs: preProcessDefs(this.options.defs),
|
|
453
568
|
i18n: this.options.i18n,
|
|
@@ -459,76 +574,121 @@ class MpxWebpackPlugin {
|
|
|
459
574
|
useRelativePath: this.options.useRelativePath,
|
|
460
575
|
removedChunks: [],
|
|
461
576
|
forceProxyEventRules: this.options.forceProxyEventRules,
|
|
462
|
-
|
|
463
|
-
const entryNodesMap = mpx.entryNodesMap
|
|
464
|
-
const entryModulesMap = mpx.entryModulesMap
|
|
465
|
-
if (!entryNodesMap[request]) {
|
|
466
|
-
entryNodesMap[request] = new EntryNode({
|
|
467
|
-
type,
|
|
468
|
-
request
|
|
469
|
-
})
|
|
470
|
-
}
|
|
471
|
-
const currentEntry = entryNodesMap[request]
|
|
472
|
-
if (currentEntry.type !== type) {
|
|
473
|
-
compilation.errors.push(`获取request为${request}的entryNode时类型与已有节点冲突, 当前获取的type为${type}, 已有节点的type为${currentEntry.type}!`)
|
|
474
|
-
}
|
|
475
|
-
if (module) {
|
|
476
|
-
currentEntry.module = module
|
|
477
|
-
entryModulesMap.set(module, currentEntry)
|
|
478
|
-
}
|
|
479
|
-
return currentEntry
|
|
480
|
-
},
|
|
577
|
+
proxyComponentEventsRules: this.options.proxyComponentEventsRules,
|
|
481
578
|
pathHash: (resourcePath) => {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
const projectRoot = this.options.projectRoot || ''
|
|
485
|
-
if (pathHashMode === 'relative') {
|
|
486
|
-
hashPath = path.relative(projectRoot, resourcePath)
|
|
579
|
+
if (this.options.pathHashMode === 'relative' && this.options.projectRoot) {
|
|
580
|
+
return hash(path.relative(this.options.projectRoot, resourcePath))
|
|
487
581
|
}
|
|
488
|
-
|
|
489
|
-
|
|
582
|
+
return hash(resourcePath)
|
|
583
|
+
},
|
|
584
|
+
addEntry (request, name, callback) {
|
|
585
|
+
const dep = EntryPlugin.createDependency(request, { name })
|
|
586
|
+
compilation.addEntry(compiler.context, dep, { name }, callback)
|
|
587
|
+
return dep
|
|
588
|
+
},
|
|
589
|
+
getEntryNode: (module, type) => {
|
|
590
|
+
const entryNodeModulesMap = mpx.entryNodeModulesMap
|
|
591
|
+
let entryNode = entryNodeModulesMap.get(module)
|
|
592
|
+
if (!entryNode) {
|
|
593
|
+
entryNode = new EntryNode(module, type)
|
|
594
|
+
entryNodeModulesMap.set(module, entryNode)
|
|
490
595
|
}
|
|
491
|
-
return
|
|
596
|
+
return entryNode
|
|
492
597
|
},
|
|
493
598
|
getOutputPath: (resourcePath, type, { ext = '', conflictPath = '' } = {}) => {
|
|
494
599
|
const name = path.parse(resourcePath).name
|
|
495
600
|
const hash = mpx.pathHash(resourcePath)
|
|
496
601
|
const customOutputPath = this.options.customOutputPath
|
|
497
602
|
if (conflictPath) return conflictPath.replace(/(\.[^\\/]+)?$/, match => hash + match)
|
|
498
|
-
if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext)
|
|
603
|
+
if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext).replace(/^\//, '')
|
|
499
604
|
if (type === 'component' || type === 'page') return path.join(type + 's', name + hash, 'index' + ext)
|
|
500
605
|
return path.join(type, name + hash + ext)
|
|
501
606
|
},
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
if (
|
|
506
|
-
|
|
607
|
+
extractedFilesCache: new Map(),
|
|
608
|
+
getExtractedFile: (resource, { error } = {}) => {
|
|
609
|
+
const cache = mpx.extractedFilesCache.get(resource)
|
|
610
|
+
if (cache) return cache
|
|
611
|
+
const { resourcePath, queryObj } = parseRequest(resource)
|
|
612
|
+
const { type, isStatic, isPlugin } = queryObj
|
|
613
|
+
let file
|
|
614
|
+
if (isPlugin) {
|
|
615
|
+
file = 'plugin.json'
|
|
616
|
+
} else if (isStatic) {
|
|
617
|
+
const packageRoot = queryObj.packageRoot || ''
|
|
618
|
+
file = toPosix(path.join(packageRoot, mpx.getOutputPath(resourcePath, type, { ext: typeExtMap[type] })))
|
|
619
|
+
} else {
|
|
620
|
+
const appInfo = mpx.appInfo
|
|
621
|
+
const pagesMap = mpx.pagesMap
|
|
622
|
+
const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
|
|
623
|
+
const componentsMap = mpx.componentsMap[packageName]
|
|
624
|
+
let filename = resourcePath === appInfo.resourcePath ? appInfo.name : (pagesMap[resourcePath] || componentsMap[resourcePath])
|
|
625
|
+
if (!filename) {
|
|
626
|
+
error && error(new Error('Get extracted file error: missing filename!'))
|
|
627
|
+
filename = 'missing-filename'
|
|
628
|
+
}
|
|
629
|
+
file = filename + typeExtMap[type]
|
|
630
|
+
}
|
|
631
|
+
mpx.extractedFilesCache.set(resource, file)
|
|
632
|
+
return file
|
|
633
|
+
},
|
|
634
|
+
recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', recordOnly, warn, error }) => {
|
|
635
|
+
const packageName = packageRoot || 'main'
|
|
636
|
+
const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
|
|
637
|
+
const currentResourceMap = resourceMap.main ? resourceMap[packageName] = resourceMap[packageName] || {} : resourceMap
|
|
638
|
+
let alreadyOutputted = false
|
|
639
|
+
if (outputPath) {
|
|
640
|
+
if (!currentResourceMap[resourcePath] || currentResourceMap[resourcePath] === true) {
|
|
641
|
+
if (!recordOnly) {
|
|
642
|
+
// 在非recordOnly的模式下,进行输出路径冲突检测,如果存在输出路径冲突,则对输出路径进行重命名
|
|
643
|
+
for (let key in currentResourceMap) {
|
|
644
|
+
// todo 用outputPathMap来检测输出路径冲突
|
|
645
|
+
if (currentResourceMap[key] === outputPath && key !== resourcePath) {
|
|
646
|
+
outputPath = mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })
|
|
647
|
+
warn && warn(new Error(`Current ${resourceType} [${resourcePath}] is registered with conflicted outputPath [${currentResourceMap[key]}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
|
|
648
|
+
break
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
currentResourceMap[resourcePath] = outputPath
|
|
653
|
+
} else {
|
|
654
|
+
if (currentResourceMap[resourcePath] === outputPath) {
|
|
655
|
+
alreadyOutputted = true
|
|
656
|
+
} else {
|
|
657
|
+
error && error(new Error(`Current ${resourceType} [${resourcePath}] is already registered with outputPath [${currentResourceMap[resourcePath]}], you can not register it with another outputPath [${outputPath}]!`))
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
} else if (!currentResourceMap[resourcePath]) {
|
|
661
|
+
currentResourceMap[resourcePath] = true
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
return {
|
|
665
|
+
outputPath,
|
|
666
|
+
alreadyOutputted
|
|
507
667
|
}
|
|
508
|
-
sideEffects && sideEffects.forEach((sideEffect) => {
|
|
509
|
-
sideEffect(additionalAssets)
|
|
510
|
-
})
|
|
511
668
|
},
|
|
512
669
|
// 组件和静态资源的输出规则如下:
|
|
513
670
|
// 1. 主包引用的资源输出至主包
|
|
514
671
|
// 2. 分包引用且主包引用过的资源输出至主包,不在当前分包重复输出
|
|
515
672
|
// 3. 分包引用且无其他包引用的资源输出至当前分包
|
|
516
673
|
// 4. 分包引用且其他分包也引用过的资源,重复输出至当前分包
|
|
517
|
-
getPackageInfo: ({ resource,
|
|
674
|
+
getPackageInfo: ({ resource, resourceType, outputPath, issuerResource, warn, error }) => {
|
|
518
675
|
let packageRoot = ''
|
|
519
676
|
let packageName = 'main'
|
|
520
|
-
|
|
521
|
-
const {
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
677
|
+
|
|
678
|
+
const { resourcePath } = parseRequest(resource)
|
|
679
|
+
const currentPackageRoot = mpx.currentPackageRoot
|
|
680
|
+
const currentPackageName = currentPackageRoot || 'main'
|
|
681
|
+
const isIndependent = !!mpx.independentSubpackagesMap[currentPackageRoot]
|
|
682
|
+
const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
|
|
683
|
+
|
|
684
|
+
if (!resourceMap.main) {
|
|
685
|
+
packageRoot = currentPackageRoot
|
|
686
|
+
packageName = currentPackageName
|
|
525
687
|
} else {
|
|
526
|
-
const currentPackageRoot = mpx.currentPackageRoot
|
|
527
|
-
const currentPackageName = currentPackageRoot || 'main'
|
|
528
|
-
const isIndependent = mpx.independentSubpackagesMap[currentPackageRoot]
|
|
529
688
|
// 主包中有引用一律使用主包中资源,不再额外输出
|
|
530
689
|
// 资源路径匹配到forceMainPackageRules规则时强制输出到主包,降低分包资源冗余
|
|
531
690
|
// 如果存在issuer且issuerPackageRoot与当前packageRoot不一致,也输出到主包
|
|
691
|
+
// todo forceMainPackageRules规则目前只能处理当前资源,不能处理资源子树,配置不当有可能会导致资源引用错误
|
|
532
692
|
let isMain = resourceMap.main[resourcePath] || matchCondition(resourcePath, this.options.forceMainPackageRules)
|
|
533
693
|
if (issuerResource) {
|
|
534
694
|
const { queryObj } = parseRequest(issuerResource)
|
|
@@ -538,50 +698,36 @@ class MpxWebpackPlugin {
|
|
|
538
698
|
isMain = true
|
|
539
699
|
}
|
|
540
700
|
}
|
|
541
|
-
// todo forceMainPackageRules规则目前只能处理当前资源,不能处理资源子树,配置不当有可能会导致资源引用错误
|
|
542
701
|
if (!isMain || isIndependent) {
|
|
543
702
|
packageRoot = currentPackageRoot
|
|
544
703
|
packageName = currentPackageName
|
|
545
|
-
if (this.options.auditResource && resourceType !== '
|
|
546
|
-
if (this.options.auditResource !== 'component' || resourceType === '
|
|
704
|
+
if (this.options.auditResource && resourceType !== 'subpackageModule' && !isIndependent) {
|
|
705
|
+
if (this.options.auditResource !== 'component' || resourceType === 'component') {
|
|
547
706
|
Object.keys(resourceMap).filter(key => key !== 'main').forEach((key) => {
|
|
548
707
|
if (resourceMap[key][resourcePath] && key !== packageName) {
|
|
549
|
-
warn && warn(new Error(`当前${resourceType === '
|
|
708
|
+
warn && warn(new Error(`当前${resourceType === 'component' ? '组件' : '静态'}资源${resourcePath}在分包${key}和分包${packageName}中都有引用,会分别输出到两个分包中,为了总体积最优,可以在主包中建立引用声明以消除资源输出冗余!`))
|
|
550
709
|
}
|
|
551
710
|
})
|
|
552
711
|
}
|
|
553
712
|
}
|
|
554
713
|
}
|
|
714
|
+
resourceMap[packageName] = resourceMap[packageName] || {}
|
|
555
715
|
}
|
|
556
716
|
|
|
557
|
-
|
|
558
|
-
const currentResourceMap = resourceMap[packageName]
|
|
559
|
-
|
|
560
|
-
let alreadyOutputed = false
|
|
561
|
-
if (outputPath) {
|
|
562
|
-
outputPath = toPosix(path.join(packageRoot, outputPath))
|
|
563
|
-
// 如果之前已经进行过输出,则不需要重复进行
|
|
564
|
-
if (currentResourceMap[resourcePath] === outputPath) {
|
|
565
|
-
alreadyOutputed = true
|
|
566
|
-
} else {
|
|
567
|
-
for (let key in currentResourceMap) {
|
|
568
|
-
if (currentResourceMap[key] === outputPath && key !== resourcePath) {
|
|
569
|
-
outputPath = toPosix(path.join(packageRoot, mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })))
|
|
570
|
-
warn && warn(new Error(`Current ${resourceType} [${resourcePath}] is registered with a conflict outputPath [${currentResourceMap[key]}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
|
|
571
|
-
break
|
|
572
|
-
}
|
|
573
|
-
}
|
|
574
|
-
currentResourceMap[resourcePath] = outputPath
|
|
575
|
-
}
|
|
576
|
-
} else if (!currentResourceMap[resourcePath]) {
|
|
577
|
-
currentResourceMap[resourcePath] = true
|
|
578
|
-
}
|
|
717
|
+
if (outputPath) outputPath = toPosix(path.join(packageRoot, outputPath))
|
|
579
718
|
|
|
580
719
|
return {
|
|
581
720
|
packageName,
|
|
582
721
|
packageRoot,
|
|
583
|
-
outputPath
|
|
584
|
-
|
|
722
|
+
// 返回outputPath及alreadyOutputted
|
|
723
|
+
...mpx.recordResourceMap({
|
|
724
|
+
resourcePath,
|
|
725
|
+
resourceType,
|
|
726
|
+
outputPath,
|
|
727
|
+
packageRoot,
|
|
728
|
+
warn,
|
|
729
|
+
error
|
|
730
|
+
})
|
|
585
731
|
}
|
|
586
732
|
}
|
|
587
733
|
}
|
|
@@ -589,18 +735,110 @@ class MpxWebpackPlugin {
|
|
|
589
735
|
|
|
590
736
|
const rawProcessModuleDependencies = compilation.processModuleDependencies
|
|
591
737
|
compilation.processModuleDependencies = (module, callback) => {
|
|
738
|
+
const presentationalDependencies = module.presentationalDependencies || []
|
|
739
|
+
async.forEach(presentationalDependencies.filter((dep) => dep.mpxAction), (dep, callback) => {
|
|
740
|
+
dep.mpxAction(module, compilation, callback)
|
|
741
|
+
}, (err) => {
|
|
742
|
+
rawProcessModuleDependencies.call(compilation, module, (innerErr) => {
|
|
743
|
+
return callback(err || innerErr)
|
|
744
|
+
})
|
|
745
|
+
})
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
const rawFactorizeModule = compilation.factorizeModule
|
|
749
|
+
compilation.factorizeModule = (options, callback) => {
|
|
750
|
+
const originModule = options.originModule
|
|
592
751
|
let proxyedCallback = callback
|
|
593
|
-
if (
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
752
|
+
if (originModule) {
|
|
753
|
+
proxyedCallback = (err, module) => {
|
|
754
|
+
// 避免selfModuleFactory的情况
|
|
755
|
+
if (module && module !== originModule) {
|
|
756
|
+
module.issuerResource = originModule.resource
|
|
757
|
+
}
|
|
758
|
+
return callback(err, module)
|
|
599
759
|
}
|
|
600
760
|
}
|
|
601
|
-
return
|
|
761
|
+
return rawFactorizeModule.call(compilation, options, proxyedCallback)
|
|
602
762
|
}
|
|
603
763
|
|
|
764
|
+
// 处理watch时缓存模块中的buildInfo
|
|
765
|
+
// 在调用addModule前对module添加分包信息,以控制分包输出及消除缓存,该操作由afterResolve钩子迁移至此是由于dependencyCache的存在,watch状态下afterResolve钩子并不会对所有模块执行,而模块的packageName在watch过程中是可能发生变更的,如新增删除一个分包资源的主包引用
|
|
766
|
+
const rawAddModule = compilation.addModule
|
|
767
|
+
compilation.addModule = (module, callback) => {
|
|
768
|
+
const issuerResource = module.issuerResource
|
|
769
|
+
const currentPackageRoot = mpx.currentPackageRoot
|
|
770
|
+
const independent = mpx.independentSubpackagesMap[currentPackageRoot]
|
|
771
|
+
|
|
772
|
+
if (module.resource) {
|
|
773
|
+
// NormalModule
|
|
774
|
+
const isStatic = isStaticModule(module)
|
|
775
|
+
|
|
776
|
+
let needPackageQuery = isStatic || independent
|
|
777
|
+
|
|
778
|
+
if (!needPackageQuery) {
|
|
779
|
+
const { resourcePath } = parseRequest(module.resource)
|
|
780
|
+
needPackageQuery = matchCondition(resourcePath, this.options.subpackageModulesRules)
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (needPackageQuery) {
|
|
784
|
+
const { packageRoot } = mpx.getPackageInfo({
|
|
785
|
+
resource: module.resource,
|
|
786
|
+
resourceType: isStatic ? 'staticResource' : 'subpackageModule',
|
|
787
|
+
issuerResource,
|
|
788
|
+
warn (e) {
|
|
789
|
+
compilation.warnings.push(e)
|
|
790
|
+
},
|
|
791
|
+
error (e) {
|
|
792
|
+
compilation.errors.push(e)
|
|
793
|
+
}
|
|
794
|
+
})
|
|
795
|
+
if (packageRoot) {
|
|
796
|
+
const queryObj = {
|
|
797
|
+
packageRoot
|
|
798
|
+
}
|
|
799
|
+
if (independent) queryObj.independent = independent
|
|
800
|
+
module.request = addQuery(module.request, queryObj)
|
|
801
|
+
module.resource = addQuery(module.resource, queryObj)
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
} else if (independent) {
|
|
805
|
+
// ContextModule/RawModule/ExternalModule等只在独立分包的情况下添加分包标记,其余默认不添加
|
|
806
|
+
const hackModuleIdentifier = (module) => {
|
|
807
|
+
const postfix = `|independent=${independent}|${currentPackageRoot}`
|
|
808
|
+
const rawIdentifier = module.identifier
|
|
809
|
+
if (rawIdentifier && !rawIdentifier.__mpxHacked) {
|
|
810
|
+
module.identifier = () => {
|
|
811
|
+
return rawIdentifier.call(module) + postfix
|
|
812
|
+
}
|
|
813
|
+
module.identifier.__mpxHacked = true
|
|
814
|
+
}
|
|
815
|
+
}
|
|
816
|
+
hackModuleIdentifier(module)
|
|
817
|
+
const rawCallback = callback
|
|
818
|
+
callback = (err, module) => {
|
|
819
|
+
// 因为文件缓存的存在,前面hack identifier的行为对于从文件缓存中创建得到的module并不生效,因此需要在回调中进行二次hack处理
|
|
820
|
+
if (err) return rawCallback(err)
|
|
821
|
+
hackModuleIdentifier(module)
|
|
822
|
+
rawCallback(null, module)
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
return rawAddModule.call(compilation, module, callback)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
const rawEmitAsset = compilation.emitAsset
|
|
829
|
+
|
|
830
|
+
compilation.emitAsset = (file, source, assetInfo) => {
|
|
831
|
+
if (assetInfo && assetInfo.skipEmit) return
|
|
832
|
+
return rawEmitAsset.call(compilation, file, source, assetInfo)
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
compilation.hooks.succeedModule.tap('MpxWebpackPlugin', (module) => {
|
|
836
|
+
// 静态资源模块由于输出结果的动态性,通过importModule会合并asset的特性,通过emitFile传递信息禁用父级extractor的缓存来保障父级的importModule每次都能被执行
|
|
837
|
+
if (isStaticModule(module)) {
|
|
838
|
+
emitFile(module, MPX_DISABLE_EXTRACTOR_CACHE, '', undefined, { skipEmit: true })
|
|
839
|
+
}
|
|
840
|
+
})
|
|
841
|
+
|
|
604
842
|
compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
|
|
605
843
|
// 自动跟进分包配置修改splitChunksPlugin配置
|
|
606
844
|
if (splitChunksPlugin) {
|
|
@@ -612,45 +850,15 @@ class MpxWebpackPlugin {
|
|
|
612
850
|
}
|
|
613
851
|
})
|
|
614
852
|
if (needInit) {
|
|
615
|
-
splitChunksPlugin.options = SplitChunksPlugin
|
|
853
|
+
splitChunksPlugin.options = new SplitChunksPlugin(splitChunksOptions).options
|
|
616
854
|
}
|
|
617
855
|
}
|
|
618
856
|
})
|
|
619
857
|
|
|
620
|
-
compilation.
|
|
621
|
-
modules.forEach((module) => {
|
|
622
|
-
if (module.needRemove) {
|
|
623
|
-
let removed = false
|
|
624
|
-
module.reasons.forEach((reason) => {
|
|
625
|
-
if (reason.module) {
|
|
626
|
-
if (reason.dependency instanceof HarmonyImportSideEffectDependency) {
|
|
627
|
-
reason.module.removeDependency(reason.dependency)
|
|
628
|
-
reason.module.addDependency(new RemovedModuleDependency(reason.dependency.request, module))
|
|
629
|
-
removed = true
|
|
630
|
-
} else if (reason.dependency instanceof CommonJsRequireDependency && reason.dependency.loc.range) {
|
|
631
|
-
let index = reason.module.dependencies.indexOf(reason.dependency)
|
|
632
|
-
if (index > -1 && reason.module.dependencies[index + 1] instanceof RequireHeaderDependency) {
|
|
633
|
-
reason.module.dependencies.splice(index, 2)
|
|
634
|
-
reason.module.addDependency(new RemovedModuleDependency(reason.dependency.request, module, reason.dependency.loc.range))
|
|
635
|
-
removed = true
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
})
|
|
640
|
-
if (removed) {
|
|
641
|
-
module.chunksIterable.forEach((chunk) => {
|
|
642
|
-
module.removeChunk(chunk)
|
|
643
|
-
})
|
|
644
|
-
module.disconnect()
|
|
645
|
-
}
|
|
646
|
-
}
|
|
647
|
-
})
|
|
648
|
-
})
|
|
649
|
-
|
|
650
|
-
compilation.moduleTemplates.javascript.hooks.content.tap('MpxWebpackPlugin', (source, module, options) => {
|
|
858
|
+
JavascriptModulesPlugin.getCompilationHooks(compilation).renderModuleContent.tap('MpxWebpackPlugin', (source, module, renderContext) => {
|
|
651
859
|
// 处理dll产生的external模块
|
|
652
860
|
if (module.external && module.userRequest.startsWith('dll-reference ') && mpx.mode !== 'web') {
|
|
653
|
-
const chunk =
|
|
861
|
+
const chunk = renderContext.chunk
|
|
654
862
|
const request = module.request
|
|
655
863
|
let relativePath = toPosix(path.relative(path.dirname(chunk.name), request))
|
|
656
864
|
if (!/^\.\.?\//.test(relativePath)) relativePath = './' + relativePath
|
|
@@ -661,133 +869,141 @@ class MpxWebpackPlugin {
|
|
|
661
869
|
return source
|
|
662
870
|
})
|
|
663
871
|
|
|
664
|
-
compilation.
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
}
|
|
672
|
-
additionalAssets[file].forEach((item) => {
|
|
673
|
-
if (item) content.add(item)
|
|
674
|
-
})
|
|
675
|
-
const modules = (additionalAssets[file].modules || []).concat(additionalAssets[file].relativeModules || [])
|
|
872
|
+
JavascriptModulesPlugin.getCompilationHooks(compilation).renderStartup.tap('MpxWebpackPlugin', (source, module) => {
|
|
873
|
+
if (module && mpx.exportModules.has(module)) {
|
|
874
|
+
source = new ConcatSource(source)
|
|
875
|
+
source.add('module.exports = __webpack_exports__;\n')
|
|
876
|
+
}
|
|
877
|
+
return source
|
|
878
|
+
})
|
|
676
879
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
880
|
+
compilation.hooks.moduleAsset.tap('MpxWebpackPlugin', (module, filename) => {
|
|
881
|
+
const modules = mpx.assetsModulesMap.get(filename) || new Set()
|
|
882
|
+
modules.add(module)
|
|
883
|
+
mpx.assetsModulesMap.set(filename, modules)
|
|
884
|
+
})
|
|
681
885
|
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
module.buildInfo.fileDependencies = fileDependencies
|
|
690
|
-
module.buildInfo.contextDependencies = contextDependencies
|
|
691
|
-
})
|
|
886
|
+
const fillExtractedAssetsMap = (assetsMap, { index, content }, filename) => {
|
|
887
|
+
if (assetsMap.has(index)) {
|
|
888
|
+
if (assetsMap.get(index) !== content) {
|
|
889
|
+
compilation.errors.push(new Error(`The extracted file [${filename}] is filled with same index [${index}] and different content:
|
|
890
|
+
old content: ${assetsMap.get(index)}
|
|
891
|
+
new content: ${content}
|
|
892
|
+
please check!`))
|
|
692
893
|
}
|
|
693
|
-
|
|
894
|
+
} else {
|
|
895
|
+
assetsMap.set(index, content)
|
|
694
896
|
}
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
const sortExtractedAssetsMap = (assetsMap) => {
|
|
900
|
+
return [...assetsMap.entries()].sort((a, b) => a[0] - b[0]).map(item => item[1])
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
compilation.hooks.beforeModuleAssets.tap('MpxWebpackPlugin', () => {
|
|
904
|
+
const extractedAssetsMap = new Map()
|
|
905
|
+
for (const module of compilation.modules) {
|
|
906
|
+
const assetsInfo = module.buildInfo.assetsInfo || new Map()
|
|
907
|
+
for (const [filename, { extractedInfo } = {}] of assetsInfo) {
|
|
908
|
+
if (extractedInfo) {
|
|
909
|
+
let extractedAssets = extractedAssetsMap.get(filename)
|
|
910
|
+
if (!extractedAssets) {
|
|
911
|
+
extractedAssets = [new Map(), new Map()]
|
|
912
|
+
extractedAssetsMap.set(filename, extractedAssets)
|
|
913
|
+
}
|
|
914
|
+
fillExtractedAssetsMap(extractedInfo.pre ? extractedAssets[0] : extractedAssets[1], extractedInfo, filename)
|
|
915
|
+
compilation.hooks.moduleAsset.call(module, filename)
|
|
916
|
+
}
|
|
700
917
|
}
|
|
701
|
-
|
|
702
|
-
})
|
|
703
|
-
// 链接主编译模块与子编译入口
|
|
704
|
-
Object.values(mpx.wxsMap).concat(Object.values(mpx.extractedMap)).forEach((item) => {
|
|
705
|
-
item.modules.forEach((module) => {
|
|
706
|
-
module.addDependency(item.dep)
|
|
707
|
-
})
|
|
708
|
-
})
|
|
918
|
+
}
|
|
709
919
|
|
|
710
|
-
|
|
920
|
+
for (const [filename, [pre, normal]] of extractedAssetsMap) {
|
|
921
|
+
const sortedExtractedAssets = [...sortExtractedAssetsMap(pre), ...sortExtractedAssetsMap(normal)]
|
|
922
|
+
const source = new ConcatSource()
|
|
923
|
+
sortedExtractedAssets.forEach((content) => {
|
|
924
|
+
if (content) {
|
|
925
|
+
// 处理replace path
|
|
926
|
+
if (/"mpx_replace_path_.*?"/.test(content)) {
|
|
927
|
+
content = content.replace(/"mpx_replace_path_(.*?)"/g, (matched, key) => {
|
|
928
|
+
return JSON.stringify(mpx.replacePathMap[key] || 'missing replace path')
|
|
929
|
+
})
|
|
930
|
+
}
|
|
931
|
+
source.add(content)
|
|
932
|
+
}
|
|
933
|
+
})
|
|
934
|
+
compilation.emitAsset(filename, source)
|
|
935
|
+
}
|
|
711
936
|
})
|
|
712
937
|
|
|
713
938
|
normalModuleFactory.hooks.parser.for('javascript/auto').tap('MpxWebpackPlugin', (parser) => {
|
|
714
|
-
// hack预处理,将expr.range写入loc中便于在CommonJsRequireDependency中获取,移除无效require
|
|
715
|
-
parser.hooks.call.for('require').tap({ name: 'MpxWebpackPlugin', stage: -100 }, (expr) => {
|
|
716
|
-
expr.loc.range = expr.range
|
|
717
|
-
})
|
|
718
|
-
|
|
719
939
|
parser.hooks.call.for('__mpx_resolve_path__').tap('MpxWebpackPlugin', (expr) => {
|
|
720
940
|
if (expr.arguments[0]) {
|
|
721
941
|
const resource = expr.arguments[0].value
|
|
722
|
-
const
|
|
723
|
-
const
|
|
724
|
-
const pagesMap = mpx.pagesMap
|
|
725
|
-
const componentsMap = mpx.componentsMap
|
|
726
|
-
const staticResourcesMap = mpx.staticResourcesMap
|
|
942
|
+
const packageName = mpx.currentPackageRoot || 'main'
|
|
943
|
+
const issuerResource = moduleGraph.getIssuer(parser.state.module).resource
|
|
727
944
|
const range = expr.range
|
|
728
|
-
const
|
|
729
|
-
|
|
730
|
-
parser.state.current.addDependency(dep)
|
|
945
|
+
const dep = new ResolveDependency(resource, packageName, issuerResource, range)
|
|
946
|
+
parser.state.current.addPresentationalDependency(dep)
|
|
731
947
|
return true
|
|
732
948
|
}
|
|
733
949
|
})
|
|
734
950
|
|
|
735
|
-
|
|
736
|
-
const
|
|
737
|
-
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
const mode = mpx.mode
|
|
743
|
-
|
|
744
|
-
let target
|
|
745
|
-
|
|
746
|
-
if (expr.type === 'Identifier') {
|
|
747
|
-
target = expr
|
|
748
|
-
} else if (expr.type === 'MemberExpression') {
|
|
749
|
-
target = expr.object
|
|
750
|
-
}
|
|
751
|
-
if (!matchCondition(resourcePath, this.options.transMpxRules) || resourcePath.indexOf('@mpxjs') !== -1 || !target || mode === srcMode) {
|
|
752
|
-
return
|
|
753
|
-
}
|
|
754
|
-
|
|
755
|
-
const type = target.name
|
|
756
|
-
|
|
757
|
-
const name = type === 'wx' ? 'mpx' : 'createFactory'
|
|
758
|
-
const replaceContent = type === 'wx' ? '__webpack_require__.n(mpx)()' : `__webpack_require__.n(createFactory)()(${JSON.stringify(type)})`
|
|
759
|
-
|
|
760
|
-
const dep = new ReplaceDependency(replaceContent, target.range)
|
|
761
|
-
current.addDependency(dep)
|
|
951
|
+
parser.hooks.call.for('__mpx_dynamic_entry__').tap('MpxWebpackPlugin', (expr) => {
|
|
952
|
+
const args = expr.arguments.map((i) => i.value)
|
|
953
|
+
args.push(expr.range)
|
|
954
|
+
const dep = new DynamicEntryDependency(...args)
|
|
955
|
+
parser.state.current.addPresentationalDependency(dep)
|
|
956
|
+
return true
|
|
957
|
+
})
|
|
762
958
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
959
|
+
const requireAsyncHandler = (expr, members) => {
|
|
960
|
+
if (members[0] === 'async') {
|
|
961
|
+
let request = expr.arguments[0].value
|
|
962
|
+
const range = expr.arguments[0].range
|
|
963
|
+
const context = parser.state.module.context
|
|
964
|
+
const { queryObj } = parseRequest(request)
|
|
965
|
+
if (queryObj.root) {
|
|
966
|
+
// 删除root query
|
|
967
|
+
request = addQuery(request, {}, false, ['root'])
|
|
968
|
+
// 目前仅wx支持require.async,其余平台使用CommonJsAsyncDependency进行模拟抹平
|
|
969
|
+
if (mpx.mode === 'wx') {
|
|
970
|
+
const dep = new DynamicEntryDependency(request, 'export', '', queryObj.root, MPX_CURRENT_CHUNK, context, range)
|
|
971
|
+
parser.state.current.addPresentationalDependency(dep)
|
|
972
|
+
// 包含require.async的模块不能被concatenate,避免DynamicEntryDependency中无法获取模块chunk以计算相对路径
|
|
973
|
+
parser.state.module.buildInfo.moduleConcatenationBailout = 'require async'
|
|
974
|
+
} else {
|
|
975
|
+
const range = expr.range
|
|
976
|
+
const dep = new CommonJsAsyncDependency(request, range)
|
|
977
|
+
parser.state.current.addDependency(dep)
|
|
978
|
+
}
|
|
979
|
+
return true
|
|
980
|
+
} else {
|
|
981
|
+
compilation.errors.push(new Error(`The require async JS [${request}] need to declare subpackage name by root`))
|
|
982
|
+
return true
|
|
768
983
|
}
|
|
769
984
|
}
|
|
770
|
-
if (needInject) {
|
|
771
|
-
const expression = `require(${JSON.stringify(`@mpxjs/core/src/runtime/${name}`)})`
|
|
772
|
-
const deps = []
|
|
773
|
-
parser.parse(expression, {
|
|
774
|
-
current: {
|
|
775
|
-
addDependency: dep => {
|
|
776
|
-
dep.userRequest = name
|
|
777
|
-
deps.push(dep)
|
|
778
|
-
}
|
|
779
|
-
},
|
|
780
|
-
module
|
|
781
|
-
})
|
|
782
|
-
module.addVariable(name, expression, deps)
|
|
783
|
-
}
|
|
784
985
|
}
|
|
986
|
+
|
|
987
|
+
parser.hooks.callMemberChain
|
|
988
|
+
.for('require')
|
|
989
|
+
.tap({
|
|
990
|
+
name: 'MpxWebpackPlugin',
|
|
991
|
+
stage: -1000
|
|
992
|
+
}, (expr, members) => requireAsyncHandler(expr, members))
|
|
993
|
+
|
|
994
|
+
parser.hooks.callMemberChainOfCallMemberChain
|
|
995
|
+
.for('require')
|
|
996
|
+
.tap({
|
|
997
|
+
name: 'MpxWebpackPlugin',
|
|
998
|
+
stage: -1000
|
|
999
|
+
}, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers))
|
|
1000
|
+
|
|
785
1001
|
// hack babel polyfill global
|
|
786
1002
|
parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
|
|
787
1003
|
if (/core-js.+microtask/.test(parser.state.module.resource)) {
|
|
788
1004
|
if (expr.test.left && (expr.test.left.name === 'Observer' || expr.test.left.name === 'MutationObserver')) {
|
|
789
1005
|
const current = parser.state.current
|
|
790
|
-
current.
|
|
1006
|
+
current.addPresentationalDependency(new InjectDependency({
|
|
791
1007
|
content: 'document && ',
|
|
792
1008
|
index: expr.test.range[0]
|
|
793
1009
|
}))
|
|
@@ -803,7 +1019,7 @@ class MpxWebpackPlugin {
|
|
|
803
1019
|
// todo 该逻辑在corejs3中不需要,等corejs3比较普及之后可以干掉
|
|
804
1020
|
if (/core-js.+global/.test(parser.state.module.resource)) {
|
|
805
1021
|
if (callee.name === 'Function' && arg0 && arg0.value === 'return this') {
|
|
806
|
-
current.
|
|
1022
|
+
current.addPresentationalDependency(new InjectDependency({
|
|
807
1023
|
content: '(function() { return this })() || ',
|
|
808
1024
|
index: expr.range[0]
|
|
809
1025
|
}))
|
|
@@ -811,102 +1027,169 @@ class MpxWebpackPlugin {
|
|
|
811
1027
|
}
|
|
812
1028
|
if (/regenerator-runtime/.test(parser.state.module.resource)) {
|
|
813
1029
|
if (callee.name === 'Function' && arg0 && arg0.value === 'r' && arg1 && arg1.value === 'regeneratorRuntime = r') {
|
|
814
|
-
current.
|
|
1030
|
+
current.addPresentationalDependency(new ReplaceDependency('(function () {})', expr.range))
|
|
815
1031
|
}
|
|
816
1032
|
}
|
|
817
1033
|
})
|
|
818
1034
|
|
|
1035
|
+
// processing for tenon-store
|
|
1036
|
+
if (mpx.mode === 'tenon') {
|
|
1037
|
+
let TENON_STORE_ID = 0
|
|
1038
|
+
parser.hooks.call.for('imported var').tap('MpxWebpackPlugin', (expr) => {
|
|
1039
|
+
if (['createStore', 'createStoreWithThis'].includes(expr.callee.name)) {
|
|
1040
|
+
const current = parser.state.current
|
|
1041
|
+
const storeOptions = expr.arguments.length && expr.arguments[0]
|
|
1042
|
+
if (storeOptions) {
|
|
1043
|
+
current.addDependency(new InjectDependency({
|
|
1044
|
+
content: 'Object.assign(',
|
|
1045
|
+
index: storeOptions.range[0]
|
|
1046
|
+
}))
|
|
1047
|
+
current.addDependency(new InjectDependency({
|
|
1048
|
+
content: `, { __store_id: ${TENON_STORE_ID++} })`,
|
|
1049
|
+
index: storeOptions.range[1]
|
|
1050
|
+
}))
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
})
|
|
1054
|
+
}
|
|
1055
|
+
|
|
819
1056
|
if (mpx.srcMode !== mpx.mode) {
|
|
820
|
-
//
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
1057
|
+
// 处理跨平台全局对象转换
|
|
1058
|
+
const transGlobalObject = (expr) => {
|
|
1059
|
+
const module = parser.state.module
|
|
1060
|
+
const current = parser.state.current
|
|
1061
|
+
const { queryObj, resourcePath } = parseRequest(module.resource)
|
|
1062
|
+
const localSrcMode = queryObj.mode
|
|
1063
|
+
const globalSrcMode = mpx.srcMode
|
|
1064
|
+
const srcMode = localSrcMode || globalSrcMode
|
|
1065
|
+
const mode = mpx.mode
|
|
1066
|
+
|
|
1067
|
+
let target
|
|
1068
|
+
if (expr.type === 'Identifier') {
|
|
1069
|
+
target = expr
|
|
1070
|
+
} else if (expr.type === 'MemberExpression') {
|
|
1071
|
+
target = expr.object
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if (!matchCondition(resourcePath, this.options.transMpxRules) || resourcePath.indexOf('@mpxjs') !== -1 || !target || mode === srcMode) return
|
|
1075
|
+
|
|
1076
|
+
const type = target.name
|
|
1077
|
+
const name = type === 'wx' ? 'mpx' : 'createFactory'
|
|
1078
|
+
const replaceContent = type === 'wx' ? 'mpx' : `createFactory(${JSON.stringify(type)})`
|
|
1079
|
+
|
|
1080
|
+
const dep = new ReplaceDependency(replaceContent, target.range)
|
|
1081
|
+
current.addPresentationalDependency(dep)
|
|
1082
|
+
|
|
1083
|
+
let needInject = true
|
|
1084
|
+
for (let dep of module.dependencies) {
|
|
1085
|
+
if (dep instanceof CommonJsVariableDependency && dep.name === name) {
|
|
1086
|
+
needInject = false
|
|
1087
|
+
break
|
|
1088
|
+
}
|
|
1089
|
+
}
|
|
1090
|
+
if (needInject) {
|
|
1091
|
+
const dep = new CommonJsVariableDependency(`@mpxjs/core/src/runtime/${name}`, name)
|
|
1092
|
+
module.addDependency(dep)
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
// 转换wx全局对象
|
|
1097
|
+
parser.hooks.expression.for('wx').tap('MpxWebpackPlugin', transGlobalObject)
|
|
832
1098
|
// Proxy ctor for transMode
|
|
833
1099
|
if (!this.options.forceDisableProxyCtor) {
|
|
834
1100
|
parser.hooks.call.for('Page').tap('MpxWebpackPlugin', (expr) => {
|
|
835
|
-
|
|
1101
|
+
transGlobalObject(expr.callee)
|
|
836
1102
|
})
|
|
837
1103
|
parser.hooks.call.for('Component').tap('MpxWebpackPlugin', (expr) => {
|
|
838
|
-
|
|
1104
|
+
transGlobalObject(expr.callee)
|
|
839
1105
|
})
|
|
840
1106
|
parser.hooks.call.for('App').tap('MpxWebpackPlugin', (expr) => {
|
|
841
|
-
|
|
1107
|
+
transGlobalObject(expr.callee)
|
|
842
1108
|
})
|
|
843
1109
|
if (mpx.mode === 'ali' || mpx.mode === 'web') {
|
|
844
1110
|
// 支付宝和web不支持Behaviors
|
|
845
1111
|
parser.hooks.call.for('Behavior').tap('MpxWebpackPlugin', (expr) => {
|
|
846
|
-
|
|
1112
|
+
transGlobalObject(expr.callee)
|
|
847
1113
|
})
|
|
848
1114
|
}
|
|
849
1115
|
}
|
|
850
|
-
}
|
|
851
1116
|
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
map
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
const
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
1117
|
+
// 为跨平台api调用注入srcMode参数指导api运行时转换
|
|
1118
|
+
const apiBlackListMap = [
|
|
1119
|
+
'createApp',
|
|
1120
|
+
'createPage',
|
|
1121
|
+
'createComponent',
|
|
1122
|
+
'createStore',
|
|
1123
|
+
'createStoreWithThis',
|
|
1124
|
+
'mixin',
|
|
1125
|
+
'injectMixins',
|
|
1126
|
+
'toPureObject',
|
|
1127
|
+
'observable',
|
|
1128
|
+
'watch',
|
|
1129
|
+
'use',
|
|
1130
|
+
'set',
|
|
1131
|
+
'remove',
|
|
1132
|
+
'delete',
|
|
1133
|
+
'setConvertRule',
|
|
1134
|
+
'getMixin',
|
|
1135
|
+
'getComputed',
|
|
1136
|
+
'implement'
|
|
1137
|
+
].reduce((map, api) => {
|
|
1138
|
+
map[api] = true
|
|
1139
|
+
return map
|
|
1140
|
+
}, {})
|
|
1141
|
+
|
|
1142
|
+
const injectSrcModeForTransApi = (expr, members) => {
|
|
1143
|
+
// members为空数组时,callee并不是memberExpression
|
|
1144
|
+
if (!members.length) return
|
|
1145
|
+
const callee = expr.callee
|
|
1146
|
+
const args = expr.arguments
|
|
1147
|
+
const name = callee.object.name
|
|
1148
|
+
const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
|
|
1149
|
+
const localSrcMode = queryObj.mode
|
|
1150
|
+
const globalSrcMode = mpx.srcMode
|
|
1151
|
+
const srcMode = localSrcMode || globalSrcMode
|
|
1152
|
+
|
|
1153
|
+
if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
|
|
1154
|
+
|
|
1155
|
+
const srcModeString = `__mpx_src_mode_${srcMode}__`
|
|
1156
|
+
const dep = new InjectDependency({
|
|
1157
|
+
content: args.length
|
|
1158
|
+
? `, ${JSON.stringify(srcModeString)}`
|
|
1159
|
+
: JSON.stringify(srcModeString),
|
|
1160
|
+
index: expr.end - 1
|
|
1161
|
+
})
|
|
1162
|
+
parser.state.current.addPresentationalDependency(dep)
|
|
887
1163
|
}
|
|
888
1164
|
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
? `, ${JSON.stringify(srcModeString)}`
|
|
893
|
-
: JSON.stringify(srcModeString),
|
|
894
|
-
index: expr.end - 1
|
|
895
|
-
})
|
|
896
|
-
parser.state.current.addDependency(dep)
|
|
1165
|
+
parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
|
|
1166
|
+
parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
|
|
1167
|
+
parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
|
|
897
1168
|
}
|
|
1169
|
+
})
|
|
898
1170
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
1171
|
+
// 为了正确生成sourceMap,将该步骤由原来的compile.hooks.emit迁移到compilation.hooks.processAssets
|
|
1172
|
+
compilation.hooks.processAssets.tap({
|
|
1173
|
+
name: 'MpxWebpackPlugin',
|
|
1174
|
+
stage: compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
|
1175
|
+
}, () => {
|
|
1176
|
+
if (mpx.mode === 'web') return
|
|
1177
|
+
|
|
1178
|
+
if (this.options.generateBuildMap) {
|
|
1179
|
+
const pagesMap = compilation.__mpx__.pagesMap
|
|
1180
|
+
const componentsPackageMap = compilation.__mpx__.componentsMap
|
|
1181
|
+
const componentsMap = Object.keys(componentsPackageMap).map(item => componentsPackageMap[item]).reduce((pre, cur) => {
|
|
1182
|
+
return { ...pre, ...cur }
|
|
1183
|
+
}, {})
|
|
1184
|
+
const outputMap = JSON.stringify({ ...pagesMap, ...componentsMap })
|
|
1185
|
+
const filename = this.options.generateBuildMap.filename || 'outputMap.json'
|
|
1186
|
+
compilation.assets[filename] = new RawSource(outputMap)
|
|
903
1187
|
}
|
|
904
|
-
})
|
|
905
1188
|
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1189
|
+
const {
|
|
1190
|
+
globalObject,
|
|
1191
|
+
chunkLoadingGlobal
|
|
1192
|
+
} = compilation.outputOptions
|
|
910
1193
|
|
|
911
1194
|
function getTargetFile (file) {
|
|
912
1195
|
let targetFile = file
|
|
@@ -918,21 +1201,23 @@ class MpxWebpackPlugin {
|
|
|
918
1201
|
}
|
|
919
1202
|
|
|
920
1203
|
const processedChunk = new Set()
|
|
921
|
-
const
|
|
1204
|
+
const appName = mpx.appInfo.name
|
|
922
1205
|
|
|
923
1206
|
function processChunk (chunk, isRuntime, relativeChunks) {
|
|
924
|
-
|
|
1207
|
+
const chunkFile = chunk.files.values().next().value
|
|
1208
|
+
if (!chunkFile || processedChunk.has(chunk)) {
|
|
925
1209
|
return
|
|
926
1210
|
}
|
|
927
1211
|
|
|
928
|
-
let originalSource = compilation.assets[
|
|
1212
|
+
let originalSource = compilation.assets[chunkFile]
|
|
929
1213
|
const source = new ConcatSource()
|
|
930
|
-
source.add(
|
|
1214
|
+
source.add(`\nvar ${globalObject} = ${globalObject} || {};\n\n`)
|
|
931
1215
|
|
|
932
1216
|
relativeChunks.forEach((relativeChunk, index) => {
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
let
|
|
1217
|
+
const relativeChunkFile = relativeChunk.files.values().next().value
|
|
1218
|
+
if (!relativeChunkFile) return
|
|
1219
|
+
let chunkPath = getTargetFile(chunkFile)
|
|
1220
|
+
let relativePath = getTargetFile(relativeChunkFile)
|
|
936
1221
|
relativePath = path.relative(path.dirname(chunkPath), relativePath)
|
|
937
1222
|
relativePath = fixRelative(relativePath, mpx.mode)
|
|
938
1223
|
relativePath = toPosix(relativePath)
|
|
@@ -940,19 +1225,19 @@ class MpxWebpackPlugin {
|
|
|
940
1225
|
// 引用runtime
|
|
941
1226
|
// 支付宝分包独立打包,通过全局context获取webpackJSONP
|
|
942
1227
|
if (mpx.mode === 'ali' && !mpx.isPluginMode) {
|
|
943
|
-
if (chunk.name ===
|
|
944
|
-
// 在rootChunk中挂载
|
|
1228
|
+
if (chunk.name === appName) {
|
|
1229
|
+
// 在rootChunk中挂载jsonpCallback
|
|
945
1230
|
source.add('// process ali subpackages runtime in root chunk\n' +
|
|
946
1231
|
'var context = (function() { return this })() || Function("return this")();\n\n')
|
|
947
|
-
source.add(`context[${JSON.stringify(
|
|
1232
|
+
source.add(`context[${JSON.stringify(chunkLoadingGlobal)}] = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
|
|
948
1233
|
} else {
|
|
949
1234
|
// 其余chunk中通过context全局传递runtime
|
|
950
1235
|
source.add('// process ali subpackages runtime in other chunk\n' +
|
|
951
1236
|
'var context = (function() { return this })() || Function("return this")();\n\n')
|
|
952
|
-
source.add(
|
|
1237
|
+
source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = context[${JSON.stringify(chunkLoadingGlobal)}];\n`)
|
|
953
1238
|
}
|
|
954
1239
|
} else {
|
|
955
|
-
source.add(
|
|
1240
|
+
source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
|
|
956
1241
|
}
|
|
957
1242
|
} else {
|
|
958
1243
|
source.add(`require("${relativePath}");\n`)
|
|
@@ -1005,18 +1290,12 @@ try {
|
|
|
1005
1290
|
} catch(e){
|
|
1006
1291
|
}\n`)
|
|
1007
1292
|
source.add(originalSource)
|
|
1008
|
-
source.add(`\nmodule.exports =
|
|
1293
|
+
source.add(`\nmodule.exports = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}];\n`)
|
|
1009
1294
|
} else {
|
|
1010
|
-
if (mpx.pluginMainModule && chunk.entryModule && mpx.pluginMainModule === chunk.entryModule) {
|
|
1011
|
-
source.add('module.exports =\n')
|
|
1012
|
-
// mpx.miniToPluginExports is a Set
|
|
1013
|
-
} else if (mpx.miniToPluginModules && chunk.entryModule && mpx.miniToPluginModules.has(chunk.entryModule)) {
|
|
1014
|
-
source.add('module.exports =\n')
|
|
1015
|
-
}
|
|
1016
1295
|
source.add(originalSource)
|
|
1017
1296
|
}
|
|
1018
1297
|
|
|
1019
|
-
compilation.assets[
|
|
1298
|
+
compilation.assets[chunkFile] = source
|
|
1020
1299
|
processedChunk.add(chunk)
|
|
1021
1300
|
}
|
|
1022
1301
|
|
|
@@ -1053,57 +1332,109 @@ try {
|
|
|
1053
1332
|
}
|
|
1054
1333
|
}
|
|
1055
1334
|
})
|
|
1056
|
-
|
|
1057
|
-
callback()
|
|
1058
1335
|
})
|
|
1059
1336
|
})
|
|
1060
1337
|
|
|
1061
1338
|
compiler.hooks.normalModuleFactory.tap('MpxWebpackPlugin', (normalModuleFactory) => {
|
|
1062
1339
|
// resolve前修改原始request
|
|
1063
|
-
normalModuleFactory.hooks.beforeResolve.
|
|
1340
|
+
normalModuleFactory.hooks.beforeResolve.tap('MpxWebpackPlugin', (data) => {
|
|
1064
1341
|
let request = data.request
|
|
1065
1342
|
let { queryObj, resource } = parseRequest(request)
|
|
1066
1343
|
if (queryObj.resolve) {
|
|
1067
1344
|
// 此处的query用于将资源引用的当前包信息传递给resolveDependency
|
|
1068
|
-
const
|
|
1069
|
-
|
|
1070
|
-
packageRoot: mpx.currentPackageRoot
|
|
1071
|
-
})
|
|
1072
|
-
data.request = `!!${pathLoader}!${resource}`
|
|
1073
|
-
} else if (queryObj.wxsModule) {
|
|
1074
|
-
const wxsPreLoader = normalize.lib('wxs/wxs-pre-loader')
|
|
1075
|
-
if (!/wxs-loader/.test(request)) {
|
|
1076
|
-
data.request = `!!${wxsPreLoader}!${resource}`
|
|
1077
|
-
}
|
|
1345
|
+
const resolveLoaderPath = normalize.lib('resolve-loader')
|
|
1346
|
+
data.request = `!!${resolveLoaderPath}!${resource}`
|
|
1078
1347
|
}
|
|
1079
|
-
callback(null, data)
|
|
1080
1348
|
})
|
|
1081
1349
|
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1350
|
+
const typeLoaderProcessInfo = {
|
|
1351
|
+
styles: ['css-loader', wxssLoaderPath, styleCompilerPath],
|
|
1352
|
+
template: ['html-loader', wxmlLoaderPath, templateCompilerPath]
|
|
1353
|
+
}
|
|
1354
|
+
|
|
1355
|
+
// 应用过rules后,注入mpx相关资源编译loader
|
|
1356
|
+
normalModuleFactory.hooks.afterResolve.tap('MpxWebpackPlugin', ({ createData }) => {
|
|
1357
|
+
const { queryObj } = parseRequest(createData.request)
|
|
1358
|
+
const loaders = createData.loaders
|
|
1359
|
+
if (queryObj.mpx && queryObj.mpx !== MPX_PROCESSED_FLAG) {
|
|
1360
|
+
const type = queryObj.type
|
|
1361
|
+
const extract = queryObj.extract
|
|
1362
|
+
switch (type) {
|
|
1363
|
+
case 'styles':
|
|
1364
|
+
case 'template':
|
|
1365
|
+
let insertBeforeIndex = -1
|
|
1366
|
+
const info = typeLoaderProcessInfo[type]
|
|
1367
|
+
loaders.forEach((loader, index) => {
|
|
1368
|
+
const currentLoader = toPosix(loader.loader)
|
|
1369
|
+
if (currentLoader.includes(info[0])) {
|
|
1370
|
+
loader.loader = info[1]
|
|
1371
|
+
insertBeforeIndex = index
|
|
1372
|
+
} else if (currentLoader.includes(info[1])) {
|
|
1373
|
+
insertBeforeIndex = index
|
|
1374
|
+
}
|
|
1375
|
+
})
|
|
1376
|
+
if (insertBeforeIndex > -1) {
|
|
1377
|
+
loaders.splice(insertBeforeIndex + 1, 0, {
|
|
1378
|
+
loader: info[2]
|
|
1379
|
+
})
|
|
1380
|
+
}
|
|
1381
|
+
break
|
|
1382
|
+
case 'json':
|
|
1383
|
+
if (queryObj.isTheme) {
|
|
1384
|
+
loaders.unshift({
|
|
1385
|
+
loader: jsonThemeCompilerPath
|
|
1386
|
+
})
|
|
1387
|
+
} else if (queryObj.isPlugin) {
|
|
1388
|
+
loaders.unshift({
|
|
1389
|
+
loader: jsonPluginCompilerPath
|
|
1390
|
+
})
|
|
1391
|
+
} else {
|
|
1392
|
+
loaders.unshift({
|
|
1393
|
+
loader: jsonCompilerPath
|
|
1394
|
+
})
|
|
1395
|
+
}
|
|
1396
|
+
break
|
|
1397
|
+
case 'wxs':
|
|
1398
|
+
loaders.unshift({
|
|
1399
|
+
loader: wxsLoaderPath
|
|
1400
|
+
})
|
|
1401
|
+
}
|
|
1402
|
+
if (extract) {
|
|
1403
|
+
loaders.unshift({
|
|
1404
|
+
loader: extractorPath
|
|
1405
|
+
})
|
|
1406
|
+
}
|
|
1407
|
+
createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
if (mpx.mode === 'web') {
|
|
1086
1411
|
const mpxStyleOptions = queryObj.mpxStyleOptions
|
|
1087
|
-
const firstLoader =
|
|
1088
|
-
const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher.js')
|
|
1412
|
+
const firstLoader = loaders[0] ? toPosix(loaders[0].loader) : ''
|
|
1413
|
+
const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher') || firstLoader.includes('@hummer/tenon-loader/dist/pitcher.js')
|
|
1089
1414
|
let cssLoaderIndex = -1
|
|
1090
1415
|
let vueStyleLoaderIndex = -1
|
|
1091
1416
|
let mpxStyleLoaderIndex = -1
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
// todo 暂时固定写死options,待后续优化为复用rules后修正
|
|
1096
|
-
loader.options = { appendTsSuffixTo: [/\.(mpx|vue)$/] }
|
|
1097
|
-
}
|
|
1417
|
+
let tenonStyleLoaderIndex = -1
|
|
1418
|
+
loaders.forEach((loader, index) => {
|
|
1419
|
+
const currentLoader = toPosix(loader.loader)
|
|
1098
1420
|
if (currentLoader.includes('css-loader')) {
|
|
1099
1421
|
cssLoaderIndex = index
|
|
1100
|
-
} else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader
|
|
1422
|
+
} else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader')) {
|
|
1101
1423
|
vueStyleLoaderIndex = index
|
|
1102
|
-
} else if (currentLoader.includes('@
|
|
1424
|
+
} else if (currentLoader.includes('@hummer/tenon-style-loader/dist/index.js')) {
|
|
1425
|
+
tenonStyleLoaderIndex = index
|
|
1426
|
+
} else if (currentLoader.includes(styleCompilerPath)) {
|
|
1103
1427
|
mpxStyleLoaderIndex = index
|
|
1104
1428
|
}
|
|
1105
1429
|
})
|
|
1106
|
-
if (mpxStyleLoaderIndex === -1) {
|
|
1430
|
+
if (mpx.mode === 'tenon' && mpxStyleLoaderIndex === -1) {
|
|
1431
|
+
if (tenonStyleLoaderIndex > -1 && !isPitcherRequest) {
|
|
1432
|
+
loaders.splice(tenonStyleLoaderIndex + 1, 0, {
|
|
1433
|
+
loader: normalize.lib('style-compiler/index.js'),
|
|
1434
|
+
options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
|
|
1435
|
+
})
|
|
1436
|
+
}
|
|
1437
|
+
} else if (mpxStyleLoaderIndex === -1) {
|
|
1107
1438
|
let loaderIndex = -1
|
|
1108
1439
|
if (cssLoaderIndex > -1 && vueStyleLoaderIndex === -1) {
|
|
1109
1440
|
loaderIndex = cssLoaderIndex
|
|
@@ -1111,37 +1442,70 @@ try {
|
|
|
1111
1442
|
loaderIndex = vueStyleLoaderIndex
|
|
1112
1443
|
}
|
|
1113
1444
|
if (loaderIndex > -1) {
|
|
1114
|
-
|
|
1115
|
-
loader:
|
|
1445
|
+
loaders.splice(loaderIndex + 1, 0, {
|
|
1446
|
+
loader: styleCompilerPath,
|
|
1116
1447
|
options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
|
|
1117
1448
|
})
|
|
1118
1449
|
}
|
|
1119
1450
|
}
|
|
1120
1451
|
}
|
|
1452
|
+
|
|
1453
|
+
createData.request = stringifyLoadersAndResource(loaders, createData.resource)
|
|
1121
1454
|
// 根据用户传入的modeRules对特定资源添加mode query
|
|
1122
|
-
this.runModeRules(
|
|
1123
|
-
callback(null, data)
|
|
1455
|
+
this.runModeRules(createData)
|
|
1124
1456
|
})
|
|
1125
1457
|
})
|
|
1126
1458
|
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1459
|
+
const clearFileCache = () => {
|
|
1460
|
+
const fs = compiler.intermediateFileSystem
|
|
1461
|
+
const cacheLocation = compiler.options.cache.cacheLocation
|
|
1462
|
+
return new Promise((resolve) => {
|
|
1463
|
+
if (!cacheLocation) return resolve()
|
|
1464
|
+
if (typeof fs.rm === 'function') {
|
|
1465
|
+
fs.rm(cacheLocation, {
|
|
1466
|
+
recursive: true,
|
|
1467
|
+
force: true
|
|
1468
|
+
}, resolve)
|
|
1469
|
+
} else {
|
|
1470
|
+
// polyfill fs.rm
|
|
1471
|
+
const rm = (file, callback) => {
|
|
1472
|
+
async.waterfall([
|
|
1473
|
+
(callback) => {
|
|
1474
|
+
fs.stat(file, callback)
|
|
1475
|
+
},
|
|
1476
|
+
(stats, callback) => {
|
|
1477
|
+
if (stats.isDirectory()) {
|
|
1478
|
+
const dir = file
|
|
1479
|
+
fs.readdir(dir, (err, files) => {
|
|
1480
|
+
if (err) return callback(err)
|
|
1481
|
+
async.each(files, (file, callback) => {
|
|
1482
|
+
file = path.join(dir, file)
|
|
1483
|
+
rm(file, callback)
|
|
1484
|
+
}, (err) => {
|
|
1485
|
+
if (err) return callback(err)
|
|
1486
|
+
fs.rmdir(dir, callback)
|
|
1487
|
+
})
|
|
1488
|
+
})
|
|
1489
|
+
} else {
|
|
1490
|
+
fs.unlink(file, callback)
|
|
1491
|
+
}
|
|
1492
|
+
}
|
|
1493
|
+
], callback)
|
|
1141
1494
|
}
|
|
1495
|
+
rm(cacheLocation, resolve)
|
|
1142
1496
|
}
|
|
1497
|
+
})
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
compiler.hooks.done.tapPromise('MpxWebpackPlugin', async () => {
|
|
1501
|
+
const cache = compiler.getCache('MpxWebpackPlugin')
|
|
1502
|
+
const cacheIsValid = await cache.getPromise('cacheIsValid', null)
|
|
1503
|
+
if (!cacheIsValid) {
|
|
1504
|
+
await Promise.all([
|
|
1505
|
+
clearFileCache(),
|
|
1506
|
+
cache.storePromise('cacheIsValid', null, true)
|
|
1507
|
+
])
|
|
1143
1508
|
}
|
|
1144
|
-
callback()
|
|
1145
1509
|
})
|
|
1146
1510
|
}
|
|
1147
1511
|
}
|