@mpxjs/webpack-plugin 2.7.0-beta.9 → 2.7.1-beta.2

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.
@@ -16,6 +16,8 @@ class AppEntryDependency extends NullDependency {
16
16
  const mpx = compilation.__mpx__
17
17
  const moduleGraph = compilation.moduleGraph
18
18
 
19
+ mpx.getEntryNode(module, 'app')
20
+
19
21
  if (mpx.appInfo.name) {
20
22
  const issuer = moduleGraph.getIssuer(module)
21
23
  const err = new Error(issuer
@@ -1,8 +1,9 @@
1
1
  const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
2
  const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+ const InitFragment = require('webpack/lib//InitFragment')
3
4
 
4
5
  class CommonJsVariableDependency extends ModuleDependency {
5
- constructor (request, name) {
6
+ constructor (request, name = '') {
6
7
  super(request)
7
8
  this.name = name
8
9
  }
@@ -44,10 +45,10 @@ CommonJsVariableDependency.Template = class CommonJsVariableDependencyTemplate e
44
45
  runtimeTemplate,
45
46
  moduleGraph,
46
47
  chunkGraph,
47
- runtimeRequirements
48
+ runtimeRequirements,
49
+ initFragments
48
50
  }
49
51
  ) {
50
- if (!dep.name) return
51
52
  const importedModule = moduleGraph.getModule(dep)
52
53
  let requireExpr = runtimeTemplate.moduleExports({
53
54
  module: importedModule,
@@ -57,7 +58,18 @@ CommonJsVariableDependency.Template = class CommonJsVariableDependencyTemplate e
57
58
  runtimeRequirements
58
59
  })
59
60
 
60
- source.insert(0, `/* mpx cjs variable */ var ${dep.name} = ${requireExpr};\n`)
61
+ let expr = '/* mpx cjs variable */ '
62
+ if (dep.name) expr += 'var ' + dep.name + ' = '
63
+ expr += requireExpr + ';\n'
64
+
65
+ initFragments.push(
66
+ new InitFragment(
67
+ expr,
68
+ InitFragment.STAGE_CONSTANTS,
69
+ 1,
70
+ dep.request
71
+ )
72
+ )
61
73
  }
62
74
  }
63
75
 
@@ -27,7 +27,7 @@ class DynamicEntryDependency extends NullDependency {
27
27
  addEntry (compilation, callback) {
28
28
  const mpx = compilation.__mpx__
29
29
  const publicPath = compilation.outputOptions.publicPath || ''
30
- let { resource, entryType, outputPath, relativePath } = this
30
+ let { resource, entryType, outputPath, relativePath, originEntryNode } = this
31
31
 
32
32
  const { packageRoot, outputPath: filename, alreadyOutputed } = mpx.getPackageInfo({
33
33
  resource,
@@ -59,7 +59,7 @@ class DynamicEntryDependency extends NullDependency {
59
59
  if (entryType === 'export') {
60
60
  mpx.exportModules.add(entryModule)
61
61
  }
62
- // todo entry的父子关系可以在这里建立
62
+ originEntryNode.addChild(mpx.getEntryNode(entryModule, entryType))
63
63
  return callback(null, {
64
64
  resultPath,
65
65
  entryModule
@@ -70,6 +70,7 @@ class DynamicEntryDependency extends NullDependency {
70
70
  mpxAction (module, compilation, callback) {
71
71
  const mpx = compilation.__mpx__
72
72
  const { packageRoot } = this
73
+ this.originEntryNode = mpx.getEntryNode(module)
73
74
  // 分包构建在需要在主包构建完成后在finishMake中处理,返回的资源路径先用key来占位,在合成extractedAssets时再进行最终替换
74
75
  if (packageRoot && mpx.currentPackageRoot !== packageRoot) {
75
76
  mpx.subpackagesEntriesMap[packageRoot] = mpx.subpackagesEntriesMap[packageRoot] || []
@@ -9,6 +9,7 @@ class FlagPluginDependency extends NullDependency {
9
9
  mpxAction (module, compilation, callback) {
10
10
  const mpx = compilation.__mpx__
11
11
  mpx.isPluginMode = true
12
+ mpx.getEntryNode(module, 'plugin')
12
13
  return callback()
13
14
  }
14
15
  }
@@ -0,0 +1,44 @@
1
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+
4
+ class RecordIndependentDependency extends NullDependency {
5
+ constructor (root, request) {
6
+ super()
7
+ this.root = root
8
+ this.request = request
9
+ }
10
+
11
+ get type () {
12
+ return 'mpx record independent'
13
+ }
14
+
15
+ mpxAction (module, compilation, callback) {
16
+ const mpx = compilation.__mpx__
17
+ const { root, request } = this
18
+ mpx.independentSubpackagesMap[root] = request
19
+ return callback()
20
+ }
21
+
22
+ serialize (context) {
23
+ const { write } = context
24
+ write(this.root)
25
+ write(this.request)
26
+ super.serialize(context)
27
+ }
28
+
29
+ deserialize (context) {
30
+ const { read } = context
31
+ this.root = read()
32
+ this.request = read()
33
+ super.deserialize(context)
34
+ }
35
+ }
36
+
37
+ RecordIndependentDependency.Template = class RecordIndependentDependencyTemplate {
38
+ apply () {
39
+ }
40
+ }
41
+
42
+ makeSerializable(RecordIndependentDependency, '@mpxjs/webpack-plugin/lib/dependencies/RecordIndependentDependency')
43
+
44
+ module.exports = RecordIndependentDependency
package/lib/extractor.js CHANGED
@@ -4,8 +4,8 @@ const parseRequest = require('./utils/parse-request')
4
4
  const toPosix = require('./utils/to-posix')
5
5
  const fixRelative = require('./utils/fix-relative')
6
6
  const addQuery = require('./utils/add-query')
7
+ const normalize = require('./utils/normalize')
7
8
  const { MPX_DISABLE_EXTRACTOR_CACHE, DEFAULT_RESULT_SOURCE } = require('./utils/const')
8
- const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
9
9
 
10
10
  module.exports = content => content
11
11
 
@@ -37,10 +37,10 @@ module.exports.pitch = async function (remainingRequest) {
37
37
  })
38
38
 
39
39
  let request = remainingRequest
40
- // static的情况下需要记录相关静态资源的输出路径
40
+ // static的情况下需要用record-loader记录相关静态资源的输出路径,不能直接在这里记录,需要确保在子依赖开始构建前完成记录,因为子依赖构建时可能就需要访问当前资源的输出路径
41
41
  if (isStatic) {
42
- const packageRoot = queryObj.packageRoot || ''
43
- this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'staticResource', file, packageRoot))
42
+ const recordLoader = normalize.lib('record-loader')
43
+ request = `${recordLoader}!${remainingRequest}`
44
44
  }
45
45
 
46
46
  let content = await this.importModule(`!!${request}`)
@@ -51,6 +51,10 @@ module.exports.pitch = async function (remainingRequest) {
51
51
  }).join('\n')
52
52
  }
53
53
 
54
+ let resultSource = DEFAULT_RESULT_SOURCE
55
+
56
+ if (typeof content !== 'string') return resultSource
57
+
54
58
  const extractedInfo = {
55
59
  content,
56
60
  index
@@ -61,8 +65,6 @@ module.exports.pitch = async function (remainingRequest) {
61
65
  extractedInfo
62
66
  })
63
67
 
64
- let resultSource = DEFAULT_RESULT_SOURCE
65
-
66
68
  const { buildInfo } = this._module
67
69
 
68
70
  // 如果importModule子模块中包含动态特性,比如动态添加入口和静态资源输出路径,则当前extractor模块不可缓存
package/lib/helpers.js CHANGED
@@ -4,14 +4,6 @@ const selectorPath = normalize.lib('selector')
4
4
  const addQuery = require('./utils/add-query')
5
5
  const parseRequest = require('./utils/parse-request')
6
6
 
7
- function getRawRequest ({ resource, loaderIndex, loaders }, excludedPreLoaders = /eslint-loader/) {
8
- return loaderUtils.getRemainingRequest({
9
- resource: resource,
10
- loaderIndex: loaderIndex,
11
- loaders: loaders.filter(loader => !excludedPreLoaders.test(loader.path))
12
- })
13
- }
14
-
15
7
  const defaultLang = {
16
8
  template: 'wxml',
17
9
  styles: 'wxss',
@@ -21,7 +13,7 @@ const defaultLang = {
21
13
  }
22
14
 
23
15
  module.exports = function createHelpers (loaderContext) {
24
- const rawRequest = getRawRequest(loaderContext)
16
+ const rawRequest = loaderUtils.getRemainingRequest(loaderContext)
25
17
 
26
18
  function getRequire (type, part, extraOptions, index) {
27
19
  return 'require(' + getRequestString(type, part, extraOptions, index) + ')'
@@ -0,0 +1,50 @@
1
+ const parseComponent = require('./parser')
2
+ const createHelpers = require('./helpers')
3
+ const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
4
+ const path = require('path')
5
+ const normalize = require('./utils/normalize')
6
+
7
+ module.exports = function (content) {
8
+ this.cacheable()
9
+ const mpx = this.getMpx()
10
+ if (!mpx) {
11
+ return content
12
+ }
13
+
14
+ const mode = mpx.mode
15
+ const env = mpx.env
16
+ const i18n = mpx.i18n
17
+ const filePath = this.resourcePath
18
+ const extname = path.extname(filePath)
19
+ if (extname === '.mpx') {
20
+ const parts = parseComponent(content, {
21
+ filePath,
22
+ needMap: this.sourceMap,
23
+ mode,
24
+ env
25
+ })
26
+ const {
27
+ getRequire
28
+ } = createHelpers(this)
29
+
30
+ if (parts.script) {
31
+ content = getRequire('script', parts.script)
32
+ } else {
33
+ content = ''
34
+ }
35
+ }
36
+
37
+ let output = 'global.isIndependent = true\n'
38
+ // 注入i18n
39
+ if (i18n) {
40
+ const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
41
+ const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
42
+ const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
43
+ this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest))
44
+ }
45
+ output += content
46
+ output += '\n'
47
+ output += 'delete global.isIndependent\n'
48
+
49
+ return output
50
+ }
package/lib/index.js CHANGED
@@ -26,6 +26,7 @@ const PackageEntryPlugin = require('./resolver/PackageEntryPlugin')
26
26
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
27
27
  const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
28
28
  const RecordGlobalComponentsDependency = require('./dependencies/RecordGlobalComponentsDependency')
29
+ const RecordIndependentDependency = require('./dependencies/RecordIndependentDependency')
29
30
  const DynamicEntryDependency = require('./dependencies/DynamicEntryDependency')
30
31
  const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
31
32
  const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
@@ -77,35 +78,6 @@ const isChunkInPackage = (chunkName, packageName) => {
77
78
  return (new RegExp(`^${packageName}\\/`)).test(chunkName)
78
79
  }
79
80
 
80
- const getPackageCacheGroup = packageName => {
81
- if (packageName === 'main') {
82
- return {
83
- // 对于独立分包模块不应用该cacheGroup
84
- test: (module) => {
85
- const { queryObj } = parseRequest(module.resource)
86
- return !queryObj.isIndependent
87
- },
88
- name: 'bundle',
89
- minChunks: 2,
90
- chunks: 'all'
91
- }
92
- } else {
93
- return {
94
- test: (module, { chunkGraph }) => {
95
- const chunks = chunkGraph.getModuleChunksIterable(module)
96
- return chunks.size && every(chunks, (chunk) => {
97
- return isChunkInPackage(chunk.name, packageName)
98
- })
99
- },
100
- name: `${packageName}/bundle`,
101
- minChunks: 2,
102
- minSize: 1000,
103
- priority: 100,
104
- chunks: 'all'
105
- }
106
- }
107
- }
108
-
109
81
  const externalsMap = {
110
82
  weui: /^weui-miniprogram/
111
83
  }
@@ -113,20 +85,19 @@ const externalsMap = {
113
85
  const warnings = []
114
86
  const errors = []
115
87
 
116
- // class EntryNode {
117
- // constructor (options) {
118
- // this.request = options.request
119
- // this.type = options.type
120
- // this.module = null
121
- // this.parents = new Set()
122
- // this.children = new Set()
123
- // }
124
- //
125
- // addChild (node) {
126
- // this.children.add(node)
127
- // node.parents.add(this)
128
- // }
129
- // }
88
+ class EntryNode {
89
+ constructor (module, type) {
90
+ this.module = module
91
+ this.type = type
92
+ this.parents = new Set()
93
+ this.children = new Set()
94
+ }
95
+
96
+ addChild (node) {
97
+ this.children.add(node)
98
+ node.parents.add(this)
99
+ }
100
+ }
130
101
 
131
102
  class MpxWebpackPlugin {
132
103
  constructor (options = {}) {
@@ -168,9 +139,6 @@ class MpxWebpackPlugin {
168
139
  options.transRpxRules = options.transRpxRules || null
169
140
  options.auditResource = options.auditResource || false
170
141
  options.decodeHTMLText = options.decodeHTMLText || false
171
- options.nativeOptions = Object.assign({
172
- cssLangs: ['css', 'less', 'stylus', 'scss', 'sass']
173
- }, options.nativeOptions)
174
142
  options.i18n = options.i18n || null
175
143
  options.checkUsingComponents = options.checkUsingComponents || false
176
144
  options.reportSize = options.reportSize || null
@@ -185,6 +153,10 @@ class MpxWebpackPlugin {
185
153
  include: () => true
186
154
  }
187
155
  options.customOutputPath = options.customOutputPath || null
156
+ options.nativeConfig = Object.assign({
157
+ cssLangs: ['css', 'less', 'stylus', 'scss', 'sass']
158
+ }, options.nativeConfig)
159
+ options.webConfig = options.webConfig || {}
188
160
  this.options = options
189
161
  }
190
162
 
@@ -344,6 +316,7 @@ class MpxWebpackPlugin {
344
316
  originalWriteFile(filePath, content, callback)
345
317
  }
346
318
  }
319
+
347
320
  const defs = this.options.defs
348
321
 
349
322
  const typeExtMap = config[this.options.mode].typeExtMap
@@ -365,6 +338,42 @@ class MpxWebpackPlugin {
365
338
 
366
339
  let mpx
367
340
 
341
+ const getPackageCacheGroup = packageName => {
342
+ if (packageName === 'main') {
343
+ return {
344
+ // 对于独立分包模块不应用该cacheGroup
345
+ test: (module) => {
346
+ let isIndependent = false
347
+ if (module.resource) {
348
+ const { queryObj } = parseRequest(module.resource)
349
+ isIndependent = !!queryObj.independent
350
+ } else {
351
+ const identifier = module.identifier()
352
+ isIndependent = /\|independent=/.test(identifier)
353
+ }
354
+ return !isIndependent
355
+ },
356
+ name: 'bundle',
357
+ minChunks: 2,
358
+ chunks: 'all'
359
+ }
360
+ } else {
361
+ return {
362
+ test: (module, { chunkGraph }) => {
363
+ const chunks = chunkGraph.getModuleChunksIterable(module)
364
+ return chunks.size && every(chunks, (chunk) => {
365
+ return isChunkInPackage(chunk.name, packageName)
366
+ })
367
+ },
368
+ name: `${packageName}/bundle`,
369
+ minChunks: 2,
370
+ minSize: 1000,
371
+ priority: 100,
372
+ chunks: 'all'
373
+ }
374
+ }
375
+ }
376
+
368
377
  const processSubpackagesEntriesMap = (compilation, callback) => {
369
378
  const mpx = compilation.__mpx__
370
379
  if (mpx && !isEmptyObject(mpx.subpackagesEntriesMap)) {
@@ -439,6 +448,9 @@ class MpxWebpackPlugin {
439
448
  compilation.dependencyFactories.set(RecordGlobalComponentsDependency, new NullFactory())
440
449
  compilation.dependencyTemplates.set(RecordGlobalComponentsDependency, new RecordGlobalComponentsDependency.Template())
441
450
 
451
+ compilation.dependencyFactories.set(RecordIndependentDependency, new NullFactory())
452
+ compilation.dependencyTemplates.set(RecordIndependentDependency, new RecordIndependentDependency.Template())
453
+
442
454
  compilation.dependencyFactories.set(CommonJsVariableDependency, normalModuleFactory)
443
455
  compilation.dependencyTemplates.set(CommonJsVariableDependency, new CommonJsVariableDependency.Template())
444
456
  })
@@ -473,17 +485,15 @@ class MpxWebpackPlugin {
473
485
  subpackagesEntriesMap: {},
474
486
  replacePathMap: {},
475
487
  exportModules: new Set(),
476
- // 记录entry依赖关系,用于体积分析
477
- entryNodesMap: {},
478
488
  // 记录entryModule与entryNode的对应关系,用于体积分析
479
- entryModulesMap: new Map(),
480
- extractedMap: {},
489
+ entryNodeModulesMap: new Map(),
490
+ // 记录与asset相关联的modules,用于体积分析
491
+ assetModulesMap: new Map(),
481
492
  usingComponents: {},
482
493
  // todo es6 map读写性能高于object,之后会逐步替换
483
494
  vueContentCache: new Map(),
484
495
  currentPackageRoot: '',
485
496
  wxsContentMap: {},
486
- assetsInfo: new Map(),
487
497
  forceUsePageCtor: this.options.forceUsePageCtor,
488
498
  resolveMode: this.options.resolveMode,
489
499
  mode: this.options.mode,
@@ -496,8 +506,10 @@ class MpxWebpackPlugin {
496
506
  transRpxRules: this.options.transRpxRules,
497
507
  postcssInlineConfig: this.options.postcssInlineConfig,
498
508
  decodeHTMLText: this.options.decodeHTMLText,
499
- // native文件专用相关配置
500
- nativeOptions: this.options.nativeOptions,
509
+ // native文件专用配置
510
+ nativeConfig: this.options.nativeConfig,
511
+ // 输出web专用配置
512
+ webConfig: this.options.webConfig,
501
513
  tabBarMap: {},
502
514
  defs: preProcessDefs(this.options.defs),
503
515
  i18n: this.options.i18n,
@@ -520,6 +532,15 @@ class MpxWebpackPlugin {
520
532
  compilation.addEntry(compiler.context, dep, { name }, callback)
521
533
  return dep
522
534
  },
535
+ getEntryNode: (module, type) => {
536
+ const entryNodeModulesMap = mpx.entryNodeModulesMap
537
+ let entryNode = entryNodeModulesMap.get(module)
538
+ if (!entryNode) {
539
+ entryNode = new EntryNode(module, type)
540
+ entryNodeModulesMap.set(module, entryNode)
541
+ }
542
+ return entryNode
543
+ },
523
544
  getOutputPath: (resourcePath, type, { ext = '', conflictPath = '' } = {}) => {
524
545
  const name = path.parse(resourcePath).name
525
546
  const hash = mpx.pathHash(resourcePath)
@@ -569,7 +590,7 @@ class MpxWebpackPlugin {
569
590
  const { resourcePath } = parseRequest(resource)
570
591
  const currentPackageRoot = mpx.currentPackageRoot
571
592
  const currentPackageName = currentPackageRoot || 'main'
572
- const isIndependent = mpx.independentSubpackagesMap[currentPackageRoot]
593
+ const isIndependent = !!mpx.independentSubpackagesMap[currentPackageRoot]
573
594
  const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
574
595
 
575
596
  if (!resourceMap.main) {
@@ -672,12 +693,14 @@ class MpxWebpackPlugin {
672
693
  const rawAddModule = compilation.addModule
673
694
  compilation.addModule = (module, callback) => {
674
695
  const issuerResource = module.issuerResource
675
- // 避免context module报错
676
- if (module.request && module.resource) {
696
+ const currentPackageRoot = mpx.currentPackageRoot
697
+ const independent = mpx.independentSubpackagesMap[currentPackageRoot]
698
+
699
+ if (module.resource) {
700
+ // NormalModule
677
701
  const isStatic = isStaticModule(module)
678
- const isIndependent = mpx.independentSubpackagesMap[mpx.currentPackageRoot]
679
702
 
680
- let needPackageQuery = isStatic || isIndependent
703
+ let needPackageQuery = isStatic || independent
681
704
 
682
705
  if (!needPackageQuery) {
683
706
  const { resourcePath } = parseRequest(module.resource)
@@ -696,15 +719,24 @@ class MpxWebpackPlugin {
696
719
  compilation.errors.push(e)
697
720
  }
698
721
  })
699
- const queryObj = {}
700
- if (packageRoot) queryObj.packageRoot = packageRoot
701
- // todo 后续可以考虑用module.layer来隔离独立分包的模块
702
- if (isIndependent) queryObj.isIndependent = true
703
- module.request = addQuery(module.request, queryObj)
704
- module.resource = addQuery(module.resource, queryObj)
722
+ if (packageRoot) {
723
+ const queryObj = {
724
+ packageRoot
725
+ }
726
+ if (independent) queryObj.independent = independent
727
+ module.request = addQuery(module.request, queryObj)
728
+ module.resource = addQuery(module.resource, queryObj)
729
+ }
730
+ }
731
+ } else if (independent) {
732
+ // ContextModule和RawModule只在独立分包的情况下添加分包标记,其余默认不添加
733
+ const postfix = `|independent=${independent}|${currentPackageRoot}`
734
+ if (module._identifier) {
735
+ module._identifier += postfix
736
+ } else if (module.identifierStr) {
737
+ module.identifierStr += postfix
705
738
  }
706
739
  }
707
-
708
740
  return rawAddModule.call(compilation, module, callback)
709
741
  }
710
742
 
@@ -760,6 +792,12 @@ class MpxWebpackPlugin {
760
792
  return source
761
793
  })
762
794
 
795
+ compilation.hooks.moduleAsset.tap('MpxWebpackPlugin', (module, filename) => {
796
+ const modules = mpx.assetModulesMap.get(filename) || new Set()
797
+ modules.add(module)
798
+ mpx.assetModulesMap.set(filename, modules)
799
+ })
800
+
763
801
  compilation.hooks.beforeModuleAssets.tap('MpxWebpackPlugin', () => {
764
802
  const extractedAssetsMap = new Map()
765
803
  for (const module of compilation.modules) {
@@ -772,8 +810,7 @@ class MpxWebpackPlugin {
772
810
  extractedAssetsMap.set(filename, extractedAssets)
773
811
  }
774
812
  extractedAssets.push(extractedInfo)
775
- // todo 后续计算体积时可以通过这个钩子关联静态assets和module
776
- // compilation.hooks.moduleAsset.call(module, filename)
813
+ compilation.hooks.moduleAsset.call(module, filename)
777
814
  }
778
815
  }
779
816
  }
@@ -1000,7 +1037,6 @@ class MpxWebpackPlugin {
1000
1037
  }
1001
1038
 
1002
1039
  const processedChunk = new Set()
1003
- // const rootName = compilation.entries.keys().next().value
1004
1040
  const appName = mpx.appInfo.name
1005
1041
 
1006
1042
  function processChunk (chunk, isRuntime, relativeChunks) {
@@ -1245,7 +1281,7 @@ try {
1245
1281
  })
1246
1282
  })
1247
1283
 
1248
- compiler.hooks.emit.tapAsync('MpxWebpackPlugin', (compilation, callback) => {
1284
+ compiler.hooks.emit.tap('MpxWebpackPlugin', (compilation) => {
1249
1285
  if (this.options.generateBuildMap) {
1250
1286
  const pagesMap = compilation.__mpx__.pagesMap
1251
1287
  const componentsPackageMap = compilation.__mpx__.componentsMap
@@ -1262,7 +1298,63 @@ try {
1262
1298
  }
1263
1299
  }
1264
1300
  }
1265
- callback()
1301
+ })
1302
+
1303
+ const clearFileCache = () => {
1304
+ const fs = compiler.intermediateFileSystem
1305
+ const cacheLocation = compiler.options.cache.cacheLocation
1306
+ return new Promise((resolve, reject) => {
1307
+ if (fs.rm) {
1308
+ fs.rm(cacheLocation, {
1309
+ recursive: true,
1310
+ force: true
1311
+ }, (err) => {
1312
+ if (err) return reject(err)
1313
+ resolve()
1314
+ })
1315
+ } else {
1316
+ // polyfill fs.rm
1317
+ const rmdir = (dir, callback) => {
1318
+ fs.readdir(dir, (err, files) => {
1319
+ if (err) return callback(err)
1320
+ async.each(files, (file, callback) => {
1321
+ file = path.join(dir, file)
1322
+ async.waterfall([
1323
+ (callback) => {
1324
+ fs.stat(file, callback)
1325
+ },
1326
+ (stats, callback) => {
1327
+ if (stats.isDirectory()) {
1328
+ rmdir(file, callback)
1329
+ } else {
1330
+ fs.unlink(file, callback)
1331
+ }
1332
+ }
1333
+ ], callback)
1334
+ }, (err) => {
1335
+ if (err) return callback(err)
1336
+ fs.rmdir(dir, callback)
1337
+ })
1338
+ })
1339
+ }
1340
+
1341
+ rmdir(cacheLocation, (err) => {
1342
+ if (err) return reject(err)
1343
+ resolve()
1344
+ })
1345
+ }
1346
+ })
1347
+ }
1348
+
1349
+ compiler.hooks.done.tapPromise('MpxWebpackPlugin', async () => {
1350
+ const cache = compiler.getCache('MpxWebpackPlugin')
1351
+ const cacheIsValid = await cache.getPromise('cacheIsValid', null)
1352
+ if (!cacheIsValid) {
1353
+ await Promise.all([
1354
+ clearFileCache(),
1355
+ cache.storePromise('cacheIsValid', null, true)
1356
+ ])
1357
+ }
1266
1358
  })
1267
1359
  }
1268
1360
  }
@@ -12,6 +12,7 @@ const getJSONContent = require('../utils/get-json-content')
12
12
  const createHelpers = require('../helpers')
13
13
  const createJSONHelper = require('./helper')
14
14
  const RecordGlobalComponentsDependency = require('../dependencies/RecordGlobalComponentsDependency')
15
+ const RecordIndependentDependency = require('../dependencies/RecordIndependentDependency')
15
16
  const { MPX_DISABLE_EXTRACTOR_CACHE, RESOLVE_IGNORED_ERR, JSON_JS_EXT } = require('../utils/const')
16
17
  const resolve = require('../utils/resolve')
17
18
 
@@ -263,13 +264,15 @@ module.exports = function (content) {
263
264
  },
264
265
  (result, content, callback) => {
265
266
  const extName = path.extname(result)
266
- if (extName === '.mpx' || extName === '.vue') {
267
+ if (extName === '.mpx') {
267
268
  const parts = parseComponent(content, {
268
269
  filePath: result,
269
270
  needMap: this.sourceMap,
270
271
  mode,
271
272
  env
272
273
  })
274
+ // 对于通过.mpx文件声明的独立分包,默认将其自身的script block视为init module
275
+ if (queryObj.independent === true) queryObj.independent = result
273
276
  getJSONContent(parts.json || {}, this, (err, content) => {
274
277
  callback(err, result, content)
275
278
  })
@@ -346,6 +349,31 @@ module.exports = function (content) {
346
349
  return result
347
350
  }
348
351
 
352
+ const recordIndependent = (root, request) => {
353
+ this._module.addPresentationalDependency(new RecordIndependentDependency(root, request))
354
+ }
355
+
356
+ const processIndependent = (otherConfig, context, tarRoot, callback) => {
357
+ // 支付宝不支持独立分包,无需处理
358
+ const independent = otherConfig.independent
359
+ if (!independent || mode === 'ali') {
360
+ delete otherConfig.independent
361
+ return callback()
362
+ }
363
+ // independent配置为字符串时视为init module
364
+ if (typeof independent === 'string') {
365
+ otherConfig.independent = true
366
+ resolve(context, independent, this, (err, result) => {
367
+ if (err) return callback(err)
368
+ recordIndependent(tarRoot, result)
369
+ callback()
370
+ })
371
+ } else {
372
+ recordIndependent(tarRoot, true)
373
+ callback()
374
+ }
375
+ }
376
+
349
377
  // 为了获取资源的所属子包,该函数需串行执行
350
378
  const processSubPackage = (subPackage, context, callback) => {
351
379
  if (subPackage) {
@@ -357,26 +385,27 @@ module.exports = function (content) {
357
385
  let srcRoot = subPackage.srcRoot || subPackage.root || ''
358
386
  if (!tarRoot || subPackagesCfg[tarRoot]) return callback()
359
387
 
388
+ context = path.join(context, srcRoot)
360
389
  const otherConfig = getOtherConfig(subPackage)
361
- // 支付宝不支持独立分包,无需处理
362
- if (otherConfig.independent && mode !== 'ali') {
363
- mpx.independentSubpackagesMap[tarRoot] = true
364
- }
365
-
366
390
  subPackagesCfg[tarRoot] = {
367
391
  root: tarRoot,
368
- pages: [],
369
- ...otherConfig
392
+ pages: []
370
393
  }
371
- context = path.join(context, srcRoot)
372
394
  async.parallel([
395
+ (callback) => {
396
+ processIndependent(otherConfig, context, tarRoot, callback)
397
+ },
373
398
  (callback) => {
374
399
  processPages(subPackage.pages, context, tarRoot, callback)
375
400
  },
376
401
  (callback) => {
377
402
  processPlugins(subPackage.plugins, context, tarRoot, callback)
378
403
  }
379
- ], callback)
404
+ ], (err) => {
405
+ if (err) return callback(err)
406
+ Object.assign(subPackagesCfg[tarRoot], otherConfig)
407
+ callback()
408
+ })
380
409
  } else {
381
410
  callback()
382
411
  }
package/lib/loader.js CHANGED
@@ -15,6 +15,8 @@ const getJSONContent = require('./utils/get-json-content')
15
15
  const normalize = require('./utils/normalize')
16
16
  const getEntryName = require('./utils/get-entry-name')
17
17
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
18
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
19
+ const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
18
20
  const { MPX_APP_MODULE_ID } = require('./utils/const')
19
21
 
20
22
  module.exports = function (content) {
@@ -25,7 +27,9 @@ module.exports = function (content) {
25
27
  return content
26
28
  }
27
29
  const { resourcePath, queryObj } = parseRequest(this.resource)
28
- const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
30
+ const packageRoot = queryObj.packageRoot || mpx.currentPackageRoot
31
+ const packageName = packageRoot || 'main'
32
+ const independent = queryObj.independent
29
33
  const pagesMap = mpx.pagesMap
30
34
  const componentsMap = mpx.componentsMap[packageName]
31
35
  const mode = mpx.mode
@@ -37,16 +41,6 @@ module.exports = function (content) {
37
41
  const vueContentCache = mpx.vueContentCache
38
42
  const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
39
43
 
40
- // 支持资源query传入isPage或isComponent支持页面/组件单独编译
41
- if ((queryObj.isComponent && !componentsMap[resourcePath]) || (queryObj.isPage && !pagesMap[resourcePath])) {
42
- const entryName = getEntryName(this)
43
- if (queryObj.isComponent) {
44
- componentsMap[resourcePath] = entryName || 'noEntryComponent'
45
- } else {
46
- pagesMap[resourcePath] = entryName || 'noEntryPage'
47
- }
48
- }
49
-
50
44
  let ctorType = 'app'
51
45
  if (pagesMap[resourcePath]) {
52
46
  // page
@@ -56,10 +50,17 @@ module.exports = function (content) {
56
50
  ctorType = 'component'
57
51
  }
58
52
 
53
+ // 支持资源query传入isPage或isComponent支持页面/组件单独编译
54
+ if (queryObj.isComponent || queryObj.isPage) {
55
+ const entryName = getEntryName(this) || (queryObj.isComponent ? 'noEntryComponent' : 'noEntryPage')
56
+ ctorType = queryObj.isComponent ? 'component' : 'page'
57
+ this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, ctorType, entryName, packageRoot))
58
+ }
59
+
59
60
  const loaderContext = this
60
61
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
61
62
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
62
- const filePath = resourcePath
63
+ const filePath = this.resourcePath
63
64
  const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
64
65
 
65
66
  const parts = parseComponent(content, {
@@ -69,6 +70,10 @@ module.exports = function (content) {
69
70
  env
70
71
  })
71
72
 
73
+ const {
74
+ getRequire
75
+ } = createHelpers(loaderContext)
76
+
72
77
  let output = ''
73
78
  const callback = this.async()
74
79
 
@@ -208,26 +213,27 @@ module.exports = function (content) {
208
213
  this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
209
214
  }
210
215
 
211
- const {
212
- getRequire
213
- } = createHelpers(loaderContext)
214
-
215
216
  // 注入模块id及资源路径
216
217
  output += `global.currentModuleId = ${JSON.stringify(moduleId)}\n`
217
218
  if (!isProduction) {
218
219
  output += `global.currentResource = ${JSON.stringify(filePath)}\n`
219
220
  }
220
- // 为app或独立分包页面注入i18n
221
- if (i18n && (ctorType === 'app' || (ctorType === 'page' && queryObj.isIndependent))) {
221
+
222
+ // 为app注入i18n
223
+ if (i18n && ctorType === 'app') {
222
224
  const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
223
225
  const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
224
226
  const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
227
+ this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest))
228
+ }
225
229
 
226
- output += `if (!global.i18n) {
227
- global.i18n = ${JSON.stringify({ locale: i18n.locale, version: 0 })}
228
- global.i18nMethods = require(${loaderUtils.stringifyRequest(loaderContext, i18nWxsRequest)})
229
- }\n`
230
+ // 为独立分包注入init module
231
+ if (independent && typeof independent === 'string') {
232
+ const independentLoader = normalize.lib('independent-loader.js')
233
+ const independentInitRequest = `!!${independentLoader}!${independent}`
234
+ this._module.addDependency(new CommonJsVariableDependency(independentInitRequest))
230
235
  }
236
+
231
237
  // 注入构造函数
232
238
  let ctor = 'App'
233
239
  if (ctorType === 'page') {
@@ -297,29 +303,17 @@ module.exports = function (content) {
297
303
  // script
298
304
  output += '/* script */\n'
299
305
  let scriptSrcMode = srcMode
300
- const script = parts.script
306
+ // 给予script默认值, 确保生成js request以自动补全js
307
+ const script = parts.script || {}
301
308
  if (script) {
302
309
  scriptSrcMode = script.mode || scriptSrcMode
303
310
  if (scriptSrcMode) output += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
304
- const extraOptions = {}
311
+ // 传递ctorType以补全js内容
312
+ const extraOptions = {
313
+ ctorType
314
+ }
305
315
  if (script.src) extraOptions.resourcePath = resourcePath
306
316
  output += getRequire('script', script, extraOptions) + '\n'
307
- } else {
308
- // todo 依然创建request在selector中进行补全或者将i18n通过CommonJsVariableDependency改造为initFragments的方式进行注入,否则在app.mpx中没有script区块的情况下无法保证i18n注入代码在@mpxjs/core之前执行
309
- switch (ctorType) {
310
- case 'app':
311
- output += 'import {createApp} from "@mpxjs/core"\n' +
312
- 'createApp({})\n'
313
- break
314
- case 'page':
315
- output += 'import {createPage} from "@mpxjs/core"\n' +
316
- 'createPage({})\n'
317
- break
318
- case 'component':
319
- output += 'import {createComponent} from "@mpxjs/core"\n' +
320
- 'createComponent({})\n'
321
- }
322
- output += '\n'
323
317
  }
324
318
  callback(null, output)
325
319
  }
@@ -55,7 +55,7 @@ module.exports = function (content) {
55
55
  }
56
56
 
57
57
  function checkCSSLangFiles (callback) {
58
- const langs = mpx.nativeOptions.cssLangs || ['less', 'stylus', 'scss', 'sass']
58
+ const langs = mpx.nativeConfig.cssLangs || ['less', 'stylus', 'scss', 'sass']
59
59
  const results = []
60
60
  async.eachOf(langs, function (lang, i, callback) {
61
61
  if (!CSS_LANG_EXT_MAP[lang]) {
@@ -0,0 +1,11 @@
1
+ const parseRequest = require('./utils/parse-request')
2
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
3
+
4
+ module.exports = function (source) {
5
+ const mpx = this.getMpx()
6
+ const { resourcePath, queryObj } = parseRequest(this.resource)
7
+ const file = mpx.getExtractedFile(this.resource)
8
+ const packageRoot = queryObj.packageRoot || ''
9
+ this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'staticResource', file, packageRoot))
10
+ return source
11
+ }
@@ -36,7 +36,8 @@
36
36
  easingFunction: {
37
37
  type: String,
38
38
  default: 'default'
39
- }
39
+ },
40
+ scrollOptions: Object
40
41
  },
41
42
  data () {
42
43
  return {
@@ -90,11 +91,21 @@
90
91
  this.goto(val)
91
92
  }
92
93
  },
94
+ activated () {
95
+ if (this.bs && this.autoplay) {
96
+ this.bs.startPlay()
97
+ }
98
+ },
99
+ deactivated () {
100
+ if (this.bs && this.autoplay) {
101
+ this.bs.pausePlay()
102
+ }
103
+ },
93
104
  beforeCreate () {
94
105
  this.itemIds = []
95
106
  },
96
107
  mounted () {
97
- this.bs = new BScroll(this.$refs.wrapper, {
108
+ const originBsOptions = {
98
109
  scrollX: !this.vertical,
99
110
  scrollY: this.vertical,
100
111
  slide: {
@@ -103,14 +114,17 @@
103
114
  speed: this.duration,
104
115
  easing: this.easing,
105
116
  interval: this.interval,
106
- autoplay: this.autoplay
117
+ autoplay: this.autoplay,
118
+ startPageXIndex: this.vertical ? 0 : this.current,
119
+ startPageYIndex: this.vertical? this.current : 0
107
120
  },
108
121
  momentum: false,
109
122
  bounce: false,
110
123
  probeType: 3,
111
124
  stopPropagation: true
112
- })
113
-
125
+ }
126
+ const bsOptions = Object.assign({}, originBsOptions, this.scrollOptions)
127
+ this.bs = new BScroll(this.$refs.wrapper, bsOptions)
114
128
  this.bs.on('slideWillChange', (page) => {
115
129
  this.currentIndex = this.vertical ? page.pageY : page.pageX
116
130
  this.$emit('change', getCustomEvent('change', {
@@ -86,7 +86,7 @@
86
86
  }
87
87
 
88
88
  if (this.maxlength !== -1) {
89
- domProps.maxlength = this.maxlength
89
+ domProps.maxLength = this.maxlength
90
90
  }
91
91
 
92
92
  const data = {
@@ -6,7 +6,6 @@ function genRegExp (str, flags) {
6
6
  }
7
7
  }
8
8
 
9
-
10
9
  function likeArray (arr) {
11
10
  if (!__mpx_wxs__) {
12
11
  return Array.isArray(arr)
@@ -23,7 +22,6 @@ function isDef (v) {
23
22
  return v !== undefined && v !== null
24
23
  }
25
24
 
26
-
27
25
  var RE_TOKEN_LIST_VALUE = genRegExp('^[0-9]+')
28
26
  var RE_TOKEN_NAMED_VALUE = genRegExp('^[A-Za-z0-9_]+')
29
27
 
@@ -40,7 +38,10 @@ function parseMessage (format) {
40
38
  var char = format[position++]
41
39
  if (char === '{') {
42
40
  if (text) {
43
- tokens.push({ type: 'text', value: text })
41
+ tokens.push({
42
+ type: 'text',
43
+ value: text
44
+ })
44
45
  }
45
46
 
46
47
  text = ''
@@ -56,7 +57,10 @@ function parseMessage (format) {
56
57
  : isClosed && RE_TOKEN_NAMED_VALUE.test(sub)
57
58
  ? 'named'
58
59
  : 'unknown'
59
- tokens.push({ value: sub, type: type })
60
+ tokens.push({
61
+ value: sub,
62
+ type: type
63
+ })
60
64
  } else if (char === '%') {
61
65
  // when found rails i18n syntax, skip text capture
62
66
  if (format[(position)] !== '{') {
@@ -67,7 +71,10 @@ function parseMessage (format) {
67
71
  }
68
72
  }
69
73
 
70
- text && tokens.push({ type: 'text', value: text })
74
+ text && tokens.push({
75
+ type: 'text',
76
+ value: text
77
+ })
71
78
 
72
79
  return tokens
73
80
  }
@@ -263,6 +270,11 @@ function exist (messages, locale, key) {
263
270
  var messages = {}
264
271
  var dateTimeFormats = {}
265
272
  var numberFormats = {}
273
+ var locale = 'zh-CN'
274
+
275
+ function getLocale () {
276
+ return __mpx_locale__ || locale
277
+ }
266
278
 
267
279
  function getMessages () {
268
280
  // __mpx_messages__会在编译时通过lib/wxs/i18n-loader注入
@@ -339,7 +351,15 @@ module.exports = {
339
351
  }
340
352
 
341
353
  if (!__mpx_wxs__) {
342
- module.exports.__getMessages = getMessages
343
- module.exports.__getDateTimeFormats = getDateTimeFormats
344
- module.exports.__getNumberFormats = getNumberFormats
354
+ if (!global.i18n) {
355
+ global.i18n = {
356
+ locale: getLocale(),
357
+ version: 0
358
+ }
359
+ global.i18nMethods = Object.assign(module.exports, {
360
+ __getMessages: getMessages,
361
+ __getDateTimeFormats: getDateTimeFormats,
362
+ __getNumberFormats: getNumberFormats
363
+ })
364
+ }
345
365
  }
package/lib/selector.js CHANGED
@@ -9,6 +9,7 @@ module.exports = function (content) {
9
9
  return content
10
10
  }
11
11
  const { queryObj } = parseRequest(this.resource)
12
+ const ctorType = queryObj.ctorType
12
13
  const type = queryObj.type
13
14
  const index = queryObj.index || 0
14
15
  const mode = mpx.mode
@@ -24,6 +25,26 @@ module.exports = function (content) {
24
25
  if (Array.isArray(part)) {
25
26
  part = part[index]
26
27
  }
28
+ if (!part) {
29
+ let content = ''
30
+ // 补全js内容
31
+ if (type === 'script') {
32
+ switch (ctorType) {
33
+ case 'app':
34
+ content += 'import {createApp} from "@mpxjs/core"\n' +
35
+ 'createApp({})\n'
36
+ break
37
+ case 'page':
38
+ content += 'import {createPage} from "@mpxjs/core"\n' +
39
+ 'createPage({})\n'
40
+ break
41
+ case 'component':
42
+ content += 'import {createComponent} from "@mpxjs/core"\n' +
43
+ 'createComponent({})\n'
44
+ }
45
+ }
46
+ part = { content }
47
+ }
27
48
  part = part || { content: '' }
28
49
  this.callback(null, part.content, part.map)
29
50
  }
@@ -23,6 +23,7 @@ module.exports = function (css, map) {
23
23
  const transRpxRulesRaw = mpx.transRpxRules
24
24
  const transRpxRules = transRpxRulesRaw ? (Array.isArray(transRpxRulesRaw) ? transRpxRulesRaw : [transRpxRulesRaw]) : []
25
25
 
26
+ const transRpxFn = mpx.webConfig.transRpxFn
26
27
  const testResolveRange = (include = () => true, exclude) => {
27
28
  return matchCondition(this.resourcePath, { include, exclude })
28
29
  }
@@ -38,15 +39,14 @@ module.exports = function (css, map) {
38
39
  },
39
40
  config.options
40
41
  )
41
- // ali环境处理host选择器
42
+ // ali平台下处理scoped和host选择器
42
43
  if (mode === 'ali') {
44
+ if (queryObj.scoped) {
45
+ plugins.push(scopeId({ id }))
46
+ }
43
47
  plugins.push(transSpecial({ id }))
44
48
  }
45
49
 
46
- if (queryObj.scoped) {
47
- plugins.push(scopeId({ id }))
48
- }
49
-
50
50
  plugins.push(pluginCondStrip({
51
51
  defs
52
52
  }))
@@ -68,7 +68,7 @@ module.exports = function (css, map) {
68
68
  }
69
69
 
70
70
  if (mpx.mode === 'web') {
71
- plugins.push(vw)
71
+ plugins.push(vw({ transRpxFn }))
72
72
  }
73
73
  // source map
74
74
  if (this.sourceMap && !options.map) {
@@ -5,12 +5,13 @@ const rpxRegExpG = /\b(\d+(\.\d+)?)rpx\b/g
5
5
  module.exports = postcss.plugin('vw', (options = {}) => root => {
6
6
  const rpx2vwRatio = +(100 / 750).toFixed(8)
7
7
 
8
+ const transRpxFn = options.transRpxFn && typeof options.transRpxFn === 'function' ? options.transRpxFn : function (match, $1) {
9
+ if ($1 === '0') return $1
10
+ return `${$1 * rpx2vwRatio}vw`
11
+ }
8
12
  function transVw (declaration) {
9
13
  if (rpxRegExp.test(declaration.value)) {
10
- declaration.value = declaration.value.replace(rpxRegExpG, function (match, $1) {
11
- if ($1 === '0') return $1
12
- return `${$1 * rpx2vwRatio}vw`
13
- })
14
+ declaration.value = declaration.value.replace(rpxRegExpG, transRpxFn)
14
15
  }
15
16
  }
16
17
 
@@ -2039,7 +2039,10 @@ function processElement (el, root, options, meta) {
2039
2039
 
2040
2040
  const pass = isNative || processTemplate(el) || processingTemplate
2041
2041
 
2042
- processScoped(el, options)
2042
+ // 仅ali平台需要scoped模拟样式隔离
2043
+ if (mode === 'ali') {
2044
+ processScoped(el, options)
2045
+ }
2043
2046
 
2044
2047
  if (transAli) {
2045
2048
  processAliExternalClassesHack(el, options)
@@ -132,7 +132,7 @@ module.exports = function (json, {
132
132
  },
133
133
  (result, content, callback) => {
134
134
  const extName = path.extname(result)
135
- if (extName === '.mpx' || extName === '.vue') {
135
+ if (extName === '.mpx') {
136
136
  const parts = parseComponent(content, {
137
137
  filePath: result,
138
138
  needMap: loaderContext.sourceMap,
@@ -113,12 +113,6 @@ module.exports = function (script, {
113
113
  import Vue from 'vue'
114
114
  import VueRouter from 'vue-router'
115
115
  Vue.use(VueRouter)
116
- import BScroll from '@better-scroll/core'
117
- import PullDown from '@better-scroll/pull-down'
118
- import ObserveDOM from '@better-scroll/observe-dom'
119
- BScroll.use(ObserveDOM)
120
- BScroll.use(PullDown)
121
- global.BScroll = BScroll
122
116
  global.getApp = function(){}
123
117
  global.getCurrentPages = function(){
124
118
  if(!global.__mpxRouter) return []
@@ -216,11 +210,11 @@ module.exports = function (script, {
216
210
  content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
217
211
  }
218
212
  // 为了正确获取currentSrcMode便于运行时进行转换,对于src引入的组件script采用require方式引入(由于webpack会将import的执行顺序上升至最顶),这意味着对于src引入脚本中的named export将不会生效,不过鉴于mpx和小程序中本身也没有在组件script中声明export的用法,所以应该没有影响
219
- content += '\n\n\n/** ====== Source start ====== **/\n'
213
+ content += '\n\n\n/** Source start **/\n'
220
214
  content += script.src
221
215
  ? `require(${stringifyRequest(script.src)})\n`
222
216
  : script.content
223
- content += '\n/** ====== Source end ====== **/\n\n\n'
217
+ content += '\n/** Source end **/\n\n\n'
224
218
  // createApp/Page/Component执行完成后立刻获取当前的option并暂存
225
219
  content += ` const currentOption = global.currentOption\n`
226
220
  // 获取pageConfig
@@ -3,7 +3,7 @@ const loaderUtils = require('loader-utils')
3
3
 
4
4
  module.exports = function (content) {
5
5
  const i18n = this.getMpx().i18n
6
- let prefix = 'var __mpx_messages__, __mpx_datetime_formats__, __mpx_number_formats__\n'
6
+ let prefix = 'var __mpx_messages__, __mpx_datetime_formats__, __mpx_number_formats__, __mpx_locale__\n'
7
7
  if (i18n) {
8
8
  if (i18n.messages) {
9
9
  prefix += `__mpx_messages__ = ${JSON.stringify(i18n.messages)}\n`
@@ -20,6 +20,9 @@ module.exports = function (content) {
20
20
  } else if (i18n.numberFormatsPath) {
21
21
  prefix += `__mpx_number_formats__ = require(${loaderUtils.stringifyRequest(this, i18n.numberFormatsPath)})\n`
22
22
  }
23
+ if (i18n.locale) {
24
+ prefix += `__mpx_locale__ = ${JSON.stringify(i18n.locale)}\n`
25
+ }
23
26
  }
24
27
  content = prefix + content
25
28
  return content
@@ -39,11 +39,16 @@ module.exports = function (content) {
39
39
  let results = targetPath.unshiftContainer('body', insertNodes) || []
40
40
  targetPath.inserted = true
41
41
  results.forEach((item) => {
42
- item.stop()
42
+ item.shouldStopTraverse = true
43
43
  })
44
44
  }
45
45
  }
46
46
  },
47
+ ForStatement (path) {
48
+ if (path.shouldStopTraverse) {
49
+ path.stop()
50
+ }
51
+ },
47
52
  // 处理vant-aliapp中export var bem = bem;这种不被acorn支持的2b语法
48
53
  ExportNamedDeclaration (path) {
49
54
  if (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.0-beta.9",
3
+ "version": "2.7.1-beta.2",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -77,5 +77,8 @@
77
77
  "@types/babel-traverse": "^6.25.4",
78
78
  "@types/babel-types": "^7.0.4"
79
79
  },
80
- "gitHead": "368e40835a53b627170f59e8fbe827b457bb2654"
80
+ "engines": {
81
+ "node": ">=14.14.0"
82
+ },
83
+ "gitHead": "63d16469fdb25698f7d5fb6585300530f0ae5381"
81
84
  }