@mpxjs/webpack-plugin 2.6.114-alpha.8 → 2.6.115
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 +1 -1
- package/lib/built-in-loader.js +49 -0
- package/lib/config.js +0 -14
- package/lib/content-loader.js +13 -0
- package/lib/dependency/ChildCompileDependency.js +24 -0
- package/lib/dependency/InjectDependency.js +26 -0
- package/lib/dependency/RemovedModuleDependency.js +23 -0
- package/lib/{dependencies → dependency}/ReplaceDependency.js +2 -19
- package/lib/dependency/ResolveDependency.js +49 -0
- package/lib/extractor.js +178 -82
- package/lib/file-loader.js +19 -7
- package/lib/helpers.js +334 -39
- package/lib/index.js +525 -889
- package/lib/json-compiler/index.js +451 -245
- package/lib/json-compiler/{theme.js → theme-loader.js} +3 -5
- package/lib/loader.js +241 -178
- package/lib/native-loader.js +133 -71
- package/lib/parser.js +2 -1
- package/lib/path-loader.js +3 -0
- package/lib/platform/json/wx/index.js +1 -1
- package/lib/platform/template/normalize-component-rules.js +3 -2
- package/lib/platform/template/wx/component-config/button.js +2 -14
- package/lib/platform/template/wx/component-config/image.js +0 -4
- package/lib/platform/template/wx/component-config/input.js +0 -4
- package/lib/platform/template/wx/component-config/rich-text.js +0 -4
- package/lib/platform/template/wx/component-config/scroll-view.js +0 -4
- package/lib/platform/template/wx/component-config/switch.js +0 -4
- package/lib/platform/template/wx/component-config/text.js +0 -4
- package/lib/platform/template/wx/component-config/textarea.js +0 -5
- package/lib/platform/template/wx/component-config/view.js +0 -4
- package/lib/platform/template/wx/index.js +3 -149
- package/lib/plugin-loader.js +287 -0
- package/lib/resolver/AddEnvPlugin.js +3 -4
- package/lib/resolver/AddModePlugin.js +3 -4
- package/lib/resolver/PackageEntryPlugin.js +36 -23
- package/lib/runtime/base.styl +0 -5
- package/lib/runtime/components/web/getInnerListeners.js +3 -1
- package/lib/runtime/components/web/mpx-image.vue +5 -20
- package/lib/runtime/components/web/mpx-movable-view.vue +2 -6
- package/lib/runtime/components/web/mpx-swiper.vue +3 -18
- package/lib/runtime/i18n.wxs +11 -31
- package/lib/runtime/optionProcessor.js +3 -48
- package/lib/selector.js +10 -29
- package/lib/staticConfig.js +4 -0
- package/lib/style-compiler/index.js +24 -16
- package/lib/style-compiler/load-postcss-config.js +1 -3
- package/lib/style-compiler/plugins/conditional-strip.js +65 -68
- package/lib/style-compiler/plugins/rpx.js +37 -43
- package/lib/style-compiler/plugins/scope-id.js +72 -79
- package/lib/style-compiler/plugins/trans-special.js +18 -25
- package/lib/style-compiler/plugins/trim.js +7 -13
- package/lib/style-compiler/plugins/vw.js +16 -22
- package/lib/template-compiler/compiler.js +199 -106
- package/lib/template-compiler/index.js +139 -52
- package/lib/template-compiler/trans-dynamic-class-expr.js +13 -18
- package/lib/url-loader.js +29 -11
- package/lib/utils/add-query.js +1 -1
- package/lib/utils/get-main-compilation.js +6 -0
- package/lib/utils/is-url-request.js +1 -10
- package/lib/utils/match-condition.js +1 -4
- package/lib/utils/normalize.js +15 -4
- package/lib/utils/parse-request.js +3 -3
- package/lib/utils/read-json-for-src.js +34 -0
- package/lib/utils/stringify-query.js +0 -4
- package/lib/utils/try-require.js +16 -0
- package/lib/web/processJSON.js +144 -113
- package/lib/web/processScript.js +34 -47
- package/lib/web/processTemplate.js +40 -57
- package/lib/wxml/{loader.js → wxml-loader.js} +62 -21
- package/lib/wxs/WxsParserPlugin.js +2 -2
- package/lib/wxs/WxsPlugin.js +8 -4
- package/lib/wxs/WxsTemplatePlugin.js +92 -46
- package/lib/wxs/{i18n-loader.js → wxs-i18n-loader.js} +4 -5
- package/lib/wxs/wxs-loader.js +117 -0
- package/lib/wxs/{pre-loader.js → wxs-pre-loader.js} +5 -20
- package/lib/wxss/getImportPrefix.js +30 -0
- package/lib/wxss/loader.js +43 -31
- package/lib/wxss/localsLoader.js +5 -1
- package/lib/wxss/processCss.js +103 -107
- package/package.json +18 -21
- package/LICENSE +0 -433
- package/lib/dependencies/AddEntryDependency.js +0 -24
- package/lib/dependencies/AppEntryDependency.js +0 -58
- package/lib/dependencies/CommonJsAsyncDependency.js +0 -51
- package/lib/dependencies/CommonJsVariableDependency.js +0 -81
- package/lib/dependencies/DynamicEntryDependency.js +0 -171
- package/lib/dependencies/FlagPluginDependency.js +0 -24
- package/lib/dependencies/InjectDependency.js +0 -43
- package/lib/dependencies/RecordGlobalComponentsDependency.js +0 -50
- package/lib/dependencies/RecordIndependentDependency.js +0 -44
- package/lib/dependencies/RecordResourceMapDependency.js +0 -62
- package/lib/dependencies/RemoveEntryDependency.js +0 -40
- package/lib/dependencies/ResolveDependency.js +0 -88
- package/lib/independent-loader.js +0 -52
- package/lib/json-compiler/helper.js +0 -156
- package/lib/json-compiler/plugin.js +0 -150
- package/lib/partial-compile/index.js +0 -35
- package/lib/record-loader.js +0 -11
- package/lib/resolve-loader.js +0 -6
- package/lib/resolver/FixDescriptionInfoPlugin.js +0 -28
- package/lib/runtime/components/tenon/getInnerListeners.js +0 -317
- package/lib/runtime/components/tenon/tenon-button.vue +0 -305
- package/lib/runtime/components/tenon/tenon-image.vue +0 -61
- package/lib/runtime/components/tenon/tenon-input.vue +0 -99
- package/lib/runtime/components/tenon/tenon-rich-text.vue +0 -21
- package/lib/runtime/components/tenon/tenon-scroll-view.vue +0 -124
- package/lib/runtime/components/tenon/tenon-switch.vue +0 -91
- package/lib/runtime/components/tenon/tenon-text-area.vue +0 -64
- package/lib/runtime/components/tenon/tenon-text.vue +0 -64
- package/lib/runtime/components/tenon/tenon-view.vue +0 -93
- package/lib/runtime/components/tenon/util.js +0 -44
- package/lib/runtime/optionProcessor.tenon.js +0 -386
- package/lib/style-compiler/plugins/hm.js +0 -20
- package/lib/tenon/index.js +0 -105
- package/lib/tenon/processJSON.js +0 -360
- package/lib/tenon/processScript.js +0 -260
- package/lib/tenon/processStyles.js +0 -21
- package/lib/tenon/processTemplate.js +0 -133
- package/lib/utils/const.js +0 -10
- package/lib/utils/emit-file.js +0 -10
- package/lib/utils/eval-json-js.js +0 -31
- package/lib/utils/get-entry-name.js +0 -13
- package/lib/utils/get-json-content.js +0 -42
- package/lib/utils/get-relative-path.js +0 -24
- package/lib/utils/resolve.js +0 -13
- package/lib/utils/set.js +0 -47
- package/lib/utils/stringify-loaders-resource.js +0 -25
- package/lib/wxs/WxsModuleIdsPlugin.js +0 -29
- package/lib/wxs/loader.js +0 -142
package/lib/index.js
CHANGED
|
@@ -1,89 +1,68 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const path = require('path')
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const
|
|
7
|
-
const
|
|
4
|
+
const ConcatSource = require('webpack-sources').ConcatSource
|
|
5
|
+
const RawSource = require('webpack-sources').RawSource
|
|
6
|
+
const ResolveDependency = require('./dependency/ResolveDependency')
|
|
7
|
+
const InjectDependency = require('./dependency/InjectDependency')
|
|
8
|
+
const ReplaceDependency = require('./dependency/ReplaceDependency')
|
|
9
|
+
const ChildCompileDependency = require('./dependency/ChildCompileDependency')
|
|
8
10
|
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')
|
|
17
11
|
const normalize = require('./utils/normalize')
|
|
18
12
|
const toPosix = require('./utils/to-posix')
|
|
19
13
|
const addQuery = require('./utils/add-query')
|
|
20
|
-
const { every } = require('./utils/set')
|
|
21
14
|
const DefinePlugin = require('webpack/lib/DefinePlugin')
|
|
22
15
|
const ExternalsPlugin = require('webpack/lib/ExternalsPlugin')
|
|
23
16
|
const AddModePlugin = require('./resolver/AddModePlugin')
|
|
24
17
|
const AddEnvPlugin = require('./resolver/AddEnvPlugin')
|
|
25
18
|
const PackageEntryPlugin = require('./resolver/PackageEntryPlugin')
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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')
|
|
19
|
+
const CommonJsRequireDependency = require('webpack/lib/dependencies/CommonJsRequireDependency')
|
|
20
|
+
const HarmonyImportSideEffectDependency = require('webpack/lib/dependencies/HarmonyImportSideEffectDependency')
|
|
21
|
+
const RequireHeaderDependency = require('webpack/lib/dependencies/RequireHeaderDependency')
|
|
22
|
+
const RemovedModuleDependency = require('./dependency/RemovedModuleDependency')
|
|
38
23
|
const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
|
|
39
|
-
const PartialCompilePlugin = require('./partial-compile/index')
|
|
40
24
|
const fixRelative = require('./utils/fix-relative')
|
|
41
25
|
const parseRequest = require('./utils/parse-request')
|
|
42
|
-
const
|
|
26
|
+
const matchCondition = require('./utils/match-condition')
|
|
43
27
|
const { preProcessDefs } = require('./utils/index')
|
|
44
|
-
const config = require('./config')
|
|
45
28
|
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')
|
|
60
29
|
|
|
61
30
|
const isProductionLikeMode = options => {
|
|
62
31
|
return options.mode === 'production' || !options.mode
|
|
63
32
|
}
|
|
64
33
|
|
|
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
|
-
|
|
80
34
|
const outputFilename = '[name].js'
|
|
81
35
|
const publicPath = '/'
|
|
82
36
|
|
|
83
|
-
|
|
37
|
+
function isChunkInPackage (chunkName, packageName) {
|
|
84
38
|
return (new RegExp(`^${packageName}\\/`)).test(chunkName)
|
|
85
39
|
}
|
|
86
40
|
|
|
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
|
+
|
|
87
66
|
const externalsMap = {
|
|
88
67
|
weui: /^weui-miniprogram/
|
|
89
68
|
}
|
|
@@ -92,9 +71,10 @@ const warnings = []
|
|
|
92
71
|
const errors = []
|
|
93
72
|
|
|
94
73
|
class EntryNode {
|
|
95
|
-
constructor (
|
|
96
|
-
this.
|
|
97
|
-
this.type = type
|
|
74
|
+
constructor (options) {
|
|
75
|
+
this.request = options.request
|
|
76
|
+
this.type = options.type
|
|
77
|
+
this.module = null
|
|
98
78
|
this.parents = new Set()
|
|
99
79
|
this.children = new Set()
|
|
100
80
|
}
|
|
@@ -122,6 +102,7 @@ class MpxWebpackPlugin {
|
|
|
122
102
|
options.writeMode = options.writeMode || 'changed'
|
|
123
103
|
options.autoScopeRules = options.autoScopeRules || {}
|
|
124
104
|
options.autoVirtualHostRules = options.autoVirtualHostRules || {}
|
|
105
|
+
options.forceDisableInject = options.forceDisableInject || false
|
|
125
106
|
options.forceDisableProxyCtor = options.forceDisableProxyCtor || false
|
|
126
107
|
options.transMpxRules = options.transMpxRules || {
|
|
127
108
|
include: () => true
|
|
@@ -143,8 +124,12 @@ class MpxWebpackPlugin {
|
|
|
143
124
|
options.forceUsePageCtor = options.forceUsePageCtor || false
|
|
144
125
|
options.postcssInlineConfig = options.postcssInlineConfig || {}
|
|
145
126
|
options.transRpxRules = options.transRpxRules || null
|
|
127
|
+
options.webConfig = options.webConfig || {}
|
|
146
128
|
options.auditResource = options.auditResource || false
|
|
147
129
|
options.decodeHTMLText = options.decodeHTMLText || false
|
|
130
|
+
options.nativeOptions = Object.assign({
|
|
131
|
+
cssLangs: ['css', 'less', 'stylus', 'scss', 'sass']
|
|
132
|
+
}, options.nativeOptions)
|
|
148
133
|
options.i18n = options.i18n || null
|
|
149
134
|
options.checkUsingComponents = options.checkUsingComponents || false
|
|
150
135
|
options.reportSize = options.reportSize || null
|
|
@@ -159,103 +144,31 @@ class MpxWebpackPlugin {
|
|
|
159
144
|
include: () => true
|
|
160
145
|
}
|
|
161
146
|
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
|
|
173
147
|
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
|
-
}
|
|
182
148
|
}
|
|
183
149
|
|
|
184
150
|
static loader (options = {}) {
|
|
185
|
-
|
|
151
|
+
loaderOptions = options
|
|
152
|
+
if (loaderOptions.transRpx) {
|
|
186
153
|
warnings.push('Mpx loader option [transRpx] is deprecated now, please use mpx webpack plugin config [transRpxRules] instead!')
|
|
187
154
|
}
|
|
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
|
-
}
|
|
155
|
+
return { loader: normalize.lib('loader'), options }
|
|
213
156
|
}
|
|
214
157
|
|
|
215
158
|
static pluginLoader (options = {}) {
|
|
216
|
-
return {
|
|
217
|
-
loader: normalize.lib('json-compiler/plugin'),
|
|
218
|
-
options
|
|
219
|
-
}
|
|
159
|
+
return { loader: normalize.lib('plugin-loader'), options }
|
|
220
160
|
}
|
|
221
161
|
|
|
222
162
|
static wxsPreLoader (options = {}) {
|
|
223
|
-
return {
|
|
224
|
-
loader: normalize.lib('wxs/pre-loader'),
|
|
225
|
-
options
|
|
226
|
-
}
|
|
163
|
+
return { loader: normalize.lib('wxs/wxs-pre-loader'), options }
|
|
227
164
|
}
|
|
228
165
|
|
|
229
166
|
static urlLoader (options = {}) {
|
|
230
|
-
return {
|
|
231
|
-
loader: normalize.lib('url-loader'),
|
|
232
|
-
options
|
|
233
|
-
}
|
|
167
|
+
return { loader: normalize.lib('url-loader'), options }
|
|
234
168
|
}
|
|
235
169
|
|
|
236
170
|
static fileLoader (options = {}) {
|
|
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
|
-
})
|
|
171
|
+
return { loader: normalize.lib('file-loader'), options }
|
|
259
172
|
}
|
|
260
173
|
|
|
261
174
|
runModeRules (data) {
|
|
@@ -281,9 +194,6 @@ class MpxWebpackPlugin {
|
|
|
281
194
|
errors.push('Multiple MpxWebpackPlugin instances exist in webpack compiler, please check webpack plugins config!')
|
|
282
195
|
}
|
|
283
196
|
|
|
284
|
-
// 将entry export标记为used且不可mangle,避免require.async生成的js chunk在生产环境下报错
|
|
285
|
-
new FlagEntryExportAsUsedPlugin(true, 'entry').apply(compiler)
|
|
286
|
-
|
|
287
197
|
if (this.options.mode !== 'web') {
|
|
288
198
|
// 强制设置publicPath为'/'
|
|
289
199
|
if (compiler.options.output.publicPath && compiler.options.output.publicPath !== publicPath) {
|
|
@@ -299,11 +209,12 @@ class MpxWebpackPlugin {
|
|
|
299
209
|
if (!compiler.options.node || !compiler.options.node.global) {
|
|
300
210
|
compiler.options.node = compiler.options.node || {}
|
|
301
211
|
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!`)
|
|
302
213
|
}
|
|
303
214
|
|
|
304
215
|
const addModePlugin = new AddModePlugin('before-file', this.options.mode, this.options.fileConditionRules, 'file')
|
|
305
216
|
const addEnvPlugin = new AddEnvPlugin('before-file', this.options.env, this.options.fileConditionRules, 'file')
|
|
306
|
-
const packageEntryPlugin = new PackageEntryPlugin('before-
|
|
217
|
+
const packageEntryPlugin = new PackageEntryPlugin('before-described-relative', this.options.miniNpmPackages, 'resolve')
|
|
307
218
|
if (Array.isArray(compiler.options.resolve.plugins)) {
|
|
308
219
|
compiler.options.resolve.plugins.push(addModePlugin)
|
|
309
220
|
} else {
|
|
@@ -313,14 +224,12 @@ class MpxWebpackPlugin {
|
|
|
313
224
|
compiler.options.resolve.plugins.push(addEnvPlugin)
|
|
314
225
|
}
|
|
315
226
|
compiler.options.resolve.plugins.push(packageEntryPlugin)
|
|
316
|
-
compiler.options.resolve.plugins.push(new FixDescriptionInfoPlugin())
|
|
317
227
|
|
|
318
228
|
let splitChunksPlugin
|
|
319
229
|
let splitChunksOptions
|
|
320
230
|
|
|
321
|
-
if (this.options.mode !== 'web'
|
|
322
|
-
|
|
323
|
-
optimization.runtimeChunk = {
|
|
231
|
+
if (this.options.mode !== 'web') {
|
|
232
|
+
compiler.options.optimization.runtimeChunk = {
|
|
324
233
|
name: (entrypoint) => {
|
|
325
234
|
for (let packageName in mpx.independentSubpackagesMap) {
|
|
326
235
|
if (mpx.independentSubpackagesMap.hasOwnProperty(packageName) && isChunkInPackage(entrypoint.name, packageName)) {
|
|
@@ -330,18 +239,8 @@ class MpxWebpackPlugin {
|
|
|
330
239
|
return 'bundle'
|
|
331
240
|
}
|
|
332
241
|
}
|
|
333
|
-
splitChunksOptions =
|
|
334
|
-
|
|
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
|
|
242
|
+
splitChunksOptions = compiler.options.optimization.splitChunks
|
|
243
|
+
delete compiler.options.optimization.splitChunks
|
|
345
244
|
splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
|
|
346
245
|
splitChunksPlugin.apply(compiler)
|
|
347
246
|
}
|
|
@@ -359,11 +258,8 @@ class MpxWebpackPlugin {
|
|
|
359
258
|
originalWriteFile(filePath, content, callback)
|
|
360
259
|
}
|
|
361
260
|
}
|
|
362
|
-
|
|
363
261
|
const defs = this.options.defs
|
|
364
262
|
|
|
365
|
-
const typeExtMap = config[this.options.mode].typeExtMap
|
|
366
|
-
|
|
367
263
|
const defsOpt = {
|
|
368
264
|
'__mpx_wxs__': DefinePlugin.runtimeValue(({ module }) => {
|
|
369
265
|
return JSON.stringify(!!module.wxs)
|
|
@@ -381,92 +277,12 @@ class MpxWebpackPlugin {
|
|
|
381
277
|
|
|
382
278
|
let mpx
|
|
383
279
|
|
|
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
|
-
|
|
460
280
|
compiler.hooks.compilation.tap('MpxWebpackPlugin ', (compilation, { normalModuleFactory }) => {
|
|
461
|
-
|
|
281
|
+
compilation.hooks.normalModuleLoader.tap('MpxWebpackPlugin', (loaderContext, module) => {
|
|
462
282
|
// 设置loaderContext的minimize
|
|
463
283
|
if (isProductionLikeMode(compiler.options)) {
|
|
464
284
|
loaderContext.minimize = true
|
|
465
285
|
}
|
|
466
|
-
|
|
467
|
-
loaderContext.getMpx = () => {
|
|
468
|
-
return mpx
|
|
469
|
-
}
|
|
470
286
|
})
|
|
471
287
|
compilation.dependencyFactories.set(ResolveDependency, new NullFactory())
|
|
472
288
|
compilation.dependencyTemplates.set(ResolveDependency, new ResolveDependency.Template())
|
|
@@ -477,92 +293,161 @@ class MpxWebpackPlugin {
|
|
|
477
293
|
compilation.dependencyFactories.set(ReplaceDependency, new NullFactory())
|
|
478
294
|
compilation.dependencyTemplates.set(ReplaceDependency, new ReplaceDependency.Template())
|
|
479
295
|
|
|
480
|
-
compilation.dependencyFactories.set(
|
|
481
|
-
compilation.dependencyTemplates.set(
|
|
482
|
-
|
|
483
|
-
compilation.dependencyFactories.set(
|
|
484
|
-
compilation.dependencyTemplates.set(
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
296
|
+
compilation.dependencyFactories.set(ChildCompileDependency, new NullFactory())
|
|
297
|
+
compilation.dependencyTemplates.set(ChildCompileDependency, new ChildCompileDependency.Template())
|
|
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
|
+
}
|
|
494
326
|
|
|
495
|
-
|
|
496
|
-
|
|
327
|
+
// 处理watch时缓存模块中的buildInfo
|
|
328
|
+
// 在调用addModule前对module添加分包信息,以控制分包输出及消除缓存,该操作由afterResolve钩子迁移至此是由于dependencyCache的存在,watch状态下afterResolve钩子并不会对所有模块执行,而模块的packageName在watch过程中是可能发生变更的,如新增删除一个分包资源的主包引用
|
|
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]
|
|
497
348
|
|
|
498
|
-
|
|
499
|
-
|
|
349
|
+
let needPackageQuery = isStatic || isIndependent
|
|
350
|
+
if (!needPackageQuery && matchCondition(resourcePath, this.options.subpackageModulesRules)) {
|
|
351
|
+
needPackageQuery = true
|
|
352
|
+
}
|
|
500
353
|
|
|
501
|
-
|
|
502
|
-
|
|
354
|
+
if (needPackageQuery) {
|
|
355
|
+
const { packageRoot } = mpx.getPackageInfo({
|
|
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
|
+
}
|
|
503
374
|
|
|
504
|
-
|
|
505
|
-
|
|
375
|
+
const addModuleResult = rawAddModule.call(compilation, module, cacheGroup)
|
|
376
|
+
if (!addModuleResult.build && addModuleResult.issuer) {
|
|
377
|
+
const buildInfo = addModuleResult.module.buildInfo
|
|
378
|
+
if (buildInfo.pagesMap) {
|
|
379
|
+
Object.assign(mpx.pagesMap, buildInfo.pagesMap)
|
|
380
|
+
}
|
|
381
|
+
if (buildInfo.componentsMap && buildInfo.packageName) {
|
|
382
|
+
Object.assign(mpx.componentsMap[buildInfo.packageName], buildInfo.componentsMap)
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return addModuleResult
|
|
386
|
+
}
|
|
506
387
|
})
|
|
507
388
|
|
|
508
389
|
compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
|
|
509
390
|
compilation.warnings = compilation.warnings.concat(warnings)
|
|
510
391
|
compilation.errors = compilation.errors.concat(errors)
|
|
511
|
-
|
|
392
|
+
// additionalAssets和mpx由于包含缓存机制,必须在每次compilation时重新初始化
|
|
393
|
+
const additionalAssets = {}
|
|
512
394
|
if (!compilation.__mpx__) {
|
|
513
395
|
// init mpx
|
|
514
396
|
mpx = compilation.__mpx__ = {
|
|
515
|
-
// app信息,便于获取appName
|
|
516
|
-
appInfo: {},
|
|
517
397
|
// pages全局记录,无需区分主包分包
|
|
518
398
|
pagesMap: {},
|
|
519
|
-
//
|
|
399
|
+
// 记录pages对应的entry,处理多appEntry输出web多页项目时可能出现的pagePath冲突的问题,多appEntry输出目前仅web模式支持
|
|
400
|
+
pagesEntryMap: {},
|
|
401
|
+
// 组件资源记录,依照所属包进行记录,冗余存储,只要某个包有引用会添加对应记录,不管其会不会在当前包输出,这样设计主要是为了在resolve时能够以较低成本找到特定资源的输出路径
|
|
520
402
|
componentsMap: {
|
|
521
403
|
main: {}
|
|
522
404
|
},
|
|
523
|
-
// 静态资源(图片,字体,独立样式)
|
|
405
|
+
// 静态资源(图片,字体,独立样式)等,依照所属包进行记录,冗余存储,同上
|
|
524
406
|
staticResourcesMap: {
|
|
525
407
|
main: {}
|
|
526
408
|
},
|
|
527
|
-
// 用于记录命中subpackageModulesRules的js
|
|
409
|
+
// 用于记录命中subpackageModulesRules的js模块最终输出到了什么分包中
|
|
528
410
|
subpackageModulesMap: {
|
|
529
411
|
main: {}
|
|
530
412
|
},
|
|
531
|
-
// 记录其他资源,如pluginMain、pluginExport,无需区分主包分包
|
|
532
|
-
otherResourcesMap: {},
|
|
533
413
|
// 记录独立分包
|
|
534
414
|
independentSubpackagesMap: {},
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
415
|
+
// 当前机制下分包处理队列在app.json的json-compiler中进行,由于addEntry回调特性,无法保障app.js中引用的模块都被标记为主包,故重写processModuleDependencies获取app.js及其所有依赖处理完成的时机,在这之后再执行分包处理队列
|
|
416
|
+
appScriptRawRequest: '',
|
|
417
|
+
appScriptPromise: null,
|
|
418
|
+
appScriptPromiseResolve: null,
|
|
419
|
+
// 记录entry依赖关系,用于体积分析
|
|
420
|
+
entryNodesMap: {},
|
|
538
421
|
// 记录entryModule与entryNode的对应关系,用于体积分析
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
// 记录与asset相关联的ast,用于体积分析和esCheck,避免重复parse
|
|
543
|
-
assetsASTsMap: new Map(),
|
|
422
|
+
entryModulesMap: new Map(),
|
|
423
|
+
loaderOptions,
|
|
424
|
+
extractedMap: {},
|
|
544
425
|
usingComponents: {},
|
|
426
|
+
hasApp: false,
|
|
545
427
|
// todo es6 map读写性能高于object,之后会逐步替换
|
|
546
428
|
vueContentCache: new Map(),
|
|
547
|
-
wxsAssetsCache: new Map(),
|
|
548
429
|
currentPackageRoot: '',
|
|
430
|
+
wxsMap: {},
|
|
549
431
|
wxsContentMap: {},
|
|
432
|
+
assetsInfo: new Map(),
|
|
433
|
+
forceDisableInject: this.options.forceDisableInject,
|
|
550
434
|
forceUsePageCtor: this.options.forceUsePageCtor,
|
|
551
435
|
resolveMode: this.options.resolveMode,
|
|
552
436
|
mode: this.options.mode,
|
|
553
437
|
srcMode: this.options.srcMode,
|
|
554
438
|
env: this.options.env,
|
|
439
|
+
// deprecated option
|
|
440
|
+
globalMpxAttrsFilter: this.options.globalMpxAttrsFilter,
|
|
555
441
|
externalClasses: this.options.externalClasses,
|
|
556
442
|
projectRoot: this.options.projectRoot,
|
|
557
443
|
autoScopeRules: this.options.autoScopeRules,
|
|
558
444
|
autoVirtualHostRules: this.options.autoVirtualHostRules,
|
|
559
445
|
transRpxRules: this.options.transRpxRules,
|
|
446
|
+
webConfig: this.options.webConfig,
|
|
560
447
|
postcssInlineConfig: this.options.postcssInlineConfig,
|
|
561
448
|
decodeHTMLText: this.options.decodeHTMLText,
|
|
562
|
-
// native
|
|
563
|
-
|
|
564
|
-
// 输出web专用配置
|
|
565
|
-
webConfig: this.options.webConfig,
|
|
449
|
+
// native文件专用相关配置
|
|
450
|
+
nativeOptions: this.options.nativeOptions,
|
|
566
451
|
tabBarMap: {},
|
|
567
452
|
defs: preProcessDefs(this.options.defs),
|
|
568
453
|
i18n: this.options.i18n,
|
|
@@ -574,121 +459,76 @@ class MpxWebpackPlugin {
|
|
|
574
459
|
useRelativePath: this.options.useRelativePath,
|
|
575
460
|
removedChunks: [],
|
|
576
461
|
forceProxyEventRules: this.options.forceProxyEventRules,
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
462
|
+
getEntryNode: (request, type, module) => {
|
|
463
|
+
const entryNodesMap = mpx.entryNodesMap
|
|
464
|
+
const entryModulesMap = mpx.entryModulesMap
|
|
465
|
+
if (!entryNodesMap[request]) {
|
|
466
|
+
entryNodesMap[request] = new EntryNode({
|
|
467
|
+
type,
|
|
468
|
+
request
|
|
469
|
+
})
|
|
581
470
|
}
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
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
|
|
588
480
|
},
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
481
|
+
pathHash: (resourcePath) => {
|
|
482
|
+
let hashPath = resourcePath
|
|
483
|
+
const pathHashMode = this.options.pathHashMode
|
|
484
|
+
const projectRoot = this.options.projectRoot || ''
|
|
485
|
+
if (pathHashMode === 'relative') {
|
|
486
|
+
hashPath = path.relative(projectRoot, resourcePath)
|
|
487
|
+
}
|
|
488
|
+
if (typeof pathHashMode === 'function') {
|
|
489
|
+
hashPath = pathHashMode(resourcePath, projectRoot) || resourcePath
|
|
595
490
|
}
|
|
596
|
-
return
|
|
491
|
+
return hash(hashPath)
|
|
597
492
|
},
|
|
598
493
|
getOutputPath: (resourcePath, type, { ext = '', conflictPath = '' } = {}) => {
|
|
599
494
|
const name = path.parse(resourcePath).name
|
|
600
495
|
const hash = mpx.pathHash(resourcePath)
|
|
601
496
|
const customOutputPath = this.options.customOutputPath
|
|
602
497
|
if (conflictPath) return conflictPath.replace(/(\.[^\\/]+)?$/, match => hash + match)
|
|
603
|
-
if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext)
|
|
498
|
+
if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext)
|
|
604
499
|
if (type === 'component' || type === 'page') return path.join(type + 's', name + hash, 'index' + ext)
|
|
605
500
|
return path.join(type, name + hash + ext)
|
|
606
501
|
},
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
if (
|
|
611
|
-
|
|
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
|
|
502
|
+
extract: (content, file, index, sideEffects) => {
|
|
503
|
+
index = index === -1 ? 0 : index
|
|
504
|
+
additionalAssets[file] = additionalAssets[file] || []
|
|
505
|
+
if (!additionalAssets[file][index]) {
|
|
506
|
+
additionalAssets[file][index] = content
|
|
667
507
|
}
|
|
508
|
+
sideEffects && sideEffects.forEach((sideEffect) => {
|
|
509
|
+
sideEffect(additionalAssets)
|
|
510
|
+
})
|
|
668
511
|
},
|
|
669
512
|
// 组件和静态资源的输出规则如下:
|
|
670
513
|
// 1. 主包引用的资源输出至主包
|
|
671
514
|
// 2. 分包引用且主包引用过的资源输出至主包,不在当前分包重复输出
|
|
672
515
|
// 3. 分包引用且无其他包引用的资源输出至当前分包
|
|
673
516
|
// 4. 分包引用且其他分包也引用过的资源,重复输出至当前分包
|
|
674
|
-
getPackageInfo: ({ resource,
|
|
517
|
+
getPackageInfo: ({ resource, outputPath, resourceType = 'components', issuerResource, warn }) => {
|
|
675
518
|
let packageRoot = ''
|
|
676
519
|
let packageName = 'main'
|
|
677
|
-
|
|
678
|
-
const { resourcePath } = parseRequest(resource)
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
|
|
683
|
-
|
|
684
|
-
if (!resourceMap.main) {
|
|
685
|
-
packageRoot = currentPackageRoot
|
|
686
|
-
packageName = currentPackageName
|
|
520
|
+
const resourceMap = mpx[`${resourceType}Map`]
|
|
521
|
+
const { queryObj, resourcePath } = parseRequest(resource)
|
|
522
|
+
if (resourceType === 'staticResources' && outputPath) {
|
|
523
|
+
packageRoot = queryObj.packageRoot || ''
|
|
524
|
+
packageName = packageRoot || 'main'
|
|
687
525
|
} else {
|
|
526
|
+
const currentPackageRoot = mpx.currentPackageRoot
|
|
527
|
+
const currentPackageName = currentPackageRoot || 'main'
|
|
528
|
+
const isIndependent = mpx.independentSubpackagesMap[currentPackageRoot]
|
|
688
529
|
// 主包中有引用一律使用主包中资源,不再额外输出
|
|
689
530
|
// 资源路径匹配到forceMainPackageRules规则时强制输出到主包,降低分包资源冗余
|
|
690
531
|
// 如果存在issuer且issuerPackageRoot与当前packageRoot不一致,也输出到主包
|
|
691
|
-
// todo forceMainPackageRules规则目前只能处理当前资源,不能处理资源子树,配置不当有可能会导致资源引用错误
|
|
692
532
|
let isMain = resourceMap.main[resourcePath] || matchCondition(resourcePath, this.options.forceMainPackageRules)
|
|
693
533
|
if (issuerResource) {
|
|
694
534
|
const { queryObj } = parseRequest(issuerResource)
|
|
@@ -698,36 +538,50 @@ class MpxWebpackPlugin {
|
|
|
698
538
|
isMain = true
|
|
699
539
|
}
|
|
700
540
|
}
|
|
541
|
+
// todo forceMainPackageRules规则目前只能处理当前资源,不能处理资源子树,配置不当有可能会导致资源引用错误
|
|
701
542
|
if (!isMain || isIndependent) {
|
|
702
543
|
packageRoot = currentPackageRoot
|
|
703
544
|
packageName = currentPackageName
|
|
704
|
-
if (this.options.auditResource && resourceType !== '
|
|
705
|
-
if (this.options.auditResource !== 'component' || resourceType === '
|
|
545
|
+
if (this.options.auditResource && resourceType !== 'subpackageModules' && !isIndependent) {
|
|
546
|
+
if (this.options.auditResource !== 'component' || resourceType === 'components') {
|
|
706
547
|
Object.keys(resourceMap).filter(key => key !== 'main').forEach((key) => {
|
|
707
548
|
if (resourceMap[key][resourcePath] && key !== packageName) {
|
|
708
|
-
warn && warn(new Error(`当前${resourceType === '
|
|
549
|
+
warn && warn(new Error(`当前${resourceType === 'components' ? '组件' : '静态'}资源${resourcePath}在分包${key}和分包${packageName}中都有引用,会分别输出到两个分包中,为了总体积最优,可以在主包中建立引用声明以消除资源输出冗余!`))
|
|
709
550
|
}
|
|
710
551
|
})
|
|
711
552
|
}
|
|
712
553
|
}
|
|
713
554
|
}
|
|
714
|
-
resourceMap[packageName] = resourceMap[packageName] || {}
|
|
715
555
|
}
|
|
716
556
|
|
|
717
|
-
|
|
557
|
+
resourceMap[packageName] = resourceMap[packageName] || {}
|
|
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
|
+
}
|
|
718
579
|
|
|
719
580
|
return {
|
|
720
581
|
packageName,
|
|
721
582
|
packageRoot,
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
resourcePath,
|
|
725
|
-
resourceType,
|
|
726
|
-
outputPath,
|
|
727
|
-
packageRoot,
|
|
728
|
-
warn,
|
|
729
|
-
error
|
|
730
|
-
})
|
|
583
|
+
outputPath,
|
|
584
|
+
alreadyOutputed
|
|
731
585
|
}
|
|
732
586
|
}
|
|
733
587
|
}
|
|
@@ -735,110 +589,18 @@ class MpxWebpackPlugin {
|
|
|
735
589
|
|
|
736
590
|
const rawProcessModuleDependencies = compilation.processModuleDependencies
|
|
737
591
|
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
|
|
751
592
|
let proxyedCallback = callback
|
|
752
|
-
if (
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
return callback(err, module)
|
|
593
|
+
if (module.rawRequest === mpx.appScriptRawRequest) {
|
|
594
|
+
// 避免模块request重名,只对第一次匹配到的模块进行代理
|
|
595
|
+
mpx.appScriptRawRequest = ''
|
|
596
|
+
proxyedCallback = (err) => {
|
|
597
|
+
mpx.appScriptPromiseResolve()
|
|
598
|
+
return callback(err)
|
|
759
599
|
}
|
|
760
600
|
}
|
|
761
|
-
return
|
|
601
|
+
return rawProcessModuleDependencies.apply(compilation, [module, proxyedCallback])
|
|
762
602
|
}
|
|
763
603
|
|
|
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
|
-
|
|
842
604
|
compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
|
|
843
605
|
// 自动跟进分包配置修改splitChunksPlugin配置
|
|
844
606
|
if (splitChunksPlugin) {
|
|
@@ -850,15 +612,45 @@ class MpxWebpackPlugin {
|
|
|
850
612
|
}
|
|
851
613
|
})
|
|
852
614
|
if (needInit) {
|
|
853
|
-
splitChunksPlugin.options =
|
|
615
|
+
splitChunksPlugin.options = SplitChunksPlugin.normalizeOptions(splitChunksOptions)
|
|
854
616
|
}
|
|
855
617
|
}
|
|
856
618
|
})
|
|
857
619
|
|
|
858
|
-
|
|
620
|
+
compilation.hooks.optimizeModules.tap('MpxWebpackPlugin', (modules) => {
|
|
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) => {
|
|
859
651
|
// 处理dll产生的external模块
|
|
860
652
|
if (module.external && module.userRequest.startsWith('dll-reference ') && mpx.mode !== 'web') {
|
|
861
|
-
const chunk =
|
|
653
|
+
const chunk = options.chunk
|
|
862
654
|
const request = module.request
|
|
863
655
|
let relativePath = toPosix(path.relative(path.dirname(chunk.name), request))
|
|
864
656
|
if (!/^\.\.?\//.test(relativePath)) relativePath = './' + relativePath
|
|
@@ -869,141 +661,133 @@ class MpxWebpackPlugin {
|
|
|
869
661
|
return source
|
|
870
662
|
})
|
|
871
663
|
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
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
|
-
})
|
|
885
|
-
|
|
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!`))
|
|
664
|
+
compilation.hooks.additionalAssets.tapAsync('MpxWebpackPlugin', (callback) => {
|
|
665
|
+
for (let file in additionalAssets) {
|
|
666
|
+
let content = new ConcatSource()
|
|
667
|
+
if (additionalAssets[file].prefix) {
|
|
668
|
+
additionalAssets[file].prefix.forEach((item) => {
|
|
669
|
+
if (item) content.add(item)
|
|
670
|
+
})
|
|
893
671
|
}
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
672
|
+
additionalAssets[file].forEach((item) => {
|
|
673
|
+
if (item) content.add(item)
|
|
674
|
+
})
|
|
675
|
+
const modules = (additionalAssets[file].modules || []).concat(additionalAssets[file].relativeModules || [])
|
|
898
676
|
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
677
|
+
if (modules.length > 1) {
|
|
678
|
+
// 同步relativeModules和modules之间的依赖
|
|
679
|
+
const fileDependencies = new Set()
|
|
680
|
+
const contextDependencies = new Set()
|
|
902
681
|
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
}
|
|
914
|
-
fillExtractedAssetsMap(extractedInfo.pre ? extractedAssets[0] : extractedAssets[1], extractedInfo, filename)
|
|
915
|
-
compilation.hooks.moduleAsset.call(module, filename)
|
|
916
|
-
}
|
|
682
|
+
modules.forEach((module) => {
|
|
683
|
+
module.buildInfo.fileDependencies.forEach((fileDependency) => {
|
|
684
|
+
fileDependencies.add(fileDependency)
|
|
685
|
+
})
|
|
686
|
+
module.buildInfo.contextDependencies.forEach((contextDependency) => {
|
|
687
|
+
contextDependencies.add(contextDependency)
|
|
688
|
+
})
|
|
689
|
+
module.buildInfo.fileDependencies = fileDependencies
|
|
690
|
+
module.buildInfo.contextDependencies = contextDependencies
|
|
691
|
+
})
|
|
917
692
|
}
|
|
693
|
+
compilation.emitAsset(file, content, { modules: additionalAssets[file].modules })
|
|
918
694
|
}
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
const
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
source.add(content)
|
|
932
|
-
}
|
|
695
|
+
// 所有编译的静态资源assetsInfo合入主编译
|
|
696
|
+
mpx.assetsInfo.forEach((assetInfo, name) => {
|
|
697
|
+
const oldAssetInfo = compilation.assetsInfo.get(name)
|
|
698
|
+
if (oldAssetInfo && oldAssetInfo.modules) {
|
|
699
|
+
assetInfo.modules = assetInfo.modules.concat(oldAssetInfo.modules)
|
|
700
|
+
}
|
|
701
|
+
compilation.assetsInfo.set(name, assetInfo)
|
|
702
|
+
})
|
|
703
|
+
// 链接主编译模块与子编译入口
|
|
704
|
+
Object.values(mpx.wxsMap).concat(Object.values(mpx.extractedMap)).forEach((item) => {
|
|
705
|
+
item.modules.forEach((module) => {
|
|
706
|
+
module.addDependency(item.dep)
|
|
933
707
|
})
|
|
934
|
-
|
|
935
|
-
|
|
708
|
+
})
|
|
709
|
+
|
|
710
|
+
callback()
|
|
936
711
|
})
|
|
937
712
|
|
|
938
713
|
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
|
+
|
|
939
719
|
parser.hooks.call.for('__mpx_resolve_path__').tap('MpxWebpackPlugin', (expr) => {
|
|
940
720
|
if (expr.arguments[0]) {
|
|
941
721
|
const resource = expr.arguments[0].value
|
|
942
|
-
const
|
|
943
|
-
const
|
|
722
|
+
const { queryObj } = parseRequest(resource)
|
|
723
|
+
const packageName = queryObj.packageRoot || 'main'
|
|
724
|
+
const pagesMap = mpx.pagesMap
|
|
725
|
+
const componentsMap = mpx.componentsMap
|
|
726
|
+
const staticResourcesMap = mpx.staticResourcesMap
|
|
944
727
|
const range = expr.range
|
|
945
|
-
const
|
|
946
|
-
|
|
728
|
+
const issuerResource = parser.state.module.issuer.resource
|
|
729
|
+
const dep = new ResolveDependency(resource, packageName, pagesMap, componentsMap, staticResourcesMap, publicPath, range, issuerResource, compilation)
|
|
730
|
+
parser.state.current.addDependency(dep)
|
|
947
731
|
return true
|
|
948
732
|
}
|
|
949
733
|
})
|
|
950
734
|
|
|
951
|
-
|
|
952
|
-
const
|
|
953
|
-
|
|
954
|
-
const
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
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
|
|
983
|
-
}
|
|
735
|
+
const transHandler = (expr) => {
|
|
736
|
+
const module = parser.state.module
|
|
737
|
+
const current = parser.state.current
|
|
738
|
+
const { queryObj, resourcePath } = parseRequest(module.resource)
|
|
739
|
+
const localSrcMode = queryObj.mode
|
|
740
|
+
const globalSrcMode = mpx.srcMode
|
|
741
|
+
const srcMode = localSrcMode || globalSrcMode
|
|
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
|
|
984
753
|
}
|
|
985
|
-
}
|
|
986
754
|
|
|
987
|
-
|
|
988
|
-
.for('require')
|
|
989
|
-
.tap({
|
|
990
|
-
name: 'MpxWebpackPlugin',
|
|
991
|
-
stage: -1000
|
|
992
|
-
}, (expr, members) => requireAsyncHandler(expr, members))
|
|
755
|
+
const type = target.name
|
|
993
756
|
|
|
994
|
-
|
|
995
|
-
.
|
|
996
|
-
.tap({
|
|
997
|
-
name: 'MpxWebpackPlugin',
|
|
998
|
-
stage: -1000
|
|
999
|
-
}, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers))
|
|
757
|
+
const name = type === 'wx' ? 'mpx' : 'createFactory'
|
|
758
|
+
const replaceContent = type === 'wx' ? '__webpack_require__.n(mpx)()' : `__webpack_require__.n(createFactory)()(${JSON.stringify(type)})`
|
|
1000
759
|
|
|
760
|
+
const dep = new ReplaceDependency(replaceContent, target.range)
|
|
761
|
+
current.addDependency(dep)
|
|
762
|
+
|
|
763
|
+
let needInject = true
|
|
764
|
+
for (let v of module.variables) {
|
|
765
|
+
if (v.name === name) {
|
|
766
|
+
needInject = false
|
|
767
|
+
break
|
|
768
|
+
}
|
|
769
|
+
}
|
|
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
|
+
}
|
|
1001
785
|
// hack babel polyfill global
|
|
1002
786
|
parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
|
|
1003
787
|
if (/core-js.+microtask/.test(parser.state.module.resource)) {
|
|
1004
788
|
if (expr.test.left && (expr.test.left.name === 'Observer' || expr.test.left.name === 'MutationObserver')) {
|
|
1005
789
|
const current = parser.state.current
|
|
1006
|
-
current.
|
|
790
|
+
current.addDependency(new InjectDependency({
|
|
1007
791
|
content: 'document && ',
|
|
1008
792
|
index: expr.test.range[0]
|
|
1009
793
|
}))
|
|
@@ -1019,7 +803,7 @@ class MpxWebpackPlugin {
|
|
|
1019
803
|
// todo 该逻辑在corejs3中不需要,等corejs3比较普及之后可以干掉
|
|
1020
804
|
if (/core-js.+global/.test(parser.state.module.resource)) {
|
|
1021
805
|
if (callee.name === 'Function' && arg0 && arg0.value === 'return this') {
|
|
1022
|
-
current.
|
|
806
|
+
current.addDependency(new InjectDependency({
|
|
1023
807
|
content: '(function() { return this })() || ',
|
|
1024
808
|
index: expr.range[0]
|
|
1025
809
|
}))
|
|
@@ -1027,169 +811,102 @@ class MpxWebpackPlugin {
|
|
|
1027
811
|
}
|
|
1028
812
|
if (/regenerator-runtime/.test(parser.state.module.resource)) {
|
|
1029
813
|
if (callee.name === 'Function' && arg0 && arg0.value === 'r' && arg1 && arg1.value === 'regeneratorRuntime = r') {
|
|
1030
|
-
current.
|
|
814
|
+
current.addDependency(new ReplaceDependency('(function () {})', expr.range))
|
|
1031
815
|
}
|
|
1032
816
|
}
|
|
1033
817
|
})
|
|
1034
818
|
|
|
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
|
-
|
|
1056
819
|
if (mpx.srcMode !== mpx.mode) {
|
|
1057
|
-
//
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
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)
|
|
820
|
+
// 全量替换未声明的wx identifier
|
|
821
|
+
parser.hooks.expression.for('wx').tap('MpxWebpackPlugin', transHandler)
|
|
822
|
+
|
|
823
|
+
// parser.hooks.evaluate.for('MemberExpression').tap('MpxWebpackPlugin', (expr) => {
|
|
824
|
+
// // Undeclared varible for wx[identifier]()
|
|
825
|
+
// // TODO Unable to handle wx[identifier]
|
|
826
|
+
// if (expr.object.name === 'wx' && !parser.scope.definitions.has('wx')) {
|
|
827
|
+
// transHandler(expr)
|
|
828
|
+
// }
|
|
829
|
+
// })
|
|
830
|
+
// // Trans for wx.xx, wx['xx'], wx.xx(), wx['xx']()
|
|
831
|
+
// parser.hooks.expressionAnyMember.for('wx').tap('MpxWebpackPlugin', transHandler)
|
|
1098
832
|
// Proxy ctor for transMode
|
|
1099
833
|
if (!this.options.forceDisableProxyCtor) {
|
|
1100
834
|
parser.hooks.call.for('Page').tap('MpxWebpackPlugin', (expr) => {
|
|
1101
|
-
|
|
835
|
+
transHandler(expr.callee)
|
|
1102
836
|
})
|
|
1103
837
|
parser.hooks.call.for('Component').tap('MpxWebpackPlugin', (expr) => {
|
|
1104
|
-
|
|
838
|
+
transHandler(expr.callee)
|
|
1105
839
|
})
|
|
1106
840
|
parser.hooks.call.for('App').tap('MpxWebpackPlugin', (expr) => {
|
|
1107
|
-
|
|
841
|
+
transHandler(expr.callee)
|
|
1108
842
|
})
|
|
1109
843
|
if (mpx.mode === 'ali' || mpx.mode === 'web') {
|
|
1110
844
|
// 支付宝和web不支持Behaviors
|
|
1111
845
|
parser.hooks.call.for('Behavior').tap('MpxWebpackPlugin', (expr) => {
|
|
1112
|
-
|
|
846
|
+
transHandler(expr.callee)
|
|
1113
847
|
})
|
|
1114
848
|
}
|
|
1115
849
|
}
|
|
850
|
+
}
|
|
1116
851
|
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
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)
|
|
852
|
+
const apiBlackListMap = [
|
|
853
|
+
'createApp',
|
|
854
|
+
'createPage',
|
|
855
|
+
'createComponent',
|
|
856
|
+
'createStore',
|
|
857
|
+
'createStoreWithThis',
|
|
858
|
+
'mixin',
|
|
859
|
+
'injectMixins',
|
|
860
|
+
'toPureObject',
|
|
861
|
+
'observable',
|
|
862
|
+
'watch',
|
|
863
|
+
'use',
|
|
864
|
+
'set',
|
|
865
|
+
'remove',
|
|
866
|
+
'delete: del',
|
|
867
|
+
'setConvertRule',
|
|
868
|
+
'getMixin',
|
|
869
|
+
'getComputed',
|
|
870
|
+
'implement'
|
|
871
|
+
].reduce((map, api) => {
|
|
872
|
+
map[api] = true
|
|
873
|
+
return map
|
|
874
|
+
}, {})
|
|
875
|
+
|
|
876
|
+
const handler = (expr) => {
|
|
877
|
+
const callee = expr.callee
|
|
878
|
+
const args = expr.arguments
|
|
879
|
+
const name = callee.object.name
|
|
880
|
+
const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
|
|
881
|
+
const localSrcMode = queryObj.mode
|
|
882
|
+
const globalSrcMode = mpx.srcMode
|
|
883
|
+
const srcMode = localSrcMode || globalSrcMode
|
|
884
|
+
|
|
885
|
+
if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) {
|
|
886
|
+
return
|
|
1163
887
|
}
|
|
1164
888
|
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
889
|
+
const srcModeString = `__mpx_src_mode_${srcMode}__`
|
|
890
|
+
const dep = new InjectDependency({
|
|
891
|
+
content: args.length
|
|
892
|
+
? `, ${JSON.stringify(srcModeString)}`
|
|
893
|
+
: JSON.stringify(srcModeString),
|
|
894
|
+
index: expr.end - 1
|
|
895
|
+
})
|
|
896
|
+
parser.state.current.addDependency(dep)
|
|
1168
897
|
}
|
|
1169
|
-
})
|
|
1170
898
|
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
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)
|
|
899
|
+
if (mpx.srcMode !== mpx.mode) {
|
|
900
|
+
parser.hooks.callAnyMember.for('imported var').tap('MpxWebpackPlugin', handler)
|
|
901
|
+
parser.hooks.callAnyMember.for('mpx').tap('MpxWebpackPlugin', handler)
|
|
902
|
+
parser.hooks.callAnyMember.for('wx').tap('MpxWebpackPlugin', handler)
|
|
1187
903
|
}
|
|
904
|
+
})
|
|
1188
905
|
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
906
|
+
// 为了正确生成sourceMap,将该步骤由原来的compile.hooks.emit迁移到compilation.hooks.optimizeChunkAssets中来
|
|
907
|
+
compilation.hooks.optimizeChunkAssets.tapAsync('MpxWebpackPlugin', (chunks, callback) => {
|
|
908
|
+
if (mpx.mode === 'web') return callback()
|
|
909
|
+
const jsonpFunction = compilation.outputOptions.jsonpFunction
|
|
1193
910
|
|
|
1194
911
|
function getTargetFile (file) {
|
|
1195
912
|
let targetFile = file
|
|
@@ -1201,23 +918,21 @@ class MpxWebpackPlugin {
|
|
|
1201
918
|
}
|
|
1202
919
|
|
|
1203
920
|
const processedChunk = new Set()
|
|
1204
|
-
const
|
|
921
|
+
const rootName = compilation._preparedEntrypoints[0].name
|
|
1205
922
|
|
|
1206
923
|
function processChunk (chunk, isRuntime, relativeChunks) {
|
|
1207
|
-
|
|
1208
|
-
if (!chunkFile || processedChunk.has(chunk)) {
|
|
924
|
+
if (!chunk.files[0] || processedChunk.has(chunk)) {
|
|
1209
925
|
return
|
|
1210
926
|
}
|
|
1211
927
|
|
|
1212
|
-
let originalSource = compilation.assets[
|
|
928
|
+
let originalSource = compilation.assets[chunk.files[0]]
|
|
1213
929
|
const source = new ConcatSource()
|
|
1214
|
-
source.add(
|
|
930
|
+
source.add('\nvar window = window || {};\n\n')
|
|
1215
931
|
|
|
1216
932
|
relativeChunks.forEach((relativeChunk, index) => {
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
let
|
|
1220
|
-
let relativePath = getTargetFile(relativeChunkFile)
|
|
933
|
+
if (!relativeChunk.files[0]) return
|
|
934
|
+
let chunkPath = getTargetFile(chunk.files[0])
|
|
935
|
+
let relativePath = getTargetFile(relativeChunk.files[0])
|
|
1221
936
|
relativePath = path.relative(path.dirname(chunkPath), relativePath)
|
|
1222
937
|
relativePath = fixRelative(relativePath, mpx.mode)
|
|
1223
938
|
relativePath = toPosix(relativePath)
|
|
@@ -1225,19 +940,19 @@ class MpxWebpackPlugin {
|
|
|
1225
940
|
// 引用runtime
|
|
1226
941
|
// 支付宝分包独立打包,通过全局context获取webpackJSONP
|
|
1227
942
|
if (mpx.mode === 'ali' && !mpx.isPluginMode) {
|
|
1228
|
-
if (chunk.name ===
|
|
1229
|
-
// 在rootChunk中挂载
|
|
943
|
+
if (chunk.name === rootName) {
|
|
944
|
+
// 在rootChunk中挂载jsonpFunction
|
|
1230
945
|
source.add('// process ali subpackages runtime in root chunk\n' +
|
|
1231
946
|
'var context = (function() { return this })() || Function("return this")();\n\n')
|
|
1232
|
-
source.add(`context[${JSON.stringify(
|
|
947
|
+
source.add(`context[${JSON.stringify(jsonpFunction)}] = window[${JSON.stringify(jsonpFunction)}] = require("${relativePath}");\n`)
|
|
1233
948
|
} else {
|
|
1234
949
|
// 其余chunk中通过context全局传递runtime
|
|
1235
950
|
source.add('// process ali subpackages runtime in other chunk\n' +
|
|
1236
951
|
'var context = (function() { return this })() || Function("return this")();\n\n')
|
|
1237
|
-
source.add(
|
|
952
|
+
source.add(`window[${JSON.stringify(jsonpFunction)}] = context[${JSON.stringify(jsonpFunction)}];\n`)
|
|
1238
953
|
}
|
|
1239
954
|
} else {
|
|
1240
|
-
source.add(
|
|
955
|
+
source.add(`window[${JSON.stringify(jsonpFunction)}] = require("${relativePath}");\n`)
|
|
1241
956
|
}
|
|
1242
957
|
} else {
|
|
1243
958
|
source.add(`require("${relativePath}");\n`)
|
|
@@ -1290,12 +1005,18 @@ try {
|
|
|
1290
1005
|
} catch(e){
|
|
1291
1006
|
}\n`)
|
|
1292
1007
|
source.add(originalSource)
|
|
1293
|
-
source.add(`\nmodule.exports =
|
|
1008
|
+
source.add(`\nmodule.exports = window[${JSON.stringify(jsonpFunction)}];\n`)
|
|
1294
1009
|
} 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
|
+
}
|
|
1295
1016
|
source.add(originalSource)
|
|
1296
1017
|
}
|
|
1297
1018
|
|
|
1298
|
-
compilation.assets[
|
|
1019
|
+
compilation.assets[chunk.files[0]] = source
|
|
1299
1020
|
processedChunk.add(chunk)
|
|
1300
1021
|
}
|
|
1301
1022
|
|
|
@@ -1332,109 +1053,57 @@ try {
|
|
|
1332
1053
|
}
|
|
1333
1054
|
}
|
|
1334
1055
|
})
|
|
1056
|
+
|
|
1057
|
+
callback()
|
|
1335
1058
|
})
|
|
1336
1059
|
})
|
|
1337
1060
|
|
|
1338
1061
|
compiler.hooks.normalModuleFactory.tap('MpxWebpackPlugin', (normalModuleFactory) => {
|
|
1339
1062
|
// resolve前修改原始request
|
|
1340
|
-
normalModuleFactory.hooks.beforeResolve.
|
|
1063
|
+
normalModuleFactory.hooks.beforeResolve.tapAsync('MpxWebpackPlugin', (data, callback) => {
|
|
1341
1064
|
let request = data.request
|
|
1342
1065
|
let { queryObj, resource } = parseRequest(request)
|
|
1343
1066
|
if (queryObj.resolve) {
|
|
1344
1067
|
// 此处的query用于将资源引用的当前包信息传递给resolveDependency
|
|
1345
|
-
const
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
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
|
-
})
|
|
1068
|
+
const pathLoader = normalize.lib('path-loader')
|
|
1069
|
+
resource = addQuery(resource, {
|
|
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}`
|
|
1406
1077
|
}
|
|
1407
|
-
createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
|
|
1408
1078
|
}
|
|
1079
|
+
callback(null, data)
|
|
1080
|
+
})
|
|
1409
1081
|
|
|
1410
|
-
|
|
1082
|
+
// resolve完成后修改loaders信息并批量添加mode query
|
|
1083
|
+
normalModuleFactory.hooks.afterResolve.tapAsync('MpxWebpackPlugin', (data, callback) => {
|
|
1084
|
+
if (data.loaders) {
|
|
1085
|
+
const { queryObj } = parseRequest(data.request)
|
|
1411
1086
|
const mpxStyleOptions = queryObj.mpxStyleOptions
|
|
1412
|
-
const firstLoader = loaders[0]
|
|
1413
|
-
const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher
|
|
1087
|
+
const firstLoader = (data.loaders[0] && data.loaders[0].loader) || ''
|
|
1088
|
+
const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher.js')
|
|
1414
1089
|
let cssLoaderIndex = -1
|
|
1415
1090
|
let vueStyleLoaderIndex = -1
|
|
1416
1091
|
let mpxStyleLoaderIndex = -1
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1092
|
+
data.loaders.forEach((loader, index) => {
|
|
1093
|
+
const currentLoader = loader.loader
|
|
1094
|
+
if (currentLoader.includes('ts-loader')) {
|
|
1095
|
+
// todo 暂时固定写死options,待后续优化为复用rules后修正
|
|
1096
|
+
loader.options = { appendTsSuffixTo: [/\.(mpx|vue)$/] }
|
|
1097
|
+
}
|
|
1420
1098
|
if (currentLoader.includes('css-loader')) {
|
|
1421
1099
|
cssLoaderIndex = index
|
|
1422
|
-
} else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader')) {
|
|
1100
|
+
} else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader.js')) {
|
|
1423
1101
|
vueStyleLoaderIndex = index
|
|
1424
|
-
} else if (currentLoader.includes('@
|
|
1425
|
-
tenonStyleLoaderIndex = index
|
|
1426
|
-
} else if (currentLoader.includes(styleCompilerPath)) {
|
|
1102
|
+
} else if (currentLoader.includes('@mpxjs/webpack-plugin/lib/style-compiler/index.js')) {
|
|
1427
1103
|
mpxStyleLoaderIndex = index
|
|
1428
1104
|
}
|
|
1429
1105
|
})
|
|
1430
|
-
if (
|
|
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) {
|
|
1106
|
+
if (mpxStyleLoaderIndex === -1) {
|
|
1438
1107
|
let loaderIndex = -1
|
|
1439
1108
|
if (cssLoaderIndex > -1 && vueStyleLoaderIndex === -1) {
|
|
1440
1109
|
loaderIndex = cssLoaderIndex
|
|
@@ -1442,70 +1111,37 @@ try {
|
|
|
1442
1111
|
loaderIndex = vueStyleLoaderIndex
|
|
1443
1112
|
}
|
|
1444
1113
|
if (loaderIndex > -1) {
|
|
1445
|
-
loaders.splice(loaderIndex + 1, 0, {
|
|
1446
|
-
loader:
|
|
1114
|
+
data.loaders.splice(loaderIndex + 1, 0, {
|
|
1115
|
+
loader: normalize.lib('style-compiler/index.js'),
|
|
1447
1116
|
options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
|
|
1448
1117
|
})
|
|
1449
1118
|
}
|
|
1450
1119
|
}
|
|
1451
1120
|
}
|
|
1452
|
-
|
|
1453
|
-
createData.request = stringifyLoadersAndResource(loaders, createData.resource)
|
|
1454
1121
|
// 根据用户传入的modeRules对特定资源添加mode query
|
|
1455
|
-
this.runModeRules(
|
|
1122
|
+
this.runModeRules(data)
|
|
1123
|
+
callback(null, data)
|
|
1456
1124
|
})
|
|
1457
1125
|
})
|
|
1458
1126
|
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
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)
|
|
1127
|
+
compiler.hooks.emit.tapAsync('MpxWebpackPlugin', (compilation, callback) => {
|
|
1128
|
+
if (this.options.generateBuildMap) {
|
|
1129
|
+
const pagesMap = compilation.__mpx__.pagesMap
|
|
1130
|
+
const componentsPackageMap = compilation.__mpx__.componentsMap
|
|
1131
|
+
const componentsMap = Object.keys(componentsPackageMap).map(item => componentsPackageMap[item]).reduce((pre, cur) => {
|
|
1132
|
+
return { ...pre, ...cur }
|
|
1133
|
+
}, {})
|
|
1134
|
+
const outputMap = JSON.stringify({ ...pagesMap, ...componentsMap })
|
|
1135
|
+
compilation.assets['../outputMap.json'] = {
|
|
1136
|
+
source: () => {
|
|
1137
|
+
return outputMap
|
|
1138
|
+
},
|
|
1139
|
+
size: () => {
|
|
1140
|
+
return Buffer.byteLength(outputMap, 'utf8')
|
|
1494
1141
|
}
|
|
1495
|
-
rm(cacheLocation, resolve)
|
|
1496
1142
|
}
|
|
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
|
-
])
|
|
1508
1143
|
}
|
|
1144
|
+
callback()
|
|
1509
1145
|
})
|
|
1510
1146
|
}
|
|
1511
1147
|
}
|