@mpxjs/webpack-plugin 2.8.40-test → 2.8.40-test.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.
Files changed (34) hide show
  1. package/lib/dependencies/DynamicEntryDependency.js +10 -16
  2. package/lib/index.js +87 -60
  3. package/lib/json-compiler/helper.js +8 -5
  4. package/lib/json-compiler/index.js +2 -2
  5. package/lib/loader.js +28 -27
  6. package/lib/parser.js +0 -1
  7. package/lib/platform/index.js +15 -4
  8. package/lib/platform/json/wx/index.js +3 -5
  9. package/lib/platform/run-rules.js +1 -2
  10. package/lib/platform/template/normalize-component-rules.js +41 -42
  11. package/lib/platform/template/wx/component-config/component.js +1 -2
  12. package/lib/platform/template/wx/component-config/fix-component-name.js +21 -0
  13. package/lib/platform/template/wx/component-config/index.js +4 -4
  14. package/lib/platform/template/wx/index.js +21 -16
  15. package/lib/runtime/base.styl +9 -1
  16. package/lib/runtime/components/web/getInnerListeners.js +1 -2
  17. package/lib/runtime/components/web/mpx-image.vue +13 -10
  18. package/lib/runtime/components/web/mpx-movable-view.vue +1 -1
  19. package/lib/runtime/components/web/mpx-picker-view-column.vue +10 -2
  20. package/lib/runtime/components/web/mpx-picker.vue +9 -1
  21. package/lib/runtime/components/web/mpx-swiper.vue +2 -2
  22. package/lib/runtime/optionProcessor.js +321 -264
  23. package/lib/runtime/stringify.wxs +44 -8
  24. package/lib/style-compiler/index.js +1 -2
  25. package/lib/template-compiler/compiler.js +74 -56
  26. package/lib/utils/check-core-version-match.js +18 -14
  27. package/lib/web/processJSON.js +4 -3
  28. package/lib/web/processMainScript.js +84 -0
  29. package/lib/web/processScript.js +21 -204
  30. package/lib/web/processTemplate.js +4 -1
  31. package/lib/web/script-helper.js +202 -0
  32. package/package.json +5 -4
  33. package/lib/platform/template/wx/component-config/fix-html-tag.js +0 -17
  34. package/lib/style-compiler/plugins/trim.js +0 -15
@@ -28,23 +28,10 @@ class DynamicEntryDependency extends NullDependency {
28
28
  return toPosix([request, entryType, outputPath, packageRoot, relativePath, context, ...range].join('|'))
29
29
  }
30
30
 
31
- collectDynamicRequest (mpx) {
32
- if (!this.packageRoot) return
33
- const curValue = mpx.dynamicEntryInfo[this.packageRoot] = mpx.dynamicEntryInfo[this.packageRoot] || {
34
- hasPage: false,
35
- entries: []
36
- }
37
- if (this.entryType === 'page') {
38
- curValue.hasPage = true
39
- } else {
40
- curValue.entries.push(this.request)
41
- }
42
- }
43
-
44
31
  addEntry (compilation, callback) {
45
32
  const mpx = compilation.__mpx__
46
33
  let { request, entryType, outputPath, relativePath, context, originEntryNode, publicPath, resolver } = this
47
- this.collectDynamicRequest(mpx)
34
+
48
35
  async.waterfall([
49
36
  (callback) => {
50
37
  if (context && resolver) {
@@ -56,12 +43,13 @@ class DynamicEntryDependency extends NullDependency {
56
43
  }
57
44
  },
58
45
  (resource, callback) => {
46
+ const { resourcePath } = parseRequest(resource)
47
+
59
48
  if (!outputPath) {
60
- const { resourcePath } = parseRequest(resource)
61
49
  outputPath = mpx.getOutputPath(resourcePath, entryType)
62
50
  }
63
51
 
64
- const { packageRoot, outputPath: filename, alreadyOutputted } = mpx.getPackageInfo({
52
+ const { packageName, packageRoot, outputPath: filename, alreadyOutputted } = mpx.getPackageInfo({
65
53
  resource,
66
54
  outputPath,
67
55
  resourceType: entryType,
@@ -116,6 +104,12 @@ class DynamicEntryDependency extends NullDependency {
116
104
  .catch(err => callback(err))
117
105
 
118
106
  mpx.addEntryPromiseMap.set(key, addEntryPromise)
107
+ mpx.collectDynamicEntryInfo({
108
+ resource,
109
+ packageName,
110
+ filename,
111
+ entryType
112
+ })
119
113
  }
120
114
  }
121
115
  ], callback)
package/lib/index.js CHANGED
@@ -14,6 +14,8 @@ const EntryPlugin = require('webpack/lib/EntryPlugin')
14
14
  const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
15
15
  const FlagEntryExportAsUsedPlugin = require('webpack/lib/FlagEntryExportAsUsedPlugin')
16
16
  const FileSystemInfo = require('webpack/lib/FileSystemInfo')
17
+ const ImportDependency = require('webpack/lib/dependencies/ImportDependency')
18
+ const AsyncDependenciesBlock = require('webpack/lib/AsyncDependenciesBlock')
17
19
  const normalize = require('./utils/normalize')
18
20
  const toPosix = require('./utils/to-posix')
19
21
  const addQuery = require('./utils/add-query')
@@ -112,7 +114,6 @@ class MpxWebpackPlugin {
112
114
  constructor (options = {}) {
113
115
  options.mode = options.mode || 'wx'
114
116
  options.env = options.env || ''
115
-
116
117
  options.srcMode = options.srcMode || options.mode
117
118
  if (options.mode !== options.srcMode && options.srcMode !== 'wx') {
118
119
  errors.push('MpxWebpackPlugin supports srcMode to be "wx" only temporarily!')
@@ -325,36 +326,31 @@ class MpxWebpackPlugin {
325
326
  compiler.options.resolve.plugins.push(packageEntryPlugin)
326
327
  compiler.options.resolve.plugins.push(new FixDescriptionInfoPlugin())
327
328
 
328
- let splitChunksPlugin
329
- let splitChunksOptions
330
-
331
- if (this.options.mode !== 'web') {
332
- const optimization = compiler.options.optimization
333
- optimization.runtimeChunk = {
334
- name: (entrypoint) => {
335
- for (const packageName in mpx.independentSubpackagesMap) {
336
- if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
337
- return `${packageName}/bundle`
338
- }
329
+ const optimization = compiler.options.optimization
330
+ optimization.runtimeChunk = {
331
+ name: (entrypoint) => {
332
+ for (const packageName in mpx.independentSubpackagesMap) {
333
+ if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
334
+ return `${packageName}/bundle`
339
335
  }
340
- return 'bundle'
341
336
  }
337
+ return 'bundle'
342
338
  }
343
- splitChunksOptions = Object.assign({
344
- defaultSizeTypes: ['javascript', 'unknown'],
345
- chunks: 'all',
346
- usedExports: optimization.usedExports === true,
347
- minChunks: 1,
348
- minSize: 1000,
349
- enforceSizeThreshold: Infinity,
350
- maxAsyncRequests: 30,
351
- maxInitialRequests: 30,
352
- automaticNameDelimiter: '-'
353
- }, optimization.splitChunks)
354
- delete optimization.splitChunks
355
- splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
356
- splitChunksPlugin.apply(compiler)
357
339
  }
340
+ const splitChunksOptions = Object.assign({
341
+ defaultSizeTypes: ['javascript', 'unknown'],
342
+ chunks: 'all',
343
+ usedExports: optimization.usedExports === true,
344
+ minChunks: 1,
345
+ minSize: 1000,
346
+ enforceSizeThreshold: Infinity,
347
+ maxAsyncRequests: 30,
348
+ maxInitialRequests: 30,
349
+ automaticNameDelimiter: '-'
350
+ }, optimization.splitChunks)
351
+ delete optimization.splitChunks
352
+ const splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
353
+ splitChunksPlugin.apply(compiler)
358
354
 
359
355
  // 代理writeFile
360
356
  if (this.options.writeMode === 'changed') {
@@ -493,17 +489,17 @@ class MpxWebpackPlugin {
493
489
  }, (compilation, callback) => {
494
490
  processSubpackagesEntriesMap(compilation, (err) => {
495
491
  if (err) return callback(err)
496
- const checkRegisterPack = () => {
497
- for (const packRoot in mpx.dynamicEntryInfo) {
498
- const entryMap = mpx.dynamicEntryInfo[packRoot]
499
- if (!entryMap.hasPage) {
492
+ const checkDynamicEntryInfo = () => {
493
+ for (const packageName in mpx.dynamicEntryInfo) {
494
+ const entryMap = mpx.dynamicEntryInfo[packageName]
495
+ if (packageName !== 'main' && !entryMap.hasPage) {
500
496
  // 引用未注册分包的所有资源
501
- const strRequest = entryMap.entries.join(',')
502
- compilation.errors.push(new Error(`资源${strRequest}目标是打入${packRoot}分包, 但是app.json中并未声明${packRoot}分包`))
497
+ const resources = entryMap.entries.map(info => info.resource).join(',')
498
+ compilation.errors.push(new Error(`资源${resources}通过分包异步声明为${packageName}分包, 但${packageName}分包未注册或不存在相关页面!`))
503
499
  }
504
500
  }
505
501
  }
506
- checkRegisterPack()
502
+ checkDynamicEntryInfo()
507
503
  callback()
508
504
  })
509
505
  })
@@ -563,8 +559,8 @@ class MpxWebpackPlugin {
563
559
  })
564
560
 
565
561
  compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
566
- compilation.warnings = compilation.warnings.concat(warnings)
567
- compilation.errors = compilation.errors.concat(errors)
562
+ compilation.warnings.push(...warnings)
563
+ compilation.errors.push(...errors)
568
564
  const moduleGraph = compilation.moduleGraph
569
565
 
570
566
  if (!compilation.__mpx__) {
@@ -593,7 +589,7 @@ class MpxWebpackPlugin {
593
589
  subpackagesEntriesMap: {},
594
590
  replacePathMap: {},
595
591
  exportModules: new Set(),
596
- // 动态记录注册的分包与注册页面映射
592
+ // 记录动态添加入口的分包信息
597
593
  dynamicEntryInfo: {},
598
594
  // 记录entryModule与entryNode的对应关系,用于体积分析
599
595
  entryNodeModulesMap: new Map(),
@@ -635,8 +631,20 @@ class MpxWebpackPlugin {
635
631
  useRelativePath: this.options.useRelativePath,
636
632
  removedChunks: [],
637
633
  forceProxyEventRules: this.options.forceProxyEventRules,
638
- enableRequireAsync: this.options.mode === 'wx' || (this.options.mode === 'ali' && this.options.enableAliRequireAsync),
634
+ supportRequireAsync: this.options.mode === 'wx' || this.options.mode === 'web' || (this.options.mode === 'ali' && this.options.enableAliRequireAsync),
639
635
  partialCompile: this.options.partialCompile,
636
+ collectDynamicEntryInfo: ({ resource, packageName, filename, entryType }) => {
637
+ const curInfo = mpx.dynamicEntryInfo[packageName] = mpx.dynamicEntryInfo[packageName] || {
638
+ hasPage: false,
639
+ entries: []
640
+ }
641
+ if (entryType === 'page') curInfo.hasPage = true
642
+ curInfo.entries.push({
643
+ entryType,
644
+ resource,
645
+ filename
646
+ })
647
+ },
640
648
  asyncSubpackageRules: this.options.asyncSubpackageRules,
641
649
  optimizeRenderRules: this.options.optimizeRenderRules,
642
650
  pathHash: (resourcePath) => {
@@ -645,7 +653,7 @@ class MpxWebpackPlugin {
645
653
  }
646
654
  return hash(resourcePath)
647
655
  },
648
- addEntry (request, name, callback) {
656
+ addEntry: (request, name, callback) => {
649
657
  const dep = EntryPlugin.createDependency(request, { name })
650
658
  compilation.addEntry(compiler.context, dep, { name }, callback)
651
659
  return dep
@@ -813,10 +821,14 @@ class MpxWebpackPlugin {
813
821
  const rawProcessModuleDependencies = compilation.processModuleDependencies
814
822
  compilation.processModuleDependencies = (module, callback) => {
815
823
  const presentationalDependencies = module.presentationalDependencies || []
824
+ const errors = []
816
825
  async.forEach(presentationalDependencies.filter((dep) => dep.mpxAction), (dep, callback) => {
817
- dep.mpxAction(module, compilation, callback)
818
- }, (err) => {
819
- if (err) compilation.errors.push(err)
826
+ dep.mpxAction(module, compilation, (err) => {
827
+ if (err) errors.push(err)
828
+ callback()
829
+ })
830
+ }, () => {
831
+ compilation.errors.push(...errors)
820
832
  rawProcessModuleDependencies.call(compilation, module, callback)
821
833
  })
822
834
  }
@@ -902,16 +914,17 @@ class MpxWebpackPlugin {
902
914
  }
903
915
 
904
916
  // hack process https://github.com/webpack/webpack/issues/16045
905
- const _handleModuleBuildAndDependenciesRaw = compilation._handleModuleBuildAndDependencies
906
-
907
- compilation._handleModuleBuildAndDependencies = (originModule, module, recursive, callback) => {
908
- const rawCallback = callback
909
- callback = (err) => {
910
- if (err) return rawCallback(err)
911
- return rawCallback(null, module)
912
- }
913
- return _handleModuleBuildAndDependenciesRaw.call(compilation, originModule, module, recursive, callback)
914
- }
917
+ // no need anymore
918
+ // const _handleModuleBuildAndDependenciesRaw = compilation._handleModuleBuildAndDependencies
919
+ //
920
+ // compilation._handleModuleBuildAndDependencies = (originModule, module, recursive, callback) => {
921
+ // const rawCallback = callback
922
+ // callback = (err) => {
923
+ // if (err) return rawCallback(err)
924
+ // return rawCallback(null, module)
925
+ // }
926
+ // return _handleModuleBuildAndDependenciesRaw.call(compilation, originModule, module, recursive, callback)
927
+ // }
915
928
 
916
929
  const rawEmitAsset = compilation.emitAsset
917
930
 
@@ -1076,15 +1089,29 @@ class MpxWebpackPlugin {
1076
1089
  // 删除root query
1077
1090
  if (queryObj.root) request = addQuery(request, {}, false, ['root'])
1078
1091
  // 目前仅wx和ali支持require.async,ali需要开启enableAliRequireAsync,其余平台使用CommonJsAsyncDependency进行模拟抹平
1079
- if (mpx.enableRequireAsync) {
1080
- const dep = new DynamicEntryDependency(request, 'export', '', tarRoot, '', context, range, {
1081
- isRequireAsync: true,
1082
- retryRequireAsync: !!this.options.retryRequireAsync
1083
- })
1092
+ if (mpx.supportRequireAsync) {
1093
+ if (mpx.mode === 'web') {
1094
+ const depBlock = new AsyncDependenciesBlock(
1095
+ {
1096
+ name: tarRoot
1097
+ },
1098
+ expr.loc,
1099
+ request
1100
+ )
1101
+ const dep = new ImportDependency(request, expr.range)
1102
+ dep.loc = expr.loc
1103
+ depBlock.addDependency(dep)
1104
+ parser.state.current.addBlock(depBlock)
1105
+ } else {
1106
+ const dep = new DynamicEntryDependency(request, 'export', '', tarRoot, '', context, range, {
1107
+ isRequireAsync: true,
1108
+ retryRequireAsync: !!this.options.retryRequireAsync
1109
+ })
1084
1110
 
1085
- parser.state.current.addPresentationalDependency(dep)
1086
- // 包含require.async的模块不能被concatenate,避免DynamicEntryDependency中无法获取模块chunk以计算相对路径
1087
- parser.state.module.buildInfo.moduleConcatenationBailout = 'require async'
1111
+ parser.state.current.addPresentationalDependency(dep)
1112
+ // 包含require.async的模块不能被concatenate,避免DynamicEntryDependency中无法获取模块chunk以计算相对路径
1113
+ parser.state.module.buildInfo.moduleConcatenationBailout = 'require async'
1114
+ }
1088
1115
  } else {
1089
1116
  const range = expr.range
1090
1117
  const dep = new CommonJsAsyncDependency(request, range)
@@ -17,7 +17,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
17
17
  const pathHash = mpx.pathHash
18
18
  const getOutputPath = mpx.getOutputPath
19
19
  const mode = mpx.mode
20
- const enableRequireAsync = mpx.enableRequireAsync
20
+ const supportRequireAsync = mpx.supportRequireAsync
21
21
  const asyncSubpackageRules = mpx.asyncSubpackageRules
22
22
 
23
23
  const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
@@ -51,15 +51,15 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
51
51
  resolve(context, component, loaderContext, (err, resource, info) => {
52
52
  if (err) return callback(err)
53
53
  const { resourcePath, queryObj } = parseRequest(resource)
54
- let placeholder = null
54
+ let placeholder = ''
55
55
  if (queryObj.root) {
56
56
  // 删除root query
57
57
  resource = addQuery(resource, {}, false, ['root'])
58
58
  // 目前只有微信支持分包异步化
59
- if (enableRequireAsync) {
59
+ if (supportRequireAsync) {
60
60
  tarRoot = queryObj.root
61
61
  }
62
- } else if (!queryObj.root && asyncSubpackageRules && enableRequireAsync) {
62
+ } else if (!queryObj.root && asyncSubpackageRules && supportRequireAsync) {
63
63
  for (const item of asyncSubpackageRules) {
64
64
  if (matchCondition(resourcePath, item)) {
65
65
  tarRoot = item.root
@@ -97,7 +97,10 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
97
97
  }
98
98
 
99
99
  const entry = getDynamicEntry(resource, 'component', outputPath, tarRoot, relativePath)
100
- callback(null, entry, tarRoot, placeholder)
100
+ callback(null, entry, {
101
+ tarRoot,
102
+ placeholder
103
+ })
101
104
  })
102
105
  }
103
106
 
@@ -211,14 +211,14 @@ module.exports = function (content) {
211
211
  const processComponents = (components, context, callback) => {
212
212
  if (components) {
213
213
  async.eachOf(components, (component, name, callback) => {
214
- processComponent(component, context, { relativePath }, (err, entry, root, placeholder) => {
214
+ processComponent(component, context, { relativePath }, (err, entry, { tarRoot, placeholder } = {}) => {
215
215
  if (err === RESOLVE_IGNORED_ERR) {
216
216
  delete components[name]
217
217
  return callback()
218
218
  }
219
219
  if (err) return callback(err)
220
220
  components[name] = entry
221
- if (root) {
221
+ if (tarRoot) {
222
222
  if (placeholder) {
223
223
  placeholder = normalizePlaceholder(placeholder)
224
224
  if (placeholder.resource) {
package/lib/loader.js CHANGED
@@ -1,7 +1,6 @@
1
1
  const JSON5 = require('json5')
2
2
  const parseComponent = require('./parser')
3
3
  const createHelpers = require('./helpers')
4
- const loaderUtils = require('loader-utils')
5
4
  const parseRequest = require('./utils/parse-request')
6
5
  const { matchCondition } = require('./utils/match-condition')
7
6
  const addQuery = require('./utils/add-query')
@@ -20,6 +19,7 @@ const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDepen
20
19
  const tsWatchRunLoaderFilter = require('./utils/ts-loader-watch-run-loader-filter')
21
20
  const { MPX_APP_MODULE_ID } = require('./utils/const')
22
21
  const path = require('path')
22
+ const processMainScript = require('./web/processMainScript')
23
23
  const getRulesRunner = require('./platform')
24
24
 
25
25
  module.exports = function (content) {
@@ -85,7 +85,6 @@ module.exports = function (content) {
85
85
  if (appName) this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
86
86
  }
87
87
  const loaderContext = this
88
- const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
89
88
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
90
89
  const filePath = this.resourcePath
91
90
  const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
@@ -154,23 +153,33 @@ module.exports = function (content) {
154
153
  // 处理mode为web时输出vue格式文件
155
154
  if (mode === 'web') {
156
155
  if (ctorType === 'app' && !queryObj.isApp) {
157
- const request = addQuery(this.resource, { isApp: true })
158
- const el = mpx.webConfig.el || '#app'
159
- output += `
160
- import App from ${stringifyRequest(request)}
161
- import Vue from 'vue'
162
- new Vue({
163
- el: '${el}',
164
- render: function(h){
165
- return h(App)
166
- }
167
- })\n
168
- `
169
- // 直接结束loader进入parse
170
- this.loaderIndex = -1
171
- return callback(null, output)
156
+ return async.waterfall([
157
+ (callback) => {
158
+ processJSON(parts.json, { loaderContext, pagesMap, componentsMap }, callback)
159
+ },
160
+ (jsonRes, callback) => {
161
+ processMainScript(parts.script, {
162
+ loaderContext,
163
+ ctorType,
164
+ srcMode,
165
+ moduleId,
166
+ isProduction,
167
+ jsonConfig: jsonRes.jsonObj,
168
+ outputPath: queryObj.outputPath || '',
169
+ localComponentsMap: jsonRes.localComponentsMap,
170
+ tabBar: jsonRes.jsonObj.tabBar,
171
+ tabBarMap: jsonRes.tabBarMap,
172
+ tabBarStr: jsonRes.tabBarStr,
173
+ localPagesMap: jsonRes.localPagesMap,
174
+ resource: this.resource
175
+ }, callback)
176
+ }
177
+ ], (err, scriptRes) => {
178
+ if (err) return callback(err)
179
+ this.loaderIndex = -1
180
+ return callback(null, scriptRes.output)
181
+ })
172
182
  }
173
-
174
183
  // 通过RecordVueContentDependency和vueContentCache确保子request不再重复生成vueContent
175
184
  const cacheContent = mpx.vueContentCache.get(filePath)
176
185
  if (cacheContent) return callback(null, cacheContent)
@@ -213,10 +222,6 @@ module.exports = function (content) {
213
222
  output += templateRes.output
214
223
  output += stylesRes.output
215
224
  output += jsonRes.output
216
- if (ctorType === 'app' && jsonRes.jsonObj.window && jsonRes.jsonObj.window.navigationBarTitleText) {
217
- mpx.appTitle = jsonRes.jsonObj.window.navigationBarTitleText
218
- }
219
-
220
225
  processScript(parts.script, {
221
226
  loaderContext,
222
227
  ctorType,
@@ -226,13 +231,10 @@ module.exports = function (content) {
226
231
  componentGenerics,
227
232
  jsonConfig: jsonRes.jsonObj,
228
233
  outputPath: queryObj.outputPath || '',
229
- tabBarMap: jsonRes.tabBarMap,
230
- tabBarStr: jsonRes.tabBarStr,
231
234
  builtInComponentsMap: templateRes.builtInComponentsMap,
232
235
  genericsInfo: templateRes.genericsInfo,
233
236
  wxsModuleMap: templateRes.wxsModuleMap,
234
- localComponentsMap: jsonRes.localComponentsMap,
235
- localPagesMap: jsonRes.localPagesMap
237
+ localComponentsMap: jsonRes.localComponentsMap
236
238
  }, callback)
237
239
  }
238
240
  ], (err, scriptRes) => {
@@ -242,7 +244,6 @@ module.exports = function (content) {
242
244
  callback(null, output)
243
245
  })
244
246
  }
245
-
246
247
  const moduleGraph = this._compilation.moduleGraph
247
248
 
248
249
  const issuer = moduleGraph.getIssuer(this._module)
package/lib/parser.js CHANGED
@@ -2,7 +2,6 @@ const cache = require('lru-cache')(100)
2
2
  const hash = require('hash-sum')
3
3
  const compiler = require('./template-compiler/compiler')
4
4
  const SourceMapGenerator = require('source-map').SourceMapGenerator
5
-
6
5
  const splitRE = /\r?\n/g
7
6
  const emptyRE = /^(?:\/\/)?\s*$/
8
7
 
@@ -1,15 +1,26 @@
1
1
  const runRules = require('./run-rules')
2
2
 
3
- module.exports = function getRulesRunner ({ type, mode, srcMode, data, meta, testKey, mainKey, waterfall, warn, error }) {
3
+ module.exports = function getRulesRunner ({
4
+ type,
5
+ mode,
6
+ srcMode,
7
+ data,
8
+ meta,
9
+ testKey,
10
+ mainKey,
11
+ waterfall,
12
+ warn,
13
+ error
14
+ }) {
4
15
  const specMap = {
5
16
  template: {
6
- wx: require('./template/wx')({ warn, error })
17
+ wx: require('./template/wx')
7
18
  },
8
19
  json: {
9
- wx: require('./json/wx')({ warn, error })
20
+ wx: require('./json/wx')
10
21
  }
11
22
  }
12
- const spec = specMap[type] && specMap[type][srcMode]
23
+ const spec = specMap[type]?.[srcMode]?.({ warn, error })
13
24
  if (spec && spec.supportedModes.indexOf(mode) > -1) {
14
25
  const normalizeTest = spec.normalizeTest
15
26
  const mainRules = mainKey ? spec[mainKey] : spec
@@ -128,10 +128,8 @@ module.exports = function getSpec ({ warn, error }) {
128
128
 
129
129
  /**
130
130
  * 将小程序代码中使用的与原生 HTML tag 或 内建组件 同名的组件进行转化,以解决与原生tag命名冲突问题。
131
- * @param {string} type usingComponents
132
- * @returns input
133
131
  */
134
- function webHTMLTagProcesser (type) {
132
+ function fixComponentName (type) {
135
133
  return function (input) {
136
134
  const usingComponents = input[type]
137
135
  if (usingComponents) {
@@ -160,7 +158,7 @@ module.exports = function getSpec ({ warn, error }) {
160
158
  },
161
159
  {
162
160
  test: 'usingComponents',
163
- web: webHTMLTagProcesser('usingComponents')
161
+ web: fixComponentName('usingComponents')
164
162
  },
165
163
  {
166
164
  test: 'usingComponents',
@@ -365,7 +363,7 @@ module.exports = function getSpec ({ warn, error }) {
365
363
  },
366
364
  {
367
365
  test: 'usingComponents',
368
- web: webHTMLTagProcesser('usingComponents')
366
+ web: fixComponentName('usingComponents')
369
367
  },
370
368
  {
371
369
  test: 'usingComponents',
@@ -32,8 +32,7 @@ module.exports = function runRules (rules = [], input, options = {}) {
32
32
  if (result !== undefined) {
33
33
  input = result
34
34
  }
35
- // rule 内外 waterfall 均为 false 时跳过
36
- if (!rule.waterfall && !waterfall) break
35
+ if (!(rule.waterfall || waterfall)) break
37
36
  }
38
37
  }
39
38
  return input
@@ -8,58 +8,57 @@ const runRules = require('../run-rules')
8
8
  module.exports = function normalizeComponentRules (cfgs, spec) {
9
9
  return cfgs.map((cfg) => {
10
10
  const result = {}
11
- if (cfg.test) {
12
- result.test = cfg.test
13
- }
14
- // 透传 waterfall 信息
11
+ if (cfg.test) result.test = cfg.test
15
12
  if (cfg.waterfall) result.waterfall = cfg.waterfall
16
13
  const supportedModes = cfg.supportedModes || spec.supportedModes
17
14
  // 合并component-config中组件的event 与index中公共的event规则
18
15
  const eventRules = (cfg.event || []).concat(spec.event.rules)
19
16
  supportedModes.forEach((mode) => {
20
- result[mode] = function (el, data) {
21
- data = Object.assign({}, data, { el, eventRules })
22
- const testKey = 'name'
23
- let rAttrsList = []
24
- const options = {
25
- mode,
26
- testKey,
27
- data
28
- }
29
- el.attrsList.forEach((attr) => {
30
- const meta = {}
31
- let rAttr = runRules(spec.directive, attr, {
32
- ...options,
33
- meta
34
- })
35
- // 指令未匹配到时说明为props,因为目前所有的指令都需要转换
36
- if (!meta.processed) {
37
- rAttr = runRules(spec.preProps, rAttr, options)
38
- rAttr = runRules(cfg.props, rAttr, options)
17
+ result[mode] = cfg.skipNormalize
18
+ ? cfg[mode]
19
+ : function (el, data) {
20
+ data = Object.assign({}, data, { el, eventRules })
21
+ const testKey = 'name'
22
+ let rAttrsList = []
23
+ const options = {
24
+ mode,
25
+ testKey,
26
+ data
27
+ }
28
+ el.attrsList.forEach((attr) => {
29
+ const meta = {}
30
+ let rAttr = runRules(spec.directive, attr, {
31
+ ...options,
32
+ meta
33
+ })
34
+ // 指令未匹配到时说明为props,因为目前所有的指令都需要转换
35
+ if (!meta.processed) {
36
+ rAttr = runRules(spec.preProps, rAttr, options)
37
+ rAttr = runRules(cfg.props, rAttr, options)
38
+ if (Array.isArray(rAttr)) {
39
+ rAttr = rAttr.map((attr) => {
40
+ return runRules(spec.postProps, attr, options)
41
+ })
42
+ } else if (rAttr !== false) {
43
+ rAttr = runRules(spec.postProps, rAttr, options)
44
+ }
45
+ }
46
+ // 生成目标attrsList
39
47
  if (Array.isArray(rAttr)) {
40
- rAttr = rAttr.map((attr) => {
41
- return runRules(spec.postProps, attr, options)
42
- })
48
+ rAttrsList = rAttrsList.concat(rAttr)
43
49
  } else if (rAttr !== false) {
44
- rAttr = runRules(spec.postProps, rAttr, options)
50
+ rAttrsList.push(rAttr)
45
51
  }
52
+ })
53
+ el.attrsList = rAttrsList
54
+ el.attrsMap = require('../../template-compiler/compiler').makeAttrsMap(rAttrsList)
55
+ // 前置处理attrs,便于携带信息用于tag的处理
56
+ const rTag = cfg[mode] && cfg[mode].call(this, el.tag, data)
57
+ if (rTag) {
58
+ el.tag = rTag
46
59
  }
47
- // 生成目标attrsList
48
- if (Array.isArray(rAttr)) {
49
- rAttrsList = rAttrsList.concat(rAttr)
50
- } else if (rAttr !== false) {
51
- rAttrsList.push(rAttr)
52
- }
53
- })
54
- el.attrsList = rAttrsList
55
- el.attrsMap = require('../../template-compiler/compiler').makeAttrsMap(rAttrsList)
56
- // 前置处理attrs,便于携带信息用于tag的处理
57
- const rTag = cfg[mode] && cfg[mode].call(this, el.tag, data)
58
- if (rTag) {
59
- el.tag = rTag
60
+ return el
60
61
  }
61
- return el
62
- }
63
62
  })
64
63
  return result
65
64
  })
@@ -1,5 +1,4 @@
1
- const templateCompiler = require('../../../../template-compiler/compiler')
2
- const parseMustache = templateCompiler.parseMustache
1
+ const { parseMustache } = require('../../../../template-compiler/compiler')
3
2
  const normalize = require('../../../../utils/normalize')
4
3
  const TAG_NAME = 'component'
5
4
 
@@ -0,0 +1,21 @@
1
+ const { isOriginTag, isBuildInTag } = require('../../../../utils/dom-tag-config')
2
+
3
+ module.exports = function () {
4
+ return {
5
+ waterfall: true,
6
+ skipNormalize: true,
7
+ supportedModes: ['web'],
8
+ test: (input) => isOriginTag(input) || isBuildInTag(input),
9
+ // 输出web时对组件名进行转义避免与原生tag和内建tag冲突
10
+ web (el, data) {
11
+ const newTag = `mpx-com-${el.tag}`
12
+ const usingComponents = data.usingComponents || []
13
+ // 当前组件名与原生tag或内建tag同名,对组件名进行转义
14
+ // json转义见:platform/json/wx/index.js fixComponentName
15
+ if (usingComponents.includes(newTag)) {
16
+ el.tag = newTag
17
+ }
18
+ return el
19
+ }
20
+ }
21
+ }