@mpxjs/webpack-plugin 2.7.1-beta.1 → 2.7.1-beta.10

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.
@@ -29,7 +29,7 @@ class DynamicEntryDependency extends NullDependency {
29
29
  const publicPath = compilation.outputOptions.publicPath || ''
30
30
  let { resource, entryType, outputPath, relativePath, originEntryNode } = this
31
31
 
32
- const { packageRoot, outputPath: filename, alreadyOutputed } = mpx.getPackageInfo({
32
+ const { packageRoot, outputPath: filename, alreadyOutputted } = mpx.getPackageInfo({
33
33
  resource,
34
34
  outputPath,
35
35
  resourceType: entryType,
@@ -49,7 +49,7 @@ class DynamicEntryDependency extends NullDependency {
49
49
  // export类型的resultPath需要添加.js后缀
50
50
  if (entryType === 'export') resultPath += '.js'
51
51
 
52
- if (alreadyOutputed) return callback(null, { resultPath })
52
+ if (alreadyOutputted) return callback(null, { resultPath })
53
53
 
54
54
  if (packageRoot) {
55
55
  resource = addQuery(resource, { packageRoot })
@@ -16,10 +16,19 @@ class RecordResourceMapDependency extends NullDependency {
16
16
 
17
17
  mpxAction (module, compilation, callback) {
18
18
  const mpx = compilation.__mpx__
19
- const packageName = this.packageRoot || 'main'
20
- const resourceMap = mpx[`${this.resourceType}sMap`] || mpx.otherResourcesMap
21
- const subResourceMap = resourceMap.main ? resourceMap[packageName] : resourceMap
22
- subResourceMap[this.resourcePath] = this.outputPath
19
+ const { resourcePath, resourceType, outputPath, packageRoot } = this
20
+ mpx.recordResourceMap({
21
+ resourcePath,
22
+ resourceType,
23
+ outputPath,
24
+ packageRoot,
25
+ warn (e) {
26
+ compilation.warnings.push(e)
27
+ },
28
+ error (e) {
29
+ compilation.errors.push(e)
30
+ }
31
+ })
23
32
  return callback()
24
33
  }
25
34
 
package/lib/helpers.js CHANGED
@@ -14,6 +14,7 @@ const defaultLang = {
14
14
 
15
15
  module.exports = function createHelpers (loaderContext) {
16
16
  const rawRequest = loaderUtils.getRemainingRequest(loaderContext)
17
+ const { resourcePath, queryObj } = parseRequest(loaderContext.resource)
17
18
 
18
19
  function getRequire (type, part, extraOptions, index) {
19
20
  return 'require(' + getRequestString(type, part, extraOptions, index) + ')'
@@ -35,9 +36,9 @@ module.exports = function createHelpers (loaderContext) {
35
36
 
36
37
  function getFakeRequest (type, part) {
37
38
  const lang = part.lang || defaultLang[type] || type
38
- const { resourcePath, queryObj } = parseRequest(loaderContext.resource)
39
- if (lang === 'json') queryObj.asScript = true
40
- return addQuery(`${resourcePath}.${lang}`, queryObj)
39
+ const options = { ...queryObj }
40
+ if (lang === 'json') options.asScript = true
41
+ return addQuery(`${resourcePath}.${lang}`, options)
41
42
  }
42
43
 
43
44
  function getRequestString (type, part, extraOptions = {}, index = 0) {
@@ -40,16 +40,9 @@ module.exports = function (content) {
40
40
  const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
41
41
  const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
42
42
  const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
43
- const i18nMethodsVar = 'i18nMethods'
44
- this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest, i18nMethodsVar))
45
-
46
- output += `if (!global.i18n) {
47
- global.i18n = ${JSON.stringify({
48
- locale: i18n.locale,
49
- version: 0
50
- })}
51
- global.i18nMethods = ${i18nMethodsVar}
52
- }\n`
43
+ this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest))
44
+ // 避免该模块被concatenate导致注入的i18n没有最先执行
45
+ this._module.buildInfo.moduleConcatenationBailout = 'i18n'
53
46
  }
54
47
  output += content
55
48
  output += '\n'
package/lib/index.js CHANGED
@@ -219,6 +219,24 @@ class MpxWebpackPlugin {
219
219
  }
220
220
  }
221
221
 
222
+ static getPageEntry (request) {
223
+ return addQuery(request, { isPage: true })
224
+ }
225
+
226
+ static getComponentEntry (request) {
227
+ return addQuery(request, { isComponent: true })
228
+ }
229
+
230
+ static getPluginEntry (request) {
231
+ return addQuery(request, {
232
+ mpx: true,
233
+ extract: true,
234
+ isPlugin: true,
235
+ asScript: true,
236
+ type: 'json'
237
+ })
238
+ }
239
+
222
240
  runModeRules (data) {
223
241
  const { resourcePath, queryObj } = parseRequest(data.resource)
224
242
  if (queryObj.mode) {
@@ -487,13 +505,15 @@ class MpxWebpackPlugin {
487
505
  exportModules: new Set(),
488
506
  // 记录entryModule与entryNode的对应关系,用于体积分析
489
507
  entryNodeModulesMap: new Map(),
490
- extractedMap: {},
508
+ // 记录与asset相关联的modules,用于体积分析
509
+ assetsModulesMap: new Map(),
510
+ // 记录与asset相关联的ast,用于体积分析和esCheck,避免重复parse
511
+ assetsASTsMap: new Map(),
491
512
  usingComponents: {},
492
513
  // todo es6 map读写性能高于object,之后会逐步替换
493
514
  vueContentCache: new Map(),
494
515
  currentPackageRoot: '',
495
516
  wxsContentMap: {},
496
- assetsInfo: new Map(),
497
517
  forceUsePageCtor: this.options.forceUsePageCtor,
498
518
  resolveMode: this.options.resolveMode,
499
519
  mode: this.options.mode,
@@ -577,15 +597,42 @@ class MpxWebpackPlugin {
577
597
  mpx.extractedFilesCache.set(resource, file)
578
598
  return file
579
599
  },
600
+ recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', warn, error }) => {
601
+ const packageName = packageRoot || 'main'
602
+ const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
603
+ const currentResourceMap = resourceMap.main ? resourceMap[packageName] = resourceMap[packageName] || {} : resourceMap
604
+ if (outputPath) {
605
+ if (!currentResourceMap[resourcePath] || currentResourceMap[resourcePath] === true) {
606
+ // 输出路径冲突检测,如果存在输出路径冲突,对输出路径进行重命名
607
+ // todo 用outputPathMap来检测输出路径冲突
608
+ for (let key in currentResourceMap) {
609
+ if (currentResourceMap[key] === outputPath && key !== resourcePath) {
610
+ outputPath = mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })
611
+ 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!`))
612
+ break
613
+ }
614
+ }
615
+ currentResourceMap[resourcePath] = outputPath
616
+ } else {
617
+ if (currentResourceMap[resourcePath] === outputPath) {
618
+ return true
619
+ } else {
620
+ error && error(new Error(`Current ${resourceType} [${resourcePath}] is already registered with outputPath [${currentResourceMap[resourcePath]}], you can not register it with another outputPath [${outputPath}]!`))
621
+ }
622
+ }
623
+ } else if (!currentResourceMap[resourcePath]) {
624
+ currentResourceMap[resourcePath] = true
625
+ }
626
+ return false
627
+ },
580
628
  // 组件和静态资源的输出规则如下:
581
629
  // 1. 主包引用的资源输出至主包
582
630
  // 2. 分包引用且主包引用过的资源输出至主包,不在当前分包重复输出
583
631
  // 3. 分包引用且无其他包引用的资源输出至当前分包
584
632
  // 4. 分包引用且其他分包也引用过的资源,重复输出至当前分包
585
- getPackageInfo: ({ resource, outputPath, resourceType, issuerResource, warn, error }) => {
633
+ getPackageInfo: ({ resource, resourceType, outputPath, issuerResource, warn, error }) => {
586
634
  let packageRoot = ''
587
635
  let packageName = 'main'
588
- let currentResourceMap = {}
589
636
 
590
637
  const { resourcePath } = parseRequest(resource)
591
638
  const currentPackageRoot = mpx.currentPackageRoot
@@ -594,7 +641,6 @@ class MpxWebpackPlugin {
594
641
  const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
595
642
 
596
643
  if (!resourceMap.main) {
597
- currentResourceMap = resourceMap
598
644
  packageRoot = currentPackageRoot
599
645
  packageName = currentPackageName
600
646
  } else {
@@ -625,36 +671,24 @@ class MpxWebpackPlugin {
625
671
  }
626
672
  }
627
673
  resourceMap[packageName] = resourceMap[packageName] || {}
628
- currentResourceMap = resourceMap[packageName]
629
674
  }
630
675
 
631
- let alreadyOutputed = false
632
- if (outputPath) {
633
- outputPath = toPosix(path.join(packageRoot, outputPath))
634
- // 如果之前已经进行过输出,则不需要重复进行
635
- if (currentResourceMap[resourcePath] === outputPath) {
636
- alreadyOutputed = true
637
- } else {
638
- // todo 用outputPathMap来检测冲突
639
- // 输出冲突检测,如果存在输出路径冲突,对输出路径进行重命名
640
- for (let key in currentResourceMap) {
641
- if (currentResourceMap[key] === outputPath && key !== resourcePath) {
642
- outputPath = toPosix(path.join(packageRoot, mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })))
643
- 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!`))
644
- break
645
- }
646
- }
647
- currentResourceMap[resourcePath] = outputPath
648
- }
649
- } else if (!currentResourceMap[resourcePath]) {
650
- currentResourceMap[resourcePath] = true
651
- }
676
+ if (outputPath) outputPath = toPosix(path.join(packageRoot, outputPath))
677
+
678
+ const alreadyOutputted = mpx.recordResourceMap({
679
+ resourcePath,
680
+ resourceType,
681
+ outputPath,
682
+ packageRoot,
683
+ warn,
684
+ error
685
+ })
652
686
 
653
687
  return {
654
688
  packageName,
655
689
  packageRoot,
656
690
  outputPath,
657
- alreadyOutputed
691
+ alreadyOutputted
658
692
  }
659
693
  }
660
694
  }
@@ -729,12 +763,13 @@ class MpxWebpackPlugin {
729
763
  }
730
764
  }
731
765
  } else if (independent) {
732
- // ContextModule和RawModule只在独立分包的情况下添加分包标记,其余默认不添加
766
+ // ContextModule/RawModuleExternalModule等只在独立分包的情况下添加分包标记,其余默认不添加
733
767
  const postfix = `|independent=${independent}|${currentPackageRoot}`
734
- if (module._identifier) {
735
- module._identifier += postfix
736
- } else if (module.identifierStr) {
737
- module.identifierStr += postfix
768
+ const rawIdentifier = module.identifier
769
+ if (rawIdentifier) {
770
+ module.identifier = () => {
771
+ return rawIdentifier.call(module) + postfix
772
+ }
738
773
  }
739
774
  }
740
775
  return rawAddModule.call(compilation, module, callback)
@@ -792,6 +827,12 @@ class MpxWebpackPlugin {
792
827
  return source
793
828
  })
794
829
 
830
+ compilation.hooks.moduleAsset.tap('MpxWebpackPlugin', (module, filename) => {
831
+ const modules = mpx.assetsModulesMap.get(filename) || new Set()
832
+ modules.add(module)
833
+ mpx.assetsModulesMap.set(filename, modules)
834
+ })
835
+
795
836
  compilation.hooks.beforeModuleAssets.tap('MpxWebpackPlugin', () => {
796
837
  const extractedAssetsMap = new Map()
797
838
  for (const module of compilation.modules) {
@@ -804,8 +845,7 @@ class MpxWebpackPlugin {
804
845
  extractedAssetsMap.set(filename, extractedAssets)
805
846
  }
806
847
  extractedAssets.push(extractedInfo)
807
- // todo 后续计算体积时可以通过这个钩子关联静态assets和module
808
- // compilation.hooks.moduleAsset.call(module, filename)
848
+ compilation.hooks.moduleAsset.call(module, filename)
809
849
  }
810
850
  }
811
851
  }
@@ -1032,7 +1072,6 @@ class MpxWebpackPlugin {
1032
1072
  }
1033
1073
 
1034
1074
  const processedChunk = new Set()
1035
- // const rootName = compilation.entries.keys().next().value
1036
1075
  const appName = mpx.appInfo.name
1037
1076
 
1038
1077
  function processChunk (chunk, isRuntime, relativeChunks) {
@@ -1299,14 +1338,40 @@ try {
1299
1338
  const clearFileCache = () => {
1300
1339
  const fs = compiler.intermediateFileSystem
1301
1340
  const cacheLocation = compiler.options.cache.cacheLocation
1302
- return new Promise((resolve, reject) => {
1303
- fs.rm(cacheLocation, {
1304
- recursive: true,
1305
- force: true
1306
- }, (err) => {
1307
- if (err) return reject(err)
1308
- resolve()
1309
- })
1341
+ return new Promise((resolve) => {
1342
+ if (typeof fs.rm === 'function') {
1343
+ fs.rm(cacheLocation, {
1344
+ recursive: true,
1345
+ force: true
1346
+ }, resolve)
1347
+ } else {
1348
+ // polyfill fs.rm
1349
+ const rm = (file, callback) => {
1350
+ async.waterfall([
1351
+ (callback) => {
1352
+ fs.stat(file, callback)
1353
+ },
1354
+ (stats, callback) => {
1355
+ if (stats.isDirectory()) {
1356
+ const dir = file
1357
+ fs.readdir(dir, (err, files) => {
1358
+ if (err) return callback(err)
1359
+ async.each(files, (file, callback) => {
1360
+ file = path.join(dir, file)
1361
+ rm(file, callback)
1362
+ }, (err) => {
1363
+ if (err) return callback(err)
1364
+ fs.rmdir(dir, callback)
1365
+ })
1366
+ })
1367
+ } else {
1368
+ fs.unlink(file, callback)
1369
+ }
1370
+ }
1371
+ ], callback)
1372
+ }
1373
+ rm(cacheLocation, resolve)
1374
+ }
1310
1375
  })
1311
1376
  }
1312
1377
 
@@ -272,9 +272,7 @@ module.exports = function (content) {
272
272
  env
273
273
  })
274
274
  // 对于通过.mpx文件声明的独立分包,默认将其自身的script block视为init module
275
- if (parts.script && queryObj.independent === true) {
276
- queryObj.independent = result
277
- }
275
+ if (queryObj.independent === true) queryObj.independent = result
278
276
  getJSONContent(parts.json || {}, this, (err, content) => {
279
277
  callback(err, result, content)
280
278
  })
package/lib/loader.js CHANGED
@@ -51,7 +51,7 @@ module.exports = function (content) {
51
51
  }
52
52
 
53
53
  // 支持资源query传入isPage或isComponent支持页面/组件单独编译
54
- if (queryObj.isComponent || queryObj.isPage) {
54
+ if (ctorType === 'app' && (queryObj.isComponent || queryObj.isPage)) {
55
55
  const entryName = getEntryName(this) || (queryObj.isComponent ? 'noEntryComponent' : 'noEntryPage')
56
56
  ctorType = queryObj.isComponent ? 'component' : 'page'
57
57
  this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, ctorType, entryName, packageRoot))
@@ -224,16 +224,9 @@ module.exports = function (content) {
224
224
  const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
225
225
  const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
226
226
  const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
227
- const i18nMethodsVar = 'i18nMethods'
228
- this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest, i18nMethodsVar))
229
-
230
- output += `if (!global.i18n) {
231
- global.i18n = ${JSON.stringify({
232
- locale: i18n.locale,
233
- version: 0
234
- })}
235
- global.i18nMethods = ${i18nMethodsVar}
236
- }\n`
227
+ this._module.addDependency(new CommonJsVariableDependency(i18nWxsRequest))
228
+ // 避免该模块被concatenate导致注入的i18n没有最先执行
229
+ this._module.buildInfo.moduleConcatenationBailout = 'i18n'
237
230
  }
238
231
 
239
232
  // 为独立分包注入init module
@@ -241,6 +234,8 @@ module.exports = function (content) {
241
234
  const independentLoader = normalize.lib('independent-loader.js')
242
235
  const independentInitRequest = `!!${independentLoader}!${independent}`
243
236
  this._module.addDependency(new CommonJsVariableDependency(independentInitRequest))
237
+ // 避免该模块被concatenate导致注入的independent init没有最先执行
238
+ this._module.buildInfo.moduleConcatenationBailout = 'independent init'
244
239
  }
245
240
 
246
241
  // 注入构造函数
@@ -267,6 +262,10 @@ module.exports = function (content) {
267
262
 
268
263
  if (template) {
269
264
  const extraOptions = {
265
+ ...template.src ? {
266
+ ...queryObj,
267
+ resourcePath
268
+ } : null,
270
269
  hasScoped,
271
270
  hasComment,
272
271
  isNative,
@@ -287,16 +286,16 @@ module.exports = function (content) {
287
286
  parts.styles.forEach((style, i) => {
288
287
  const scoped = style.scoped || autoScope
289
288
  const extraOptions = {
289
+ // style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerFile
290
+ ...style.src ? {
291
+ ...queryObj,
292
+ isStatic: true,
293
+ issuerFile: mpx.getExtractedFile(addQuery(this.resource, { type: 'styles' }, true))
294
+ } : null,
290
295
  moduleId,
291
296
  scoped
292
297
  }
293
298
  // require style
294
- if (style.src) {
295
- // style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerFile
296
- extraOptions.isStatic = true
297
- const issuerResource = addQuery(this.resource, { type: 'styles' }, true)
298
- extraOptions.issuerFile = mpx.getExtractedFile(issuerResource)
299
- }
300
299
  output += getRequire('styles', style, extraOptions, i) + '\n'
301
300
  })
302
301
  } else if (ctorType === 'app' && mode === 'ali') {
@@ -307,7 +306,10 @@ module.exports = function (content) {
307
306
  output += '/* json */\n'
308
307
  // 给予json默认值, 确保生成json request以自动补全json
309
308
  const json = parts.json || {}
310
- output += getRequire('json', json, json.src && { resourcePath }) + '\n'
309
+ output += getRequire('json', json, json.src && {
310
+ ...queryObj,
311
+ resourcePath
312
+ }) + '\n'
311
313
 
312
314
  // script
313
315
  output += '/* script */\n'
@@ -319,9 +321,12 @@ module.exports = function (content) {
319
321
  if (scriptSrcMode) output += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
320
322
  // 传递ctorType以补全js内容
321
323
  const extraOptions = {
324
+ ...script.src ? {
325
+ ...queryObj,
326
+ resourcePath
327
+ } : null,
322
328
  ctorType
323
329
  }
324
- if (script.src) extraOptions.resourcePath = resourcePath
325
330
  output += getRequire('script', script, extraOptions) + '\n'
326
331
  }
327
332
  callback(null, output)
@@ -137,9 +137,10 @@ module.exports = function (content) {
137
137
  const getRequireByType = (type) => {
138
138
  const src = typeResourceMap[type]
139
139
  const part = { src }
140
- const extraOptions = Object.assign({}, queryObj, {
140
+ const extraOptions = {
141
+ ...queryObj,
141
142
  resourcePath
142
- })
143
+ }
143
144
 
144
145
  switch (type) {
145
146
  case 'template':
@@ -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
  }
@@ -120,6 +120,8 @@ function stringifyArray (value) {
120
120
  }
121
121
 
122
122
  var mpxDashReg = genRegExp('(.+)MpxDash$')
123
+ // 转义字符在wxs正则中存在平台兼容性问题,用[$]规避使用转义字符
124
+ var mpxDashReplaceReg = genRegExp('[$]', 'g')
123
125
 
124
126
  function stringifyObject (value) {
125
127
  var res = ''
@@ -129,7 +131,7 @@ function stringifyObject (value) {
129
131
  if (value[key]) {
130
132
  if (res) res += ' '
131
133
  if (mpxDashReg.test(key)) {
132
- key = hump2dash(mpxDashReg.exec(key)[1])
134
+ key = mpxDashReg.exec(key)[1].replace(mpxDashReplaceReg, '-')
133
135
  }
134
136
  res += key
135
137
  }
@@ -1619,7 +1619,9 @@ function processClass (el, meta) {
1619
1619
  staticClass = staticClass.replace(/\s+/g, ' ')
1620
1620
  if (dynamicClass) {
1621
1621
  let staticClassExp = parseMustache(staticClass).result
1622
- let dynamicClassExp = transDynamicClassExpr(parseMustache(dynamicClass).result)
1622
+ let dynamicClassExp = transDynamicClassExpr(parseMustache(dynamicClass).result, {
1623
+ error: error$1
1624
+ })
1623
1625
  addAttrs(el, [{
1624
1626
  name: targetType,
1625
1627
  // swan中externalClass是通过编译时静态实现,因此需要保留原有的staticClass形式避免externalClass失效
@@ -53,7 +53,8 @@ module.exports = function (raw) {
53
53
  externalClasses,
54
54
  hasScoped,
55
55
  moduleId,
56
- filePath: this.resourcePath,
56
+ // 这里需传递resourcePath和wxsContentMap保持一致
57
+ filePath: resourcePath,
57
58
  i18n,
58
59
  checkUsingComponents: mpx.checkUsingComponents,
59
60
  globalComponents: Object.keys(mpx.usingComponents),
@@ -1,27 +1,32 @@
1
1
  const babylon = require('@babel/parser')
2
2
  const t = require('@babel/types')
3
3
  const generate = require('@babel/generator').default
4
- const dash2hump = require('../utils/hump-dash').dash2hump
5
4
 
6
- module.exports = function transDynamicClassExpr (expr) {
7
- expr = babylon.parseExpression(expr, {
8
- plugins: [
9
- 'objectRestSpread'
10
- ]
11
- })
12
- if (t.isObjectExpression(expr)) {
13
- expr.properties.forEach((property) => {
14
- if (t.isObjectProperty(property) && !property.computed) {
15
- const propertyName = property.key.name || property.key.value
16
- if (/-/.test(propertyName)) {
17
- property.key = t.identifier(dash2hump(propertyName) + 'MpxDash')
18
- } else {
19
- property.key = t.identifier(propertyName)
20
- }
21
- }
5
+ module.exports = function transDynamicClassExpr (expr, { error } = {}) {
6
+ try {
7
+ const ast = babylon.parseExpression(expr, {
8
+ plugins: [
9
+ 'objectRestSpread'
10
+ ]
22
11
  })
12
+ if (t.isObjectExpression(ast)) {
13
+ ast.properties.forEach((property) => {
14
+ if (t.isObjectProperty(property) && !property.computed) {
15
+ const propertyName = property.key.name || property.key.value
16
+ if (/-/.test(propertyName)) {
17
+ if (/\$/.test(propertyName)) {
18
+ error(`Dynamic classname [${propertyName}] is not supported, which includes [-] char and [$] char at the same time.`)
19
+ } else {
20
+ property.key = t.identifier(propertyName.replace(/-/g, '$$') + 'MpxDash')
21
+ }
22
+ }
23
+ }
24
+ })
25
+ }
26
+ return generate(ast, {
27
+ compact: true
28
+ }).code
29
+ } catch (e) {
30
+ return expr
23
31
  }
24
- return generate(expr, {
25
- compact: true
26
- }).code
27
32
  }
@@ -96,7 +96,7 @@ module.exports = function (template, {
96
96
  // todo 后续输出web也采用mpx的scoped处理
97
97
  hasScoped: false,
98
98
  moduleId,
99
- filePath: loaderContext.resourcePath,
99
+ filePath: resourcePath,
100
100
  i18n: null,
101
101
  checkUsingComponents,
102
102
  // web模式下全局组件不会被合入usingComponents中,故globalComponents可以传空
@@ -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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.1-beta.1",
3
+ "version": "2.7.1-beta.10",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -80,5 +80,5 @@
80
80
  "engines": {
81
81
  "node": ">=14.14.0"
82
82
  },
83
- "gitHead": "0ea8bcfff2ccfc433cb2ce43275b7e2af2bc8a61"
83
+ "gitHead": "7c4e400e01958c74f15ec45a09dd43c2c1069435"
84
84
  }