@mpxjs/webpack-plugin 2.8.39 → 2.8.40-test

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.
Files changed (51) hide show
  1. package/lib/dependencies/CommonJsExtractDependency.js +51 -0
  2. package/lib/dependencies/ResolveDependency.js +11 -9
  3. package/lib/extractor.js +1 -0
  4. package/lib/helpers.js +9 -1
  5. package/lib/index.js +173 -72
  6. package/lib/json-compiler/helper.js +25 -9
  7. package/lib/json-compiler/index.js +77 -28
  8. package/lib/loader.js +3 -10
  9. package/lib/native-loader.js +21 -14
  10. package/lib/platform/json/wx/index.js +65 -2
  11. package/lib/platform/run-rules.js +2 -1
  12. package/lib/platform/template/normalize-component-rules.js +2 -0
  13. package/lib/platform/template/wx/component-config/README.md +1 -1
  14. package/lib/platform/template/wx/component-config/fix-html-tag.js +17 -0
  15. package/lib/platform/template/wx/component-config/hypen-tag-name.js +2 -6
  16. package/lib/platform/template/wx/component-config/index.js +4 -2
  17. package/lib/platform/template/wx/component-config/view.js +0 -11
  18. package/lib/platform/template/wx/index.js +65 -18
  19. package/lib/runtime/base.styl +0 -5
  20. package/lib/runtime/components/web/filterTag.js +9 -30
  21. package/lib/runtime/components/web/getInnerListeners.js +2 -14
  22. package/lib/runtime/components/web/mpx-keep-alive.vue +10 -17
  23. package/lib/runtime/components/web/mpx-movable-view.vue +105 -23
  24. package/lib/runtime/components/web/mpx-picker-view.vue +1 -1
  25. package/lib/runtime/components/web/mpx-scroll-view.vue +69 -23
  26. package/lib/runtime/components/web/mpx-swiper.vue +152 -62
  27. package/lib/runtime/components/web/mpx-video.vue +123 -89
  28. package/lib/runtime/components/web/mpx-web-view.vue +120 -81
  29. package/lib/runtime/components/web/promisify.js +19 -0
  30. package/lib/runtime/components/wx/default-page.mpx +27 -0
  31. package/lib/runtime/optionProcessor.js +12 -18
  32. package/lib/style-compiler/index.js +5 -1
  33. package/lib/template-compiler/bind-this.js +280 -49
  34. package/lib/template-compiler/compiler.js +54 -58
  35. package/lib/template-compiler/index.js +35 -23
  36. package/lib/utils/dom-tag-config.js +115 -0
  37. package/lib/utils/make-map.js +12 -0
  38. package/lib/utils/string.js +7 -1
  39. package/lib/utils/ts-loader-watch-run-loader-filter.js +4 -5
  40. package/lib/web/processJSON.js +35 -0
  41. package/lib/web/processScript.js +7 -4
  42. package/lib/web/processTemplate.js +7 -34
  43. package/package.json +4 -4
  44. package/lib/partial-compile/index.js +0 -35
  45. package/lib/template-compiler/preprocessor.js +0 -29
  46. package/lib/wxss/compile-exports.js +0 -52
  47. package/lib/wxss/createResolver.js +0 -36
  48. package/lib/wxss/css-base.js +0 -79
  49. package/lib/wxss/getLocalIdent.js +0 -25
  50. package/lib/wxss/localsLoader.js +0 -44
  51. package/lib/wxss/processCss.js +0 -274
@@ -0,0 +1,51 @@
1
+ const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+
4
+ class CommonJsExtractDependency extends ModuleDependency {
5
+ constructor (request, range) {
6
+ super(request)
7
+ this.range = range
8
+ }
9
+
10
+ get type () {
11
+ return 'mpx cjs extract'
12
+ }
13
+
14
+ get category () {
15
+ return 'commonjs'
16
+ }
17
+ }
18
+
19
+ CommonJsExtractDependency.Template = class CommonJsExtractDependencyTemplate extends (
20
+ ModuleDependency.Template
21
+ ) {
22
+ apply (
23
+ dep,
24
+ source,
25
+ {
26
+ runtimeTemplate,
27
+ moduleGraph,
28
+ chunkGraph,
29
+ runtimeRequirements
30
+ }
31
+ ) {
32
+ let content = ''
33
+ if (!dep.weak) {
34
+ content = runtimeTemplate.moduleExports({
35
+ module: moduleGraph.getModule(dep),
36
+ chunkGraph,
37
+ request: dep.request,
38
+ weak: dep.weak,
39
+ runtimeRequirements
40
+ })
41
+ }
42
+ source.replace(dep.range[0], dep.range[1] - 1, content)
43
+ }
44
+ }
45
+
46
+ makeSerializable(
47
+ CommonJsExtractDependency,
48
+ '@mpxjs/webpack-plugin/lib/dependencies/CommonJsExtractDependency'
49
+ )
50
+
51
+ module.exports = CommonJsExtractDependency
@@ -1,6 +1,7 @@
1
1
  const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
2
  const parseRequest = require('../utils/parse-request')
3
3
  const makeSerializable = require('webpack/lib/util/makeSerializable')
4
+ const { matchCondition } = require('../utils/match-condition')
4
5
 
5
6
  class ResolveDependency extends NullDependency {
6
7
  constructor (resource, packageName, issuerResource, range) {
@@ -22,28 +23,29 @@ class ResolveDependency extends NullDependency {
22
23
  }
23
24
 
24
25
  getResolved () {
25
- const { resource, packageName, compilation } = this
26
+ const { resource, packageName, compilation, issuerResource } = this
26
27
  if (!compilation) return ''
27
28
  const mpx = compilation.__mpx__
28
29
  if (!mpx) return ''
29
- const { pagesMap, componentsMap, staticResourcesMap } = mpx
30
+ const { pagesMap, componentsMap, staticResourcesMap, partialCompile } = mpx
30
31
  const { resourcePath } = parseRequest(resource)
31
32
  const currentComponentsMap = componentsMap[packageName]
32
33
  const mainComponentsMap = componentsMap.main
33
34
  const currentStaticResourcesMap = staticResourcesMap[packageName]
34
35
  const mainStaticResourcesMap = staticResourcesMap.main
35
- return pagesMap[resourcePath] || currentComponentsMap[resourcePath] || mainComponentsMap[resourcePath] || currentStaticResourcesMap[resourcePath] || mainStaticResourcesMap[resourcePath] || ''
36
+ const resolveResult = pagesMap[resourcePath] || currentComponentsMap[resourcePath] || mainComponentsMap[resourcePath] || currentStaticResourcesMap[resourcePath] || mainStaticResourcesMap[resourcePath] || ''
37
+ if (!resolveResult) {
38
+ if (!partialCompile || matchCondition(resourcePath, partialCompile)) {
39
+ compilation.errors.push(new Error(`Path ${resource} is not a page/component/static resource, which is resolved from ${issuerResource}!`))
40
+ }
41
+ }
42
+ return resolveResult
36
43
  }
37
44
 
38
45
  // resolved可能会动态变更,需用此更新hash
39
46
  updateHash (hash, context) {
40
47
  this.resolved = this.getResolved()
41
- const { resource, issuerResource, compilation } = this
42
- if (this.resolved) {
43
- hash.update(this.resolved)
44
- } else {
45
- compilation.errors.push(new Error(`Path ${resource} is not a page/component/static resource, which is resolved from ${issuerResource}!`))
46
- }
48
+ hash.update(this.resolved)
47
49
  super.updateHash(hash, context)
48
50
  }
49
51
 
package/lib/extractor.js CHANGED
@@ -116,5 +116,6 @@ module.exports.pitch = async function (remainingRequest) {
116
116
  }
117
117
  }
118
118
 
119
+ if (!resultSource) buildInfo.isEmpty = true
119
120
  return resultSource
120
121
  }
package/lib/helpers.js CHANGED
@@ -20,7 +20,15 @@ module.exports = function createHelpers (loaderContext) {
20
20
  const { mode, env } = loaderContext.getMpx() || {}
21
21
 
22
22
  function getRequire (type, part, extraOptions, index) {
23
- return 'require(' + getRequestString(type, part, extraOptions, index) + ')'
23
+ let extract = false
24
+ switch (type) {
25
+ // eslint-disable-next-line no-fallthrough
26
+ case 'json':
27
+ case 'styles':
28
+ case 'template':
29
+ extract = true
30
+ }
31
+ return (extract ? 'require.extract(' : 'require(') + getRequestString(type, part, extraOptions, index) + ')'
24
32
  }
25
33
 
26
34
  function getImport (type, part, extraOptions, index) {
package/lib/index.js CHANGED
@@ -8,7 +8,7 @@ const ReplaceDependency = require('./dependencies/ReplaceDependency')
8
8
  const NullFactory = require('webpack/lib/NullFactory')
9
9
  const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
10
10
  const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
11
- const harmonySpecifierTag = require('webpack/lib/dependencies/HarmonyImportDependencyParserPlugin').harmonySpecifierTag
11
+ const CommonJsExtractDependency = require('./dependencies/CommonJsExtractDependency')
12
12
  const NormalModule = require('webpack/lib/NormalModule')
13
13
  const EntryPlugin = require('webpack/lib/EntryPlugin')
14
14
  const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
@@ -38,7 +38,6 @@ const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
38
38
  const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
39
39
  const RecordVueContentDependency = require('./dependencies/RecordVueContentDependency')
40
40
  const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
41
- const PartialCompilePlugin = require('./partial-compile/index')
42
41
  const fixRelative = require('./utils/fix-relative')
43
42
  const parseRequest = require('./utils/parse-request')
44
43
  const { matchCondition } = require('./utils/match-condition')
@@ -55,6 +54,7 @@ const jsonThemeCompilerPath = normalize.lib('json-compiler/theme')
55
54
  const jsonPluginCompilerPath = normalize.lib('json-compiler/plugin')
56
55
  const extractorPath = normalize.lib('extractor')
57
56
  const async = require('async')
57
+ const { parseQuery } = require('loader-utils')
58
58
  const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
59
59
  const emitFile = require('./utils/emit-file')
60
60
  const { MPX_PROCESSED_FLAG, MPX_DISABLE_EXTRACTOR_CACHE } = require('./utils/const')
@@ -167,8 +167,11 @@ class MpxWebpackPlugin {
167
167
  }, options.nativeConfig)
168
168
  options.webConfig = options.webConfig || {}
169
169
  options.partialCompile = options.mode !== 'web' && options.partialCompile
170
+ options.asyncSubpackageRules = options.asyncSubpackageRules || []
171
+ options.optimizeRenderRules = options.optimizeRenderRules || {}
170
172
  options.retryRequireAsync = options.retryRequireAsync || false
171
173
  options.enableAliRequireAsync = options.enableAliRequireAsync || false
174
+ options.optimizeSize = options.optimizeSize || false
172
175
  this.options = options
173
176
  // Hack for buildDependencies
174
177
  const rawResolveBuildDependencies = FileSystemInfo.prototype.resolveBuildDependencies
@@ -293,6 +296,14 @@ class MpxWebpackPlugin {
293
296
  warnings.push(`webpack options: MpxWebpackPlugin accept options.output.filename to be ${outputFilename} only, custom options.output.filename will be ignored!`)
294
297
  }
295
298
  compiler.options.output.filename = compiler.options.output.chunkFilename = outputFilename
299
+ if (this.options.optimizeSize) {
300
+ compiler.options.optimization.chunkIds = 'total-size'
301
+ compiler.options.optimization.moduleIds = 'natural'
302
+ compiler.options.optimization.mangleExports = 'size'
303
+ compiler.options.output.globalObject = 'g'
304
+ // todo chunkLoadingGlobal不具备项目唯一性,在多构建产物混编时可能存在问题,尤其在支付宝使用全局对象传递的情况下
305
+ compiler.options.output.chunkLoadingGlobal = 'c'
306
+ }
296
307
  }
297
308
 
298
309
  if (!compiler.options.node || !compiler.options.node.global) {
@@ -381,7 +392,34 @@ class MpxWebpackPlugin {
381
392
  let mpx
382
393
 
383
394
  if (this.options.partialCompile) {
384
- new PartialCompilePlugin(this.options.partialCompile).apply(compiler)
395
+ function isResolvingPage (obj) {
396
+ // valid query should start with '?'
397
+ const query = parseQuery(obj.query || '?')
398
+ return query.isPage && !query.type
399
+ }
400
+
401
+ // new PartialCompilePlugin(this.options.partialCompile).apply(compiler)
402
+ compiler.resolverFactory.hooks.resolver.intercept({
403
+ factory: (type, hook) => {
404
+ hook.tap('MpxPartialCompilePlugin', (resolver) => {
405
+ resolver.hooks.result.tapAsync({
406
+ name: 'MpxPartialCompilePlugin',
407
+ stage: -100
408
+ }, (obj, resolverContext, callback) => {
409
+ if (obj.path.startsWith(require.resolve('./runtime/components/wx/default-page.mpx'))) {
410
+ return callback(null, obj)
411
+ }
412
+ if (isResolvingPage(obj) && !matchCondition(obj.path, this.options.partialCompile)) {
413
+ const infix = obj.query ? '&' : '?'
414
+ obj.query += `${infix}resourcePath=${obj.path}`
415
+ obj.path = require.resolve('./runtime/components/wx/default-page.mpx')
416
+ }
417
+ callback(null, obj)
418
+ })
419
+ })
420
+ return hook
421
+ }
422
+ })
385
423
  }
386
424
 
387
425
  const getPackageCacheGroup = packageName => {
@@ -517,6 +555,9 @@ class MpxWebpackPlugin {
517
555
  compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
518
556
  compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
519
557
 
558
+ compilation.dependencyFactories.set(CommonJsExtractDependency, normalModuleFactory)
559
+ compilation.dependencyTemplates.set(CommonJsExtractDependency, new CommonJsExtractDependency.Template())
560
+
520
561
  compilation.dependencyFactories.set(RecordVueContentDependency, new NullFactory())
521
562
  compilation.dependencyTemplates.set(RecordVueContentDependency, new RecordVueContentDependency.Template())
522
563
  })
@@ -595,6 +636,9 @@ class MpxWebpackPlugin {
595
636
  removedChunks: [],
596
637
  forceProxyEventRules: this.options.forceProxyEventRules,
597
638
  enableRequireAsync: this.options.mode === 'wx' || (this.options.mode === 'ali' && this.options.enableAliRequireAsync),
639
+ partialCompile: this.options.partialCompile,
640
+ asyncSubpackageRules: this.options.asyncSubpackageRules,
641
+ optimizeRenderRules: this.options.optimizeRenderRules,
598
642
  pathHash: (resourcePath) => {
599
643
  if (this.options.pathHashMode === 'relative' && this.options.projectRoot) {
600
644
  return hash(path.relative(this.options.projectRoot, resourcePath))
@@ -656,7 +700,15 @@ class MpxWebpackPlugin {
656
700
  mpx.extractedFilesCache.set(resource, file)
657
701
  return file
658
702
  },
659
- recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', recordOnly, warn, error }) => {
703
+ recordResourceMap: ({
704
+ resourcePath,
705
+ resourceType,
706
+ outputPath,
707
+ packageRoot = '',
708
+ recordOnly,
709
+ warn,
710
+ error
711
+ }) => {
660
712
  const packageName = packageRoot || 'main'
661
713
  const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
662
714
  const currentResourceMap = resourceMap.main ? resourceMap[packageName] = resourceMap[packageName] || {} : resourceMap
@@ -876,6 +928,17 @@ class MpxWebpackPlugin {
876
928
  })
877
929
 
878
930
  compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
931
+ // 移除extractor抽取后的空模块
932
+ for (const module of modules) {
933
+ if (module.buildInfo.isEmpty) {
934
+ for (const connection of moduleGraph.getIncomingConnections(module)) {
935
+ if (connection.dependency.type === 'mpx cjs extract') {
936
+ connection.weak = true
937
+ connection.dependency.weak = true
938
+ }
939
+ }
940
+ }
941
+ }
879
942
  // 自动跟进分包配置修改splitChunksPlugin配置
880
943
  if (splitChunksPlugin) {
881
944
  let needInit = false
@@ -999,13 +1062,22 @@ class MpxWebpackPlugin {
999
1062
  let request = expr.arguments[0].value
1000
1063
  const range = expr.arguments[0].range
1001
1064
  const context = parser.state.module.context
1002
- const { queryObj } = parseRequest(request)
1003
- if (queryObj.root) {
1065
+ const { queryObj, resourcePath } = parseRequest(request)
1066
+ let tarRoot = queryObj.root
1067
+ if (!tarRoot && mpx.asyncSubpackageRules) {
1068
+ for (const item of mpx.asyncSubpackageRules) {
1069
+ if (matchCondition(resourcePath, item)) {
1070
+ tarRoot = item.root
1071
+ break
1072
+ }
1073
+ }
1074
+ }
1075
+ if (tarRoot) {
1004
1076
  // 删除root query
1005
- request = addQuery(request, {}, false, ['root'])
1077
+ if (queryObj.root) request = addQuery(request, {}, false, ['root'])
1006
1078
  // 目前仅wx和ali支持require.async,ali需要开启enableAliRequireAsync,其余平台使用CommonJsAsyncDependency进行模拟抹平
1007
1079
  if (mpx.enableRequireAsync) {
1008
- const dep = new DynamicEntryDependency(request, 'export', '', queryObj.root, '', context, range, {
1080
+ const dep = new DynamicEntryDependency(request, 'export', '', tarRoot, '', context, range, {
1009
1081
  isRequireAsync: true,
1010
1082
  retryRequireAsync: !!this.options.retryRequireAsync
1011
1083
  })
@@ -1040,6 +1112,31 @@ class MpxWebpackPlugin {
1040
1112
  stage: -1000
1041
1113
  }, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers, expr.arguments))
1042
1114
 
1115
+ const requireExtractHandler = (expr, members, args) => {
1116
+ if (members[0] === 'extract') {
1117
+ const request = expr.arguments[0].value
1118
+ const range = expr.range
1119
+ const dep = new CommonJsExtractDependency(request, range)
1120
+ parser.state.current.addDependency(dep)
1121
+ if (args) parser.walkExpressions(args)
1122
+ return true
1123
+ }
1124
+ }
1125
+
1126
+ parser.hooks.callMemberChain
1127
+ .for('require')
1128
+ .tap({
1129
+ name: 'MpxWebpackPlugin',
1130
+ stage: -2000
1131
+ }, (expr, members) => requireExtractHandler(expr, members))
1132
+
1133
+ parser.hooks.callMemberChainOfCallMemberChain
1134
+ .for('require')
1135
+ .tap({
1136
+ name: 'MpxWebpackPlugin',
1137
+ stage: -2000
1138
+ }, (expr, calleeMembers, callExpr) => requireExtractHandler(callExpr, calleeMembers, expr.arguments))
1139
+
1043
1140
  // hack babel polyfill global
1044
1141
  parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
1045
1142
  if (/core-js.+microtask/.test(parser.state.module.resource)) {
@@ -1180,56 +1277,56 @@ class MpxWebpackPlugin {
1180
1277
  }
1181
1278
 
1182
1279
  // 为跨平台api调用注入srcMode参数指导api运行时转换
1183
- const apiBlackListMap = [
1184
- 'createApp',
1185
- 'createPage',
1186
- 'createComponent',
1187
- 'createStore',
1188
- 'createStoreWithThis',
1189
- 'mixin',
1190
- 'injectMixins',
1191
- 'toPureObject',
1192
- 'observable',
1193
- 'watch',
1194
- 'use',
1195
- 'set',
1196
- 'remove',
1197
- 'delete',
1198
- 'setConvertRule',
1199
- 'getMixin',
1200
- 'getComputed',
1201
- 'implement'
1202
- ].reduce((map, api) => {
1203
- map[api] = true
1204
- return map
1205
- }, {})
1206
-
1207
- const injectSrcModeForTransApi = (expr, members) => {
1208
- // members为空数组时,callee并不是memberExpression
1209
- if (!members.length) return
1210
- const callee = expr.callee
1211
- const args = expr.arguments
1212
- const name = callee.object.name
1213
- const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1214
- const localSrcMode = queryObj.mode
1215
- const globalSrcMode = mpx.srcMode
1216
- const srcMode = localSrcMode || globalSrcMode
1217
-
1218
- if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
1219
-
1220
- const srcModeString = `__mpx_src_mode_${srcMode}__`
1221
- const dep = new InjectDependency({
1222
- content: args.length
1223
- ? `, ${JSON.stringify(srcModeString)}`
1224
- : JSON.stringify(srcModeString),
1225
- index: expr.end - 1
1226
- })
1227
- parser.state.current.addPresentationalDependency(dep)
1228
- }
1229
-
1230
- parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1231
- parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1232
- parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1280
+ // const apiBlackListMap = [
1281
+ // 'createApp',
1282
+ // 'createPage',
1283
+ // 'createComponent',
1284
+ // 'createStore',
1285
+ // 'createStoreWithThis',
1286
+ // 'mixin',
1287
+ // 'injectMixins',
1288
+ // 'toPureObject',
1289
+ // 'observable',
1290
+ // 'watch',
1291
+ // 'use',
1292
+ // 'set',
1293
+ // 'remove',
1294
+ // 'delete',
1295
+ // 'setConvertRule',
1296
+ // 'getMixin',
1297
+ // 'getComputed',
1298
+ // 'implement'
1299
+ // ].reduce((map, api) => {
1300
+ // map[api] = true
1301
+ // return map
1302
+ // }, {})
1303
+ //
1304
+ // const injectSrcModeForTransApi = (expr, members) => {
1305
+ // // members为空数组时,callee并不是memberExpression
1306
+ // if (!members.length) return
1307
+ // const callee = expr.callee
1308
+ // const args = expr.arguments
1309
+ // const name = callee.object.name
1310
+ // const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1311
+ // const localSrcMode = queryObj.mode
1312
+ // const globalSrcMode = mpx.srcMode
1313
+ // const srcMode = localSrcMode || globalSrcMode
1314
+ //
1315
+ // if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
1316
+ //
1317
+ // const srcModeString = `__mpx_src_mode_${srcMode}__`
1318
+ // const dep = new InjectDependency({
1319
+ // content: args.length
1320
+ // ? `, ${JSON.stringify(srcModeString)}`
1321
+ // : JSON.stringify(srcModeString),
1322
+ // index: expr.end - 1
1323
+ // })
1324
+ // parser.state.current.addPresentationalDependency(dep)
1325
+ // }
1326
+ //
1327
+ // parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1328
+ // parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1329
+ // parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1233
1330
  }
1234
1331
  }
1235
1332
  normalModuleFactory.hooks.parser.for('javascript/auto').tap('MpxWebpackPlugin', normalModuleFactoryParserCallback)
@@ -1259,6 +1356,8 @@ class MpxWebpackPlugin {
1259
1356
  chunkLoadingGlobal
1260
1357
  } = compilation.outputOptions
1261
1358
 
1359
+ const chunkLoadingGlobalStr = JSON.stringify(chunkLoadingGlobal)
1360
+
1262
1361
  function getTargetFile (file) {
1263
1362
  let targetFile = file
1264
1363
  const queryStringIdx = targetFile.indexOf('?')
@@ -1278,7 +1377,7 @@ class MpxWebpackPlugin {
1278
1377
 
1279
1378
  const originalSource = compilation.assets[chunkFile]
1280
1379
  const source = new ConcatSource()
1281
- source.add(`\nvar ${globalObject} = ${globalObject} || {};\n\n`)
1380
+ source.add(`\nvar ${globalObject} = {};\n`)
1282
1381
 
1283
1382
  relativeChunks.forEach((relativeChunk, index) => {
1284
1383
  const relativeChunkFile = relativeChunk.files.values().next().value
@@ -1295,16 +1394,16 @@ class MpxWebpackPlugin {
1295
1394
  if (compilation.options.entry[chunk.name]) {
1296
1395
  // 在rootChunk中挂载jsonpCallback
1297
1396
  source.add('// process ali subpackages runtime in root chunk\n' +
1298
- 'var context = (function() { return this })() || Function("return this")();\n\n')
1299
- source.add(`context[${JSON.stringify(chunkLoadingGlobal)}] = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
1397
+ 'var context = (function() { return this })() || Function("return this")();\n')
1398
+ source.add(`context[${chunkLoadingGlobalStr}] = ${globalObject}[${chunkLoadingGlobalStr}] = require("${relativePath}");\n`)
1300
1399
  } else {
1301
1400
  // 其余chunk中通过context全局传递runtime
1302
1401
  source.add('// process ali subpackages runtime in other chunk\n' +
1303
- 'var context = (function() { return this })() || Function("return this")();\n\n')
1304
- source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = context[${JSON.stringify(chunkLoadingGlobal)}];\n`)
1402
+ 'var context = (function() { return this })() || Function("return this")();\n')
1403
+ source.add(`${globalObject}[${chunkLoadingGlobalStr}] = context[${chunkLoadingGlobalStr}];\n`)
1305
1404
  }
1306
1405
  } else {
1307
- source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
1406
+ source.add(`${globalObject}[${chunkLoadingGlobalStr}] = require("${relativePath}");\n`)
1308
1407
  }
1309
1408
  } else {
1310
1409
  source.add(`require("${relativePath}");\n`)
@@ -1312,10 +1411,11 @@ class MpxWebpackPlugin {
1312
1411
  })
1313
1412
 
1314
1413
  if (isRuntime) {
1315
- source.add('var context = (function() { return this })() || Function("return this")();\n')
1316
- source.add(`
1414
+ if (mpx.mode === 'ali' || mpx.mode === 'qq') {
1415
+ source.add(`
1317
1416
  // Fix babel runtime in some quirky environment like ali & qq dev.
1318
1417
  try {
1418
+ var context = (function() { return this })() || Function("return this")();
1319
1419
  if(!context.console){
1320
1420
  context.console = console;
1321
1421
  context.setInterval = setInterval;
@@ -1356,8 +1456,9 @@ try {
1356
1456
  }
1357
1457
  } catch(e){
1358
1458
  }\n`)
1459
+ }
1359
1460
  source.add(originalSource)
1360
- source.add(`\nmodule.exports = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}];\n`)
1461
+ source.add(`\nmodule.exports = ${globalObject}[${chunkLoadingGlobalStr}];\n`)
1361
1462
  } else {
1362
1463
  source.add(originalSource)
1363
1464
  }
@@ -1415,8 +1516,8 @@ try {
1415
1516
  })
1416
1517
 
1417
1518
  const typeLoaderProcessInfo = {
1418
- styles: ['css-loader', wxssLoaderPath, styleCompilerPath],
1419
- template: ['html-loader', wxmlLoaderPath, templateCompilerPath]
1519
+ styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath],
1520
+ template: ['node_modules/html-loader', wxmlLoaderPath, templateCompilerPath]
1420
1521
  }
1421
1522
 
1422
1523
  // 应用过rules后,注入mpx相关资源编译loader
@@ -1479,15 +1580,15 @@ try {
1479
1580
  if (mpx.mode === 'web') {
1480
1581
  const mpxStyleOptions = queryObj.mpxStyleOptions
1481
1582
  const firstLoader = loaders[0] ? toPosix(loaders[0].loader) : ''
1482
- const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher')
1583
+ const isPitcherRequest = firstLoader.includes('node_modules/vue-loader/lib/loaders/pitcher')
1483
1584
  let cssLoaderIndex = -1
1484
1585
  let vueStyleLoaderIndex = -1
1485
1586
  let mpxStyleLoaderIndex = -1
1486
1587
  loaders.forEach((loader, index) => {
1487
1588
  const currentLoader = toPosix(loader.loader)
1488
- if (currentLoader.includes('css-loader') && cssLoaderIndex === -1) {
1589
+ if (currentLoader.includes('node_modules/css-loader') && cssLoaderIndex === -1) {
1489
1590
  cssLoaderIndex = index
1490
- } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader') && vueStyleLoaderIndex === -1) {
1591
+ } else if (currentLoader.includes('node_modules/vue-loader/lib/loaders/stylePostLoader') && vueStyleLoaderIndex === -1) {
1491
1592
  vueStyleLoaderIndex = index
1492
1593
  } else if (currentLoader.includes(styleCompilerPath) && mpxStyleLoaderIndex === -1) {
1493
1594
  mpxStyleLoaderIndex = index
@@ -6,6 +6,7 @@ const parseRequest = require('../utils/parse-request')
6
6
  const addQuery = require('../utils/add-query')
7
7
  const loaderUtils = require('loader-utils')
8
8
  const resolve = require('../utils/resolve')
9
+ const { matchCondition } = require('../utils/match-condition')
9
10
 
10
11
  module.exports = function createJSONHelper ({ loaderContext, emitWarning, customGetDynamicEntry }) {
11
12
  const mpx = loaderContext.getMpx()
@@ -17,9 +18,11 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
17
18
  const getOutputPath = mpx.getOutputPath
18
19
  const mode = mpx.mode
19
20
  const enableRequireAsync = mpx.enableRequireAsync
21
+ const asyncSubpackageRules = mpx.asyncSubpackageRules
20
22
 
21
23
  const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
22
24
  const urlToRequest = r => loaderUtils.urlToRequest(r)
25
+ const isScript = ext => /\.(ts|js)$/.test(ext)
23
26
 
24
27
  const dynamicEntryMap = new Map()
25
28
 
@@ -45,23 +48,33 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
45
48
  if (resolveMode === 'native') {
46
49
  component = urlToRequest(component)
47
50
  }
48
-
49
51
  resolve(context, component, loaderContext, (err, resource, info) => {
50
52
  if (err) return callback(err)
51
53
  const { resourcePath, queryObj } = parseRequest(resource)
52
-
54
+ let placeholder = null
53
55
  if (queryObj.root) {
54
56
  // 删除root query
55
57
  resource = addQuery(resource, {}, false, ['root'])
56
58
  // 目前只有微信支持分包异步化
57
- if (enableRequireAsync) tarRoot = queryObj.root
59
+ if (enableRequireAsync) {
60
+ tarRoot = queryObj.root
61
+ }
62
+ } else if (!queryObj.root && asyncSubpackageRules && enableRequireAsync) {
63
+ for (const item of asyncSubpackageRules) {
64
+ if (matchCondition(resourcePath, item)) {
65
+ tarRoot = item.root
66
+ placeholder = item.placeholder
67
+ break
68
+ }
69
+ }
58
70
  }
71
+
59
72
  const parsed = path.parse(resourcePath)
60
73
  const ext = parsed.ext
61
74
  const resourceName = path.join(parsed.dir, parsed.name)
62
75
 
63
76
  if (!outputPath) {
64
- if (ext === '.js' && resourceName.includes('node_modules') && mode !== 'web') {
77
+ if (isScript(ext) && resourceName.includes('node_modules') && mode !== 'web') {
65
78
  let root = info.descriptionFileRoot
66
79
  let name = 'nativeComponent'
67
80
  if (info.descriptionFileData) {
@@ -79,12 +92,12 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
79
92
  outputPath = getOutputPath(resourcePath, 'component')
80
93
  }
81
94
  }
82
- if (ext === '.js' && mode !== 'web') {
95
+ if (isScript(ext) && mode !== 'web') {
83
96
  resource = `!!${nativeLoaderPath}!${resource}`
84
97
  }
85
98
 
86
99
  const entry = getDynamicEntry(resource, 'component', outputPath, tarRoot, relativePath)
87
- callback(null, entry)
100
+ callback(null, entry, tarRoot, placeholder)
88
101
  })
89
102
  }
90
103
 
@@ -101,7 +114,9 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
101
114
  // 增加 page 标识
102
115
  page = addQuery(page, { isPage: true })
103
116
  resolve(context, page, loaderContext, (err, resource) => {
104
- if (err) return callback(err)
117
+ if (err) {
118
+ return callback(err)
119
+ }
105
120
  const { resourcePath, queryObj: { isFirst } } = parseRequest(resource)
106
121
  const ext = path.extname(resourcePath)
107
122
  let outputPath
@@ -117,14 +132,15 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
117
132
  outputPath = /^(.*?)(\.[^.]*)?$/.exec(relative)[1]
118
133
  }
119
134
  }
120
- if (ext === '.js' && mode !== 'web') {
135
+ if (isScript(ext) && mode !== 'web') {
121
136
  resource = `!!${nativeLoaderPath}!${resource}`
122
137
  }
123
138
  const entry = getDynamicEntry(resource, 'page', outputPath, tarRoot, publicPath + tarRoot)
124
139
  const key = [resourcePath, outputPath, tarRoot].join('|')
125
140
  callback(null, entry, {
126
141
  isFirst,
127
- key
142
+ key,
143
+ resource
128
144
  })
129
145
  })
130
146
  }