@mpxjs/webpack-plugin 2.9.0-beta.2 → 2.9.0-beta.3

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 (46) hide show
  1. package/lib/dependencies/CommonJsExtractDependency.js +51 -0
  2. package/lib/extractor.js +1 -0
  3. package/lib/helpers.js +9 -1
  4. package/lib/index.js +88 -17
  5. package/lib/json-compiler/helper.js +4 -3
  6. package/lib/json-compiler/index.js +4 -1
  7. package/lib/loader.js +1 -1
  8. package/lib/native-loader.js +18 -6
  9. package/lib/platform/json/wx/index.js +44 -2
  10. package/lib/platform/run-rules.js +2 -1
  11. package/lib/platform/template/normalize-component-rules.js +2 -0
  12. package/lib/platform/template/wx/component-config/fix-html-tag.js +17 -0
  13. package/lib/platform/template/wx/component-config/index.js +2 -0
  14. package/lib/platform/template/wx/index.js +45 -14
  15. package/lib/runtime/base.styl +9 -1
  16. package/lib/runtime/components/web/filterTag.js +9 -30
  17. package/lib/runtime/components/web/getInnerListeners.js +2 -14
  18. package/lib/runtime/components/web/mpx-keep-alive.vue +8 -17
  19. package/lib/runtime/components/web/mpx-movable-view.vue +28 -9
  20. package/lib/runtime/components/web/mpx-picker-view.vue +1 -1
  21. package/lib/runtime/components/web/mpx-scroll-view.vue +13 -6
  22. package/lib/runtime/components/web/mpx-video.vue +123 -89
  23. package/lib/runtime/components/web/mpx-web-view.vue +119 -81
  24. package/lib/runtime/components/wx/default-page.mpx +27 -0
  25. package/lib/runtime/optionProcessor.js +4 -2
  26. package/lib/style-compiler/index.js +5 -1
  27. package/lib/template-compiler/bind-this.js +248 -48
  28. package/lib/template-compiler/compiler.js +69 -109
  29. package/lib/template-compiler/index.js +16 -1
  30. package/lib/utils/dom-tag-config.js +101 -0
  31. package/lib/utils/make-map.js +12 -0
  32. package/lib/utils/string.js +7 -1
  33. package/lib/utils/ts-loader-watch-run-loader-filter.js +1 -1
  34. package/lib/web/processJSON.js +35 -0
  35. package/lib/web/processMainScript.js +1 -1
  36. package/lib/web/processTemplate.js +18 -35
  37. package/lib/web/script-helper.js +5 -2
  38. package/package.json +4 -4
  39. package/lib/json-compiler/default-page.mpx +0 -3
  40. package/lib/template-compiler/preprocessor.js +0 -29
  41. package/lib/wxss/compile-exports.js +0 -52
  42. package/lib/wxss/createResolver.js +0 -36
  43. package/lib/wxss/css-base.js +0 -79
  44. package/lib/wxss/getLocalIdent.js +0 -25
  45. package/lib/wxss/localsLoader.js +0 -44
  46. package/lib/wxss/processCss.js +0 -274
@@ -0,0 +1,51 @@
1
+ const ModuleDependency = require('webpack/lib/dependencies/ModuleDependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+
4
+ class CommonJsExtractDependency extends ModuleDependency {
5
+ constructor (request, range) {
6
+ super(request)
7
+ this.range = range
8
+ }
9
+
10
+ get type () {
11
+ return 'mpx cjs extract'
12
+ }
13
+
14
+ get category () {
15
+ return 'commonjs'
16
+ }
17
+ }
18
+
19
+ CommonJsExtractDependency.Template = class CommonJsExtractDependencyTemplate extends (
20
+ ModuleDependency.Template
21
+ ) {
22
+ apply (
23
+ dep,
24
+ source,
25
+ {
26
+ runtimeTemplate,
27
+ moduleGraph,
28
+ chunkGraph,
29
+ runtimeRequirements
30
+ }
31
+ ) {
32
+ let content = ''
33
+ if (!dep.weak) {
34
+ content = runtimeTemplate.moduleExports({
35
+ module: moduleGraph.getModule(dep),
36
+ chunkGraph,
37
+ request: dep.request,
38
+ weak: dep.weak,
39
+ runtimeRequirements
40
+ })
41
+ }
42
+ source.replace(dep.range[0], dep.range[1] - 1, content)
43
+ }
44
+ }
45
+
46
+ makeSerializable(
47
+ CommonJsExtractDependency,
48
+ '@mpxjs/webpack-plugin/lib/dependencies/CommonJsExtractDependency'
49
+ )
50
+
51
+ module.exports = CommonJsExtractDependency
package/lib/extractor.js CHANGED
@@ -116,5 +116,6 @@ module.exports.pitch = async function (remainingRequest) {
116
116
  }
117
117
  }
118
118
 
119
+ if (!resultSource) buildInfo.isEmpty = true
119
120
  return resultSource
120
121
  }
package/lib/helpers.js CHANGED
@@ -20,7 +20,15 @@ module.exports = function createHelpers (loaderContext) {
20
20
  const { mode, env } = loaderContext.getMpx() || {}
21
21
 
22
22
  function getRequire (type, part, extraOptions, index) {
23
- return 'require(' + getRequestString(type, part, extraOptions, index) + ')'
23
+ let extract = false
24
+ switch (type) {
25
+ // eslint-disable-next-line no-fallthrough
26
+ case 'json':
27
+ case 'styles':
28
+ case 'template':
29
+ extract = true
30
+ }
31
+ return (extract ? 'require.extract(' : 'require(') + getRequestString(type, part, extraOptions, index) + ')'
24
32
  }
25
33
 
26
34
  function getImport (type, part, extraOptions, index) {
package/lib/index.js CHANGED
@@ -8,6 +8,7 @@ const ReplaceDependency = require('./dependencies/ReplaceDependency')
8
8
  const NullFactory = require('webpack/lib/NullFactory')
9
9
  const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
10
10
  const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
11
+ const CommonJsExtractDependency = require('./dependencies/CommonJsExtractDependency')
11
12
  const harmonySpecifierTag = require('webpack/lib/dependencies/HarmonyImportDependencyParserPlugin').harmonySpecifierTag
12
13
  const NormalModule = require('webpack/lib/NormalModule')
13
14
  const EntryPlugin = require('webpack/lib/EntryPlugin')
@@ -123,6 +124,7 @@ class MpxWebpackPlugin {
123
124
  options.resolveMode = options.resolveMode || 'webpack'
124
125
  options.writeMode = options.writeMode || 'changed'
125
126
  options.autoScopeRules = options.autoScopeRules || {}
127
+ options.renderOptimizeRules = options.renderOptimizeRules || {}
126
128
  options.autoVirtualHostRules = options.autoVirtualHostRules || {}
127
129
  options.forceDisableProxyCtor = options.forceDisableProxyCtor || false
128
130
  options.transMpxRules = options.transMpxRules || {
@@ -169,6 +171,13 @@ class MpxWebpackPlugin {
169
171
  options.asyncSubpackageRules = options.asyncSubpackageRules || null
170
172
  options.retryRequireAsync = options.retryRequireAsync || false
171
173
  options.enableAliRequireAsync = options.enableAliRequireAsync || false
174
+ options.optimizeSize = options.optimizeSize || false
175
+ let proxyComponentEventsRules = []
176
+ const proxyComponentEventsRulesRaw = options.proxyComponentEventsRules
177
+ if (proxyComponentEventsRulesRaw) {
178
+ proxyComponentEventsRules = Array.isArray(proxyComponentEventsRulesRaw) ? proxyComponentEventsRulesRaw : [proxyComponentEventsRulesRaw]
179
+ }
180
+ options.proxyComponentEventsRules = proxyComponentEventsRules
172
181
  this.options = options
173
182
  // Hack for buildDependencies
174
183
  const rawResolveBuildDependencies = FileSystemInfo.prototype.resolveBuildDependencies
@@ -293,6 +302,14 @@ class MpxWebpackPlugin {
293
302
  warnings.push(`webpack options: MpxWebpackPlugin accept options.output.filename to be ${outputFilename} only, custom options.output.filename will be ignored!`)
294
303
  }
295
304
  compiler.options.output.filename = compiler.options.output.chunkFilename = outputFilename
305
+ if (this.options.optimizeSize) {
306
+ compiler.options.optimization.chunkIds = 'total-size'
307
+ compiler.options.optimization.moduleIds = 'natural'
308
+ compiler.options.optimization.mangleExports = 'size'
309
+ compiler.options.output.globalObject = 'g'
310
+ // todo chunkLoadingGlobal不具备项目唯一性,在多构建产物混编时可能存在问题,尤其在支付宝使用全局对象传递的情况下
311
+ compiler.options.output.chunkLoadingGlobal = 'c'
312
+ }
296
313
  }
297
314
 
298
315
  if (!compiler.options.node || !compiler.options.node.global) {
@@ -386,6 +403,7 @@ class MpxWebpackPlugin {
386
403
  const query = parseQuery(obj.query || '?')
387
404
  return query.isPage && !query.type
388
405
  }
406
+
389
407
  // new PartialCompilePlugin(this.options.partialCompile).apply(compiler)
390
408
  compiler.resolverFactory.hooks.resolver.intercept({
391
409
  factory: (type, hook) => {
@@ -394,13 +412,13 @@ class MpxWebpackPlugin {
394
412
  name: 'MpxPartialCompilePlugin',
395
413
  stage: -100
396
414
  }, (obj, resolverContext, callback) => {
397
- if (obj.path.startsWith(require.resolve('./json-compiler/default-page.mpx'))) {
415
+ if (obj.path.startsWith(require.resolve('./runtime/components/wx/default-page.mpx'))) {
398
416
  return callback(null, obj)
399
417
  }
400
418
  if (isResolvingPage(obj) && !matchCondition(obj.path, this.options.partialCompile)) {
401
419
  const infix = obj.query ? '&' : '?'
402
420
  obj.query += `${infix}resourcePath=${obj.path}`
403
- obj.path = require.resolve('./json-compiler/default-page.mpx')
421
+ obj.path = require.resolve('./runtime/components/wx/default-page.mpx')
404
422
  }
405
423
  callback(null, obj)
406
424
  })
@@ -543,6 +561,9 @@ class MpxWebpackPlugin {
543
561
  compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
544
562
  compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
545
563
 
564
+ compilation.dependencyFactories.set(CommonJsExtractDependency, normalModuleFactory)
565
+ compilation.dependencyTemplates.set(CommonJsExtractDependency, new CommonJsExtractDependency.Template())
566
+
546
567
  compilation.dependencyFactories.set(RecordVueContentDependency, new NullFactory())
547
568
  compilation.dependencyTemplates.set(RecordVueContentDependency, new RecordVueContentDependency.Template())
548
569
  })
@@ -617,6 +638,7 @@ class MpxWebpackPlugin {
617
638
  appTitle: 'Mpx homepage',
618
639
  attributes: this.options.attributes,
619
640
  externals: this.options.externals,
641
+ renderOptimizeRules: this.options.renderOptimizeRules,
620
642
  useRelativePath: this.options.useRelativePath,
621
643
  removedChunks: [],
622
644
  forceProxyEventRules: this.options.forceProxyEventRules,
@@ -635,6 +657,7 @@ class MpxWebpackPlugin {
635
657
  })
636
658
  },
637
659
  asyncSubpackageRules: this.options.asyncSubpackageRules,
660
+ proxyComponentEventsRules: this.options.proxyComponentEventsRules,
638
661
  pathHash: (resourcePath) => {
639
662
  if (this.options.pathHashMode === 'relative' && this.options.projectRoot) {
640
663
  return hash(path.relative(this.options.projectRoot, resourcePath))
@@ -696,7 +719,15 @@ class MpxWebpackPlugin {
696
719
  mpx.extractedFilesCache.set(resource, file)
697
720
  return file
698
721
  },
699
- recordResourceMap: ({ resourcePath, resourceType, outputPath, packageRoot = '', recordOnly, warn, error }) => {
722
+ recordResourceMap: ({
723
+ resourcePath,
724
+ resourceType,
725
+ outputPath,
726
+ packageRoot = '',
727
+ recordOnly,
728
+ warn,
729
+ error
730
+ }) => {
700
731
  const packageName = packageRoot || 'main'
701
732
  const resourceMap = mpx[`${resourceType}sMap`] || mpx.otherResourcesMap
702
733
  const currentResourceMap = resourceMap.main ? resourceMap[packageName] = resourceMap[packageName] || {} : resourceMap
@@ -921,6 +952,17 @@ class MpxWebpackPlugin {
921
952
  })
922
953
 
923
954
  compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
955
+ // 移除extractor抽取后的空模块
956
+ for (const module of modules) {
957
+ if (module.buildInfo.isEmpty) {
958
+ for (const connection of moduleGraph.getIncomingConnections(module)) {
959
+ if (connection.dependency.type === 'mpx cjs extract') {
960
+ connection.weak = true
961
+ connection.dependency.weak = true
962
+ }
963
+ }
964
+ }
965
+ }
924
966
  // 自动跟进分包配置修改splitChunksPlugin配置
925
967
  if (splitChunksPlugin) {
926
968
  let needInit = false
@@ -1094,6 +1136,31 @@ class MpxWebpackPlugin {
1094
1136
  stage: -1000
1095
1137
  }, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers, expr.arguments))
1096
1138
 
1139
+ const requireExtractHandler = (expr, members, args) => {
1140
+ if (members[0] === 'extract') {
1141
+ const request = expr.arguments[0].value
1142
+ const range = expr.range
1143
+ const dep = new CommonJsExtractDependency(request, range)
1144
+ parser.state.current.addDependency(dep)
1145
+ if (args) parser.walkExpressions(args)
1146
+ return true
1147
+ }
1148
+ }
1149
+
1150
+ parser.hooks.callMemberChain
1151
+ .for('require')
1152
+ .tap({
1153
+ name: 'MpxWebpackPlugin',
1154
+ stage: -2000
1155
+ }, (expr, members) => requireExtractHandler(expr, members))
1156
+
1157
+ parser.hooks.callMemberChainOfCallMemberChain
1158
+ .for('require')
1159
+ .tap({
1160
+ name: 'MpxWebpackPlugin',
1161
+ stage: -2000
1162
+ }, (expr, calleeMembers, callExpr) => requireExtractHandler(callExpr, calleeMembers, expr.arguments))
1163
+
1097
1164
  // hack babel polyfill global
1098
1165
  parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
1099
1166
  if (/core-js.+microtask/.test(parser.state.module.resource)) {
@@ -1313,6 +1380,8 @@ class MpxWebpackPlugin {
1313
1380
  chunkLoadingGlobal
1314
1381
  } = compilation.outputOptions
1315
1382
 
1383
+ const chunkLoadingGlobalStr = JSON.stringify(chunkLoadingGlobal)
1384
+
1316
1385
  function getTargetFile (file) {
1317
1386
  let targetFile = file
1318
1387
  const queryStringIdx = targetFile.indexOf('?')
@@ -1332,7 +1401,7 @@ class MpxWebpackPlugin {
1332
1401
 
1333
1402
  const originalSource = compilation.assets[chunkFile]
1334
1403
  const source = new ConcatSource()
1335
- source.add(`\nvar ${globalObject} = ${globalObject} || {};\n\n`)
1404
+ source.add(`\nvar ${globalObject} = {};\n`)
1336
1405
 
1337
1406
  relativeChunks.forEach((relativeChunk, index) => {
1338
1407
  const relativeChunkFile = relativeChunk.files.values().next().value
@@ -1349,16 +1418,16 @@ class MpxWebpackPlugin {
1349
1418
  if (compilation.options.entry[chunk.name]) {
1350
1419
  // 在rootChunk中挂载jsonpCallback
1351
1420
  source.add('// process ali subpackages runtime in root chunk\n' +
1352
- 'var context = (function() { return this })() || Function("return this")();\n\n')
1353
- source.add(`context[${JSON.stringify(chunkLoadingGlobal)}] = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
1421
+ 'var context = (function() { return this })() || Function("return this")();\n')
1422
+ source.add(`context[${chunkLoadingGlobalStr}] = ${globalObject}[${chunkLoadingGlobalStr}] = require("${relativePath}");\n`)
1354
1423
  } else {
1355
1424
  // 其余chunk中通过context全局传递runtime
1356
1425
  source.add('// process ali subpackages runtime in other chunk\n' +
1357
- 'var context = (function() { return this })() || Function("return this")();\n\n')
1358
- source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = context[${JSON.stringify(chunkLoadingGlobal)}];\n`)
1426
+ 'var context = (function() { return this })() || Function("return this")();\n')
1427
+ source.add(`${globalObject}[${chunkLoadingGlobalStr}] = context[${chunkLoadingGlobalStr}];\n`)
1359
1428
  }
1360
1429
  } else {
1361
- source.add(`${globalObject}[${JSON.stringify(chunkLoadingGlobal)}] = require("${relativePath}");\n`)
1430
+ source.add(`${globalObject}[${chunkLoadingGlobalStr}] = require("${relativePath}");\n`)
1362
1431
  }
1363
1432
  } else {
1364
1433
  source.add(`require("${relativePath}");\n`)
@@ -1366,10 +1435,11 @@ class MpxWebpackPlugin {
1366
1435
  })
1367
1436
 
1368
1437
  if (isRuntime) {
1369
- source.add('var context = (function() { return this })() || Function("return this")();\n')
1370
- source.add(`
1438
+ if (mpx.mode === 'ali' || mpx.mode === 'qq') {
1439
+ source.add(`
1371
1440
  // Fix babel runtime in some quirky environment like ali & qq dev.
1372
1441
  try {
1442
+ var context = (function() { return this })() || Function("return this")();
1373
1443
  if(!context.console){
1374
1444
  context.console = console;
1375
1445
  context.setInterval = setInterval;
@@ -1410,8 +1480,9 @@ try {
1410
1480
  }
1411
1481
  } catch(e){
1412
1482
  }\n`)
1483
+ }
1413
1484
  source.add(originalSource)
1414
- source.add(`\nmodule.exports = ${globalObject}[${JSON.stringify(chunkLoadingGlobal)}];\n`)
1485
+ source.add(`\nmodule.exports = ${globalObject}[${chunkLoadingGlobalStr}];\n`)
1415
1486
  } else {
1416
1487
  source.add(originalSource)
1417
1488
  }
@@ -1469,8 +1540,8 @@ try {
1469
1540
  })
1470
1541
 
1471
1542
  const typeLoaderProcessInfo = {
1472
- styles: ['css-loader', wxssLoaderPath, styleCompilerPath],
1473
- template: ['html-loader', wxmlLoaderPath, templateCompilerPath]
1543
+ styles: ['node_modules/css-loader', wxssLoaderPath, styleCompilerPath],
1544
+ template: ['node_modules/html-loader', wxmlLoaderPath, templateCompilerPath]
1474
1545
  }
1475
1546
 
1476
1547
  // 应用过rules后,注入mpx相关资源编译loader
@@ -1533,15 +1604,15 @@ try {
1533
1604
  if (mpx.mode === 'web') {
1534
1605
  const mpxStyleOptions = queryObj.mpxStyleOptions
1535
1606
  const firstLoader = loaders[0] ? toPosix(loaders[0].loader) : ''
1536
- const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher')
1607
+ const isPitcherRequest = firstLoader.includes('node_modules/vue-loader/lib/loaders/pitcher')
1537
1608
  let cssLoaderIndex = -1
1538
1609
  let vueStyleLoaderIndex = -1
1539
1610
  let mpxStyleLoaderIndex = -1
1540
1611
  loaders.forEach((loader, index) => {
1541
1612
  const currentLoader = toPosix(loader.loader)
1542
- if (currentLoader.includes('css-loader') && cssLoaderIndex === -1) {
1613
+ if (currentLoader.includes('node_modules/css-loader') && cssLoaderIndex === -1) {
1543
1614
  cssLoaderIndex = index
1544
- } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader') && vueStyleLoaderIndex === -1) {
1615
+ } else if (currentLoader.includes('node_modules/vue-loader/lib/loaders/stylePostLoader') && vueStyleLoaderIndex === -1) {
1545
1616
  vueStyleLoaderIndex = index
1546
1617
  } else if (currentLoader.includes(styleCompilerPath) && mpxStyleLoaderIndex === -1) {
1547
1618
  mpxStyleLoaderIndex = index
@@ -22,6 +22,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
22
22
 
23
23
  const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
24
24
  const urlToRequest = r => loaderUtils.urlToRequest(r)
25
+ const isScript = ext => /\.(ts|js)$/.test(ext)
25
26
 
26
27
  const dynamicEntryMap = new Map()
27
28
 
@@ -73,7 +74,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
73
74
  const resourceName = path.join(parsed.dir, parsed.name)
74
75
 
75
76
  if (!outputPath) {
76
- if (ext === '.js' && resourceName.includes('node_modules') && mode !== 'web') {
77
+ if (isScript(ext) && resourceName.includes('node_modules') && mode !== 'web') {
77
78
  let root = info.descriptionFileRoot
78
79
  let name = 'nativeComponent'
79
80
  if (info.descriptionFileData) {
@@ -91,7 +92,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
91
92
  outputPath = getOutputPath(resourcePath, 'component')
92
93
  }
93
94
  }
94
- if (ext === '.js' && mode !== 'web') {
95
+ if (isScript(ext) && mode !== 'web') {
95
96
  resource = `!!${nativeLoaderPath}!${resource}`
96
97
  }
97
98
 
@@ -131,7 +132,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
131
132
  outputPath = /^(.*?)(\.[^.]*)?$/.exec(relative)[1]
132
133
  }
133
134
  }
134
- if (ext === '.js' && mode !== 'web') {
135
+ if (isScript(ext) && mode !== 'web') {
135
136
  resource = `!!${nativeLoaderPath}!${resource}`
136
137
  }
137
138
  const entry = getDynamicEntry(resource, 'page', outputPath, tarRoot, publicPath + tarRoot)
@@ -154,6 +154,9 @@ module.exports = function (content) {
154
154
  if (!json.usingComponents) {
155
155
  json.usingComponents = {}
156
156
  }
157
+ if (!json.component && mode === 'swan') {
158
+ json.component = true
159
+ }
157
160
  }
158
161
  } else if (componentsMap[resourcePath]) {
159
162
  // component
@@ -250,7 +253,7 @@ module.exports = function (content) {
250
253
  const localPages = []
251
254
  const subPackagesCfg = {}
252
255
  const pageKeySet = new Set()
253
- const defaultPagePath = require.resolve('./default-page.mpx')
256
+ const defaultPagePath = require.resolve('../runtime/components/wx/default-page.mpx')
254
257
  const processPages = (pages, context, tarRoot = '', callback) => {
255
258
  if (pages) {
256
259
  const pagesCache = []
package/lib/loader.js CHANGED
@@ -285,7 +285,7 @@ module.exports = function (content) {
285
285
  let ctor = 'App'
286
286
  if (ctorType === 'page') {
287
287
  // swan也默认使用Page构造器
288
- if (mpx.forceUsePageCtor || mode === 'ali' || mode === 'swan') {
288
+ if (mpx.forceUsePageCtor || mode === 'ali') {
289
289
  ctor = 'Page'
290
290
  } else {
291
291
  ctor = 'Component'
@@ -8,7 +8,7 @@ const async = require('async')
8
8
  const { matchCondition } = require('./utils/match-condition')
9
9
  const { JSON_JS_EXT } = require('./utils/const')
10
10
  const getRulesRunner = require('./platform')
11
-
11
+ // todo native-loader考虑与mpx-loader或加强复用,原生组件约等于4个区块都为src的.mpx文件
12
12
  module.exports = function (content) {
13
13
  this.cacheable()
14
14
 
@@ -44,6 +44,8 @@ module.exports = function (content) {
44
44
  scss: '.scss'
45
45
  }
46
46
 
47
+ const TS_EXT = '.ts'
48
+
47
49
  let useJSONJS = false
48
50
  let cssLang = ''
49
51
  const hasScoped = (queryObj.scoped || autoScope) && mode === 'ali'
@@ -54,7 +56,7 @@ module.exports = function (content) {
54
56
  this.resolve(parsed.dir, resourceName + extName, callback)
55
57
  }
56
58
 
57
- function checkCSSLangFiles (callback) {
59
+ function checkCSSLangFile (callback) {
58
60
  const langs = mpx.nativeConfig.cssLangs || ['less', 'stylus', 'scss', 'sass']
59
61
  const results = []
60
62
  async.eachOf(langs, function (lang, i, callback) {
@@ -89,6 +91,15 @@ module.exports = function (content) {
89
91
  })
90
92
  }
91
93
 
94
+ function checkTSFile (callback) {
95
+ checkFileExists(TS_EXT, (err, result) => {
96
+ if (!err && result) {
97
+ typeResourceMap.script = result
98
+ }
99
+ callback()
100
+ })
101
+ }
102
+
92
103
  const emitWarning = (msg) => {
93
104
  this.emitWarning(
94
105
  new Error('[native-loader][' + this.resource + ']: ' + msg)
@@ -105,15 +116,16 @@ module.exports = function (content) {
105
116
  async.waterfall([
106
117
  (callback) => {
107
118
  async.parallel([
108
- checkCSSLangFiles,
109
- checkJSONJSFile
119
+ checkCSSLangFile,
120
+ checkJSONJSFile,
121
+ checkTSFile
110
122
  ], (err) => {
111
123
  callback(err)
112
124
  })
113
125
  },
114
126
  (callback) => {
115
127
  async.forEachOf(typeExtMap, (ext, key, callback) => {
116
- // 检测到jsonjs或cssLang时跳过对应类型文件检测
128
+ // 对应资源存在预处理类型文件时跳过对应的标准文件检测
117
129
  if (typeResourceMap[key]) {
118
130
  return callback()
119
131
  }
@@ -202,7 +214,7 @@ module.exports = function (content) {
202
214
  let ctorType = 'app'
203
215
  if (pagesMap[resourcePath]) {
204
216
  ctorType = 'page'
205
- if (mpx.forceUsePageCtor || mode === 'ali' || mode === 'swan') {
217
+ if (mpx.forceUsePageCtor || mode === 'ali') {
206
218
  ctor = 'Page'
207
219
  } else {
208
220
  ctor = 'Component'
@@ -3,6 +3,7 @@ const normalizeTest = require('../normalize-test')
3
3
  const changeKey = require('../change-key')
4
4
  const normalize = require('../../../utils/normalize')
5
5
  const { capitalToHyphen } = require('../../../utils/string')
6
+ const { isOriginTag } = require('../../../utils/dom-tag-config')
6
7
 
7
8
  const mpxViewPath = normalize.lib('runtime/components/ali/mpx-view.mpx')
8
9
  const mpxTextPath = normalize.lib('runtime/components/ali/mpx-text.mpx')
@@ -70,6 +71,19 @@ module.exports = function getSpec ({ warn, error }) {
70
71
  return input
71
72
  }
72
73
 
74
+ // 校验输出支付宝 componentGenerics 配置的正确性
75
+ function aliComponentGenericsValidate (input) {
76
+ const componentGenerics = input.componentGenerics
77
+ if (componentGenerics && typeof componentGenerics === 'object') {
78
+ Object.keys(componentGenerics).forEach(key => {
79
+ if (!componentGenerics[key].default) {
80
+ error(`Ali environment componentGenerics need to specify a default custom component! please check the configuration of component ${key}`)
81
+ }
82
+ })
83
+ }
84
+ return input
85
+ }
86
+
73
87
  function fillGlobalComponents (input, { globalComponents }) {
74
88
  if (globalComponents) {
75
89
  Object.assign(globalComponents, input.usingComponents)
@@ -112,10 +126,30 @@ module.exports = function getSpec ({ warn, error }) {
112
126
  }
113
127
  }
114
128
 
129
+ /**
130
+ * 将小程序代码中使用的与原生 HTML tag 同名组件进行转化,以解决与原生tag命名冲突问题。
131
+ * @param {string} type usingComponents
132
+ * @returns input
133
+ */
134
+ function webHTMLTagProcesser (type) {
135
+ return function (input) {
136
+ const usingComponents = input[type]
137
+ if (usingComponents) {
138
+ Object.keys(usingComponents).forEach(tag => {
139
+ if (isOriginTag(tag)) {
140
+ usingComponents[`mpx-com-${tag}`] = usingComponents[tag]
141
+ delete usingComponents[tag]
142
+ }
143
+ })
144
+ }
145
+ return input
146
+ }
147
+ }
148
+
115
149
  const componentRules = [
116
150
  {
117
151
  test: 'componentGenerics',
118
- ali: deletePath(true)
152
+ ali: aliComponentGenericsValidate
119
153
  },
120
154
  {
121
155
  test: 'componentPlaceholder',
@@ -124,6 +158,10 @@ module.exports = function getSpec ({ warn, error }) {
124
158
  tt: deletePath(),
125
159
  jd: deletePath()
126
160
  },
161
+ {
162
+ test: 'usingComponents',
163
+ web: webHTMLTagProcesser('usingComponents')
164
+ },
127
165
  {
128
166
  test: 'usingComponents',
129
167
  ali: componentNameCapitalToHyphen('usingComponents'),
@@ -224,7 +262,7 @@ module.exports = function getSpec ({ warn, error }) {
224
262
  }
225
263
 
226
264
  const spec = {
227
- supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd'],
265
+ supportedModes: ['ali', 'swan', 'qq', 'tt', 'jd', 'qa', 'dd', 'web'],
228
266
  normalizeTest,
229
267
  page: [
230
268
  ...windowRules,
@@ -325,6 +363,10 @@ module.exports = function getSpec ({ warn, error }) {
325
363
  tt: deletePath(),
326
364
  jd: deletePath(true)
327
365
  },
366
+ {
367
+ test: 'usingComponents',
368
+ web: webHTMLTagProcesser('usingComponents')
369
+ },
328
370
  {
329
371
  test: 'usingComponents',
330
372
  ali: componentNameCapitalToHyphen('usingComponents'),
@@ -32,7 +32,8 @@ module.exports = function runRules (rules = [], input, options = {}) {
32
32
  if (result !== undefined) {
33
33
  input = result
34
34
  }
35
- if (!waterfall) break
35
+ // rule 内外 waterfall 均为 false 时跳过
36
+ if (!rule.waterfall && !waterfall) break
36
37
  }
37
38
  }
38
39
  return input
@@ -11,6 +11,8 @@ module.exports = function normalizeComponentRules (cfgs, spec) {
11
11
  if (cfg.test) {
12
12
  result.test = cfg.test
13
13
  }
14
+ // 透传 waterfall 信息
15
+ if (cfg.waterfall) result.waterfall = cfg.waterfall
14
16
  const supportedModes = cfg.supportedModes || spec.supportedModes
15
17
  // 合并component-config中组件的event 与index中公共的event规则
16
18
  const eventRules = (cfg.event || []).concat(spec.event.rules)
@@ -0,0 +1,17 @@
1
+ const { isOriginTag } = require('../../../../utils/dom-tag-config')
2
+
3
+ module.exports = function () {
4
+ return {
5
+ waterfall: true,
6
+ test: (input) => isOriginTag(input),
7
+ // 处理原生tag
8
+ web (tag, data = {}) {
9
+ // @see packages/webpack-plugin/lib/platform/json/wx/index.js webHTMLTagProcesser
10
+ const newTag = `mpx-com-${tag}`
11
+ const usingComponents = data.usingComponents || []
12
+ // 存在同名组件,则返回新tag
13
+ if (usingComponents.includes(newTag)) return newTag
14
+ return tag
15
+ }
16
+ }
17
+ }
@@ -39,6 +39,7 @@ const view = require('./view')
39
39
  const webView = require('./web-view')
40
40
  const wxs = require('./wxs')
41
41
  const component = require('./component')
42
+ const fixHTMLTag = require('./fix-html-tag')
42
43
 
43
44
  module.exports = function getComponentConfigs ({ warn, error }) {
44
45
  /**
@@ -79,6 +80,7 @@ module.exports = function getComponentConfigs ({ warn, error }) {
79
80
 
80
81
  // 转换规则只需以微信为基准配置微信和支付宝的差异部分,比如微信和支付宝都支持但是写法不一致,或者微信支持而支付宝不支持的部分(抛出错误或警告)
81
82
  return [
83
+ fixHTMLTag(),
82
84
  ...Nonsupport({ print }),
83
85
  ad({ print }),
84
86
  view({ print }),