@mpxjs/webpack-plugin 2.6.102 → 2.6.107

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.
package/lib/extractor.js CHANGED
@@ -23,9 +23,9 @@ module.exports = function (content) {
23
23
  const mpx = mainCompilation.__mpx__
24
24
 
25
25
  const pagesMap = mpx.pagesMap
26
+ const getOutputPath = mpx.getOutputPath
26
27
 
27
28
  const extract = mpx.extract
28
- const pathHash = mpx.pathHash
29
29
  const extractedMap = mpx.extractedMap
30
30
  const mode = mpx.mode
31
31
  const typeExtMap = config[mode].typeExtMap
@@ -50,8 +50,7 @@ module.exports = function (content) {
50
50
  if (filename) {
51
51
  return filename + typeExtMap[type]
52
52
  } else {
53
- const resourceName = path.parse(resourcePath).name
54
- const outputPath = path.join(type, resourceName + pathHash(resourcePath) + typeExtMap[type])
53
+ const outputPath = getOutputPath(resourcePath, type, { ext: typeExtMap[type] })
55
54
  return mpx.getPackageInfo({
56
55
  resource: resourceRaw,
57
56
  outputPath,
package/lib/index.js CHANGED
@@ -101,6 +101,7 @@ class MpxWebpackPlugin {
101
101
  options.resolveMode = options.resolveMode || 'webpack'
102
102
  options.writeMode = options.writeMode || 'changed'
103
103
  options.autoScopeRules = options.autoScopeRules || {}
104
+ options.autoVirtualHostRules = options.autoVirtualHostRules || {}
104
105
  options.forceDisableInject = options.forceDisableInject || false
105
106
  options.forceDisableProxyCtor = options.forceDisableProxyCtor || false
106
107
  options.transMpxRules = options.transMpxRules || {
@@ -123,6 +124,7 @@ class MpxWebpackPlugin {
123
124
  options.forceUsePageCtor = options.forceUsePageCtor || false
124
125
  options.postcssInlineConfig = options.postcssInlineConfig || {}
125
126
  options.transRpxRules = options.transRpxRules || null
127
+ options.webConfig = options.webConfig || {}
126
128
  options.auditResource = options.auditResource || false
127
129
  options.decodeHTMLText = options.decodeHTMLText || false
128
130
  options.nativeOptions = Object.assign({
@@ -141,6 +143,7 @@ class MpxWebpackPlugin {
141
143
  options.fileConditionRules = options.fileConditionRules || {
142
144
  include: () => true
143
145
  }
146
+ options.customOutputPath = options.customOutputPath || null
144
147
  this.options = options
145
148
  }
146
149
 
@@ -435,7 +438,9 @@ class MpxWebpackPlugin {
435
438
  externalClasses: this.options.externalClasses,
436
439
  projectRoot: this.options.projectRoot,
437
440
  autoScopeRules: this.options.autoScopeRules,
441
+ autoVirtualHostRules: this.options.autoVirtualHostRules,
438
442
  transRpxRules: this.options.transRpxRules,
443
+ webConfig: this.options.webConfig,
439
444
  postcssInlineConfig: this.options.postcssInlineConfig,
440
445
  decodeHTMLText: this.options.decodeHTMLText,
441
446
  // native文件专用相关配置
@@ -482,6 +487,15 @@ class MpxWebpackPlugin {
482
487
  }
483
488
  return hash(hashPath)
484
489
  },
490
+ getOutputPath: (resourcePath, type, { ext = '', conflictPath = '' } = {}) => {
491
+ const name = path.parse(resourcePath).name
492
+ const hash = mpx.pathHash(resourcePath)
493
+ const customOutputPath = this.options.customOutputPath
494
+ if (conflictPath) return conflictPath.replace(/(\.[^\\/]+)?$/, match => hash + match)
495
+ if (typeof customOutputPath === 'function') return customOutputPath(type, name, hash, ext)
496
+ if (type === 'component' || type === 'page') return path.join(type + 's', name + hash, 'index' + ext)
497
+ return path.join(type, name + hash + ext)
498
+ },
485
499
  extract: (content, file, index, sideEffects) => {
486
500
  index = index === -1 ? 0 : index
487
501
  additionalAssets[file] = additionalAssets[file] || []
@@ -547,6 +561,13 @@ class MpxWebpackPlugin {
547
561
  if (currentResourceMap[resourcePath] === outputPath) {
548
562
  alreadyOutputed = true
549
563
  } else {
564
+ for (let key in currentResourceMap) {
565
+ if (currentResourceMap[key] === outputPath && key !== resourcePath) {
566
+ outputPath = toPosix(path.join(packageRoot, mpx.getOutputPath(resourcePath, resourceType, { conflictPath: outputPath })))
567
+ 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!`))
568
+ break
569
+ }
570
+ }
550
571
  currentResourceMap[resourcePath] = outputPath
551
572
  }
552
573
  } else if (!currentResourceMap[resourcePath]) {
@@ -948,6 +969,7 @@ try {
948
969
  context.setTimeout = setTimeout;
949
970
  context.JSON = JSON;
950
971
  context.Math = Math;
972
+ context.Date = Date;
951
973
  context.RegExp = RegExp;
952
974
  context.Infinity = Infinity;
953
975
  context.isFinite = isFinite;
@@ -962,6 +984,22 @@ try {
962
984
  context.ArrayBuffer = ArrayBuffer;
963
985
  context.Symbol = Symbol;
964
986
  context.Reflect = Reflect;
987
+ context.Object = Object;
988
+ context.Error = Error;
989
+ context.Array = Array;
990
+ context.Float32Array = Float32Array;
991
+ context.Float64Array = Float64Array;
992
+ context.Int16Array = Int16Array;
993
+ context.Int32Array = Int32Array;
994
+ context.Int8Array = Int8Array;
995
+ context.Uint16Array = Uint16Array;
996
+ context.Uint32Array = Uint32Array;
997
+ context.Uint8ClampedArray = Uint8ClampedArray;
998
+ context.String = String;
999
+ context.Function = Function;
1000
+ context.SyntaxError = SyntaxError;
1001
+ context.decodeURIComponent = decodeURIComponent;
1002
+ context.encodeURIComponent = encodeURIComponent;
965
1003
  }
966
1004
  } catch(e){
967
1005
  }\n`)
@@ -26,6 +26,7 @@ module.exports = function (raw = '{}') {
26
26
  const options = loaderUtils.getOptions(this) || {}
27
27
  const mainCompilation = getMainCompilation(this._compilation)
28
28
  const mpx = mainCompilation.__mpx__
29
+ const getOutputPath = mpx.getOutputPath
29
30
 
30
31
  const emitWarning = (msg) => {
31
32
  this.emitWarning(
@@ -297,8 +298,7 @@ module.exports = function (raw = '{}') {
297
298
  let relativePath = path.relative(root, resourceName)
298
299
  outputPath = path.join('components', name + pathHash(root), relativePath)
299
300
  } else {
300
- let componentName = parsed.name
301
- outputPath = path.join('components', componentName + pathHash(resourcePath), componentName)
301
+ outputPath = getOutputPath(resourcePath, 'component')
302
302
  }
303
303
  }
304
304
  const { packageRoot, outputPath: componentPath, alreadyOutputed } = mpx.getPackageInfo({
@@ -515,10 +515,10 @@ module.exports = function (raw = '{}') {
515
515
  callback()
516
516
  }
517
517
 
518
- const getPageName = (resourcePath, ext) => {
519
- const baseName = path.basename(resourcePath, ext)
520
- return path.join('pages', baseName + pathHash(resourcePath), baseName)
521
- }
518
+ // const getPageName = (resourcePath, ext) => {
519
+ // const baseName = path.basename(resourcePath, ext)
520
+ // return path.join('pages', baseName + pathHash(resourcePath), baseName)
521
+ // }
522
522
 
523
523
  const processPages = (pages, srcRoot = '', tarRoot = '', context, callback) => {
524
524
  if (pages) {
@@ -552,18 +552,18 @@ module.exports = function (raw = '{}') {
552
552
  const relative = path.relative(context, resourcePath)
553
553
  if (/^\./.test(relative)) {
554
554
  // 如果当前page不存在于context中,对其进行重命名
555
- pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
555
+ pageName = getOutputPath(resourcePath, 'page')
556
556
  emitWarning(`Current page [${resourcePath}] is not in current pages directory [${context}], the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
557
557
  } else {
558
558
  pageName = toPosix(path.join(tarRoot, /^(.*?)(\.[^.]*)?$/.exec(relative)[1]))
559
559
  // 如果当前page与已有page存在命名冲突,也进行重命名
560
- for (let key in pagesMap) {
561
- if (pagesMap[key] === pageName && key !== resourcePath) {
562
- const pageNameRaw = pageName
563
- pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
564
- emitWarning(`Current page [${resourcePath}] is registered with a conflict page path [${pageNameRaw}] which is already existed in system, the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
565
- break
566
- }
560
+ }
561
+ for (let key in pagesMap) {
562
+ if (pagesMap[key] === pageName && key !== resourcePath) {
563
+ const pageNameRaw = pageName
564
+ pageName = getOutputPath(resourcePath, 'page', { conflictPath: pageNameRaw })
565
+ emitWarning(`Current page [${resourcePath}] is registered with a conflict page path [${pageNameRaw}] which is already existed in system, the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
566
+ break
567
567
  }
568
568
  }
569
569
  }
package/lib/loader.js CHANGED
@@ -15,7 +15,7 @@ const processTemplate = require('./web/processTemplate')
15
15
  const readJsonForSrc = require('./utils/read-json-for-src')
16
16
  const normalize = require('./utils/normalize')
17
17
  const getMainCompilation = require('./utils/get-main-compilation')
18
-
18
+ const { MPX_APP_MODULE_ID } = require('./staticConfig')
19
19
  module.exports = function (content) {
20
20
  this.cacheable()
21
21
 
@@ -38,6 +38,7 @@ module.exports = function (content) {
38
38
  const localSrcMode = queryObj.mode
39
39
  const srcMode = localSrcMode || globalSrcMode
40
40
  const vueContentCache = mpx.vueContentCache
41
+ const webRouteMode = mpx.webConfig.routeMode || 'hash'
41
42
  const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
42
43
 
43
44
  // 支持资源query传入page或component支持页面/组件单独编译
@@ -66,7 +67,6 @@ module.exports = function (content) {
66
67
  // component
67
68
  ctorType = 'component'
68
69
  }
69
-
70
70
  const loaderContext = this
71
71
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
72
72
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
@@ -88,7 +88,10 @@ module.exports = function (content) {
88
88
 
89
89
  const filePath = resourcePath
90
90
 
91
- const moduleId = 'm' + mpx.pathHash(filePath)
91
+ let moduleId = 'm' + mpx.pathHash(filePath)
92
+ if (ctorType === 'app') {
93
+ moduleId = MPX_APP_MODULE_ID
94
+ }
92
95
 
93
96
  const parts = parseComponent(content, {
94
97
  filePath,
@@ -242,6 +245,7 @@ module.exports = function (content) {
242
245
  i18n,
243
246
  componentGenerics,
244
247
  projectRoot,
248
+ webRouteMode,
245
249
  jsonConfig: jsonRes.jsonObj,
246
250
  componentId: queryObj.componentId || '',
247
251
  tabBarMap: jsonRes.tabBarMap,
@@ -306,6 +310,7 @@ module.exports = function (content) {
306
310
  ctor = 'Component'
307
311
  }
308
312
  globalInjectCode += `global.currentCtor = ${ctor}\n`
313
+ globalInjectCode += `global.currentResourceType = '${ctorType}'\n`
309
314
  globalInjectCode += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
310
315
  return match.toLowerCase()
311
316
  }))}\n`
@@ -394,6 +399,8 @@ module.exports = function (content) {
394
399
  }
395
400
  })
396
401
  output += styleInjectionCode + '\n'
402
+ } else if (ctorType === 'app' && mode === 'ali') {
403
+ output += getRequire('styles', {}) + '\n'
397
404
  }
398
405
 
399
406
  // json
@@ -79,7 +79,7 @@ module.exports = function ({ print }) {
79
79
  if (isMustache(value)) {
80
80
  // 如果是个变量,报warning
81
81
  baiduValueLog({ name, value })
82
- } else if (supportList.indexOf(value) === -1) {
82
+ } else if (value && supportList.indexOf(value) === -1) {
83
83
  baiduValueLogError({ name, value })
84
84
  }
85
85
  },
@@ -91,7 +91,7 @@ module.exports = function ({ print }) {
91
91
  if (isMustache(value)) {
92
92
  // 如果是个变量,报warning
93
93
  qqValueLog({ name, value })
94
- } else if (supportList.indexOf(value) === -1) {
94
+ } else if (value && supportList.indexOf(value) === -1) {
95
95
  qqValueLogError({ name, value })
96
96
  }
97
97
  },
@@ -103,7 +103,7 @@ module.exports = function ({ print }) {
103
103
  ttValueLog({ name, value })
104
104
  } else {
105
105
  const supportList = ['share', 'getPhoneNumber', 'contact']
106
- if (supportList.indexOf(value) === -1) {
106
+ if (value && supportList.indexOf(value) === -1) {
107
107
  ttValueLogError({ name, value })
108
108
  }
109
109
  }
@@ -54,6 +54,7 @@ module.exports = function (source) {
54
54
  const context = this.context
55
55
  const packageName = 'main'
56
56
  const pagesMap = mpx.pagesMap
57
+ const getOutputPath = mpx.getOutputPath
57
58
  const componentsMap = mpx.componentsMap[packageName]
58
59
  const getEntryNode = mpx.getEntryNode
59
60
  const resolveMode = mpx.resolveMode
@@ -191,8 +192,7 @@ module.exports = function (source) {
191
192
  let relativePath = path.relative(root, resourceName)
192
193
  outputPath = path.join('components', name + pathHash(root), relativePath)
193
194
  } else {
194
- let componentName = parsed.name
195
- outputPath = path.join('components', componentName + pathHash(resourcePath), componentName)
195
+ outputPath = getOutputPath(resourcePath, 'component')
196
196
  }
197
197
  const componentPath = toPosix(outputPath)
198
198
  pluginEntry.publicComponents[name] = componentPath
@@ -1,4 +1,5 @@
1
1
  import { isEmptyObject } from './util'
2
+ const isTouchDevice = 'ontouchstart' in document.documentElement
2
3
 
3
4
  function processModel (listeners, context) {
4
5
  // 该函数只有wx:model的情况下才调用,而且默认e.detail.value有值
@@ -54,58 +55,63 @@ function processTap (listeners, context) {
54
55
  })
55
56
  if (isEmptyObject(listenerMap)) return
56
57
  context.__mpxTapInfo = context.__mpxTapInfo || {}
57
- let events = {
58
- touchstart (e) {
59
- context.__mpxTapInfo.detail = {
60
- x: e.changedTouches[0].pageX,
61
- y: e.changedTouches[0].pageY
62
- }
63
- context.__mpxTapInfo.startTimer = null
64
- context.__mpxTapInfo.needTap = true
65
- context.__mpxTapInfo.hadTouch = true
66
- if (listenerMap.longpress || listenerMap.longtap) {
67
- context.__mpxTapInfo.startTimer = setTimeout(() => {
58
+ let events
59
+ if (isTouchDevice) {
60
+ events = {
61
+ touchstart (e) {
62
+ context.__mpxTapInfo.detail = {
63
+ x: e.changedTouches[0].pageX,
64
+ y: e.changedTouches[0].pageY
65
+ }
66
+ context.__mpxTapInfo.startTimer = null
67
+ context.__mpxTapInfo.needTap = true
68
+ if (listenerMap.longpress || listenerMap.longtap) {
69
+ context.__mpxTapInfo.startTimer = setTimeout(() => {
70
+ context.__mpxTapInfo.needTap = false
71
+ if (listenerMap.longpress) {
72
+ const re = inheritEvent('longpress', e, context.__mpxTapInfo.detail)
73
+ context.$emit('longpress', re)
74
+ }
75
+ if (listenerMap.longtap) {
76
+ const re = inheritEvent('longtap', e, context.__mpxTapInfo.detail)
77
+ context.$emit('longtap', re)
78
+ }
79
+ }, 350)
80
+ }
81
+ },
82
+ touchmove (e) {
83
+ const tapDetailInfo = context.__mpxTapInfo.detail || {}
84
+ const currentPageX = e.changedTouches[0].pageX
85
+ const currentPageY = e.changedTouches[0].pageY
86
+ if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) {
68
87
  context.__mpxTapInfo.needTap = false
69
- if (listenerMap.longpress) {
70
- const re = inheritEvent('longpress', e, context.__mpxTapInfo.detail)
71
- context.$emit('longpress', re)
72
- }
73
- if (listenerMap.longtap) {
74
- const re = inheritEvent('longtap', e, context.__mpxTapInfo.detail)
75
- context.$emit('longtap', re)
76
- }
77
- }, 350)
78
- }
79
- },
80
- touchmove (e) {
81
- const tapDetailInfo = context.__mpxTapInfo.detail || {}
82
- const currentPageX = e.changedTouches[0].pageX
83
- const currentPageY = e.changedTouches[0].pageY
84
- if (Math.abs(currentPageX - tapDetailInfo.x) > 1 || Math.abs(currentPageY - tapDetailInfo.y) > 1) {
85
- context.__mpxTapInfo.needTap = false
88
+ context.__mpxTapInfo.startTimer && clearTimeout(context.__mpxTapInfo.startTimer)
89
+ context.__mpxTapInfo.startTimer = null
90
+ }
91
+ },
92
+ touchend (e) {
86
93
  context.__mpxTapInfo.startTimer && clearTimeout(context.__mpxTapInfo.startTimer)
87
- context.__mpxTapInfo.startTimer = null
88
- }
89
- },
90
- touchend (e) {
91
- context.__mpxTapInfo.startTimer && clearTimeout(context.__mpxTapInfo.startTimer)
92
- if (listenerMap.tap && context.__mpxTapInfo.needTap) {
93
- const re = inheritEvent('tap', e, context.__mpxTapInfo.detail)
94
- context.$emit('tap', re)
94
+ if (listenerMap.tap && context.__mpxTapInfo.needTap) {
95
+ const re = inheritEvent('tap', e, context.__mpxTapInfo.detail)
96
+ context.$emit('tap', re)
97
+ }
95
98
  }
96
- },
97
- click (e) {
98
- if (listenerMap.tap && !context.__mpxTapInfo.hadTouch) {
99
- context.__mpxTapInfo.detail = {
100
- x: e.pageX,
101
- y: e.pageY
99
+ }
100
+ } else {
101
+ events = {
102
+ click (e) {
103
+ if (listenerMap.tap) {
104
+ context.__mpxTapInfo.detail = {
105
+ x: e.pageX,
106
+ y: e.pageY
107
+ }
108
+ const re = inheritEvent('tap', e, context.__mpxTapInfo.detail)
109
+ context.$emit('tap', re)
102
110
  }
103
- const re = inheritEvent('tap', e, context.__mpxTapInfo.detail)
104
- context.$emit('tap', re)
105
111
  }
106
- context.__mpxTapInfo.hadTouch = false
107
112
  }
108
113
  }
114
+
109
115
  mergeListeners(listeners, events, {
110
116
  force: true
111
117
  })
@@ -1,5 +1,6 @@
1
1
  <script>
2
2
  import { inBrowser } from '../../../utils/env'
3
+
3
4
  function isDef (v) {
4
5
  return v !== undefined && v !== null
5
6
  }
@@ -30,7 +31,7 @@
30
31
 
31
32
  function getVnodeKey (vnode) {
32
33
  if (vnode && vnode.componentOptions) {
33
- return vnode.key || vnode.componentOptions.Ctor.cid + (vnode.componentOptions.tag ? ('::' + (vnode.componentOptions.tag)) : '')
34
+ return vnode.componentOptions.Ctor.cid + (vnode.componentOptions.tag ? ('::' + (vnode.componentOptions.tag)) : '')
34
35
  }
35
36
  }
36
37
 
@@ -73,6 +74,8 @@
73
74
  const current = stack[i - 1]
74
75
  if (current.vnode && current.vnodeKey === vnodeKey && current.vnode.componentInstance) {
75
76
  vnode.componentInstance = current.vnode.componentInstance
77
+ // 避免组件实例复用但是vnode.key不一致带来的bad case
78
+ vnode.key = current.vnode.key
76
79
  break
77
80
  }
78
81
  }
@@ -15,7 +15,7 @@
15
15
  'mpx-tab-bar': tabBarPagesMap['mpx-tab-bar']
16
16
  }
17
17
  tabBar.list.forEach(({ pagePath }) => {
18
- const name = pagePath.replace('/', '-')
18
+ const name = pagePath.replace(/\//g, '-')
19
19
  const page = tabBarPagesMap[pagePath]
20
20
  if (page) {
21
21
  components[name] = page
@@ -39,7 +39,7 @@
39
39
  currentComponent () {
40
40
  const index = this.currentIndex
41
41
  const tabItem = tabBar.list[index]
42
- return tabItem.pagePath.replace('/', '-')
42
+ return tabItem.pagePath.replace(/\//g, '-')
43
43
  }
44
44
  },
45
45
  watch: {
@@ -12,6 +12,7 @@ export default function processOption (
12
12
  componentGenerics,
13
13
  genericsInfo,
14
14
  mixin,
15
+ webRouteMode,
15
16
  Vue,
16
17
  VueRouter,
17
18
  i18n
@@ -122,6 +123,7 @@ export default function processOption (
122
123
  })
123
124
  }
124
125
  global.__mpxRouter = option.router = new VueRouter({
126
+ mode: webRouteMode,
125
127
  routes: routes
126
128
  })
127
129
  global.__mpxRouter.stack = []
package/lib/selector.js CHANGED
@@ -23,7 +23,9 @@ module.exports = function (content) {
23
23
  })
24
24
  let part = parts[query.type] || {}
25
25
  if (Array.isArray(part)) {
26
- part = part[query.index]
26
+ part = part[query.index] || {
27
+ content: ''
28
+ }
27
29
  }
28
30
  this.callback(null, part.content, part.map)
29
31
  }
@@ -0,0 +1,4 @@
1
+ module.exports = {
2
+ MPX_ROOT_VIEW: 'mpx-root-view', // 根节点类名
3
+ MPX_APP_MODULE_ID: 'mpx-app-scope' // app文件moduleId
4
+ }
@@ -2,22 +2,28 @@ const getMainCompilation = require('../utils/get-main-compilation')
2
2
  const postcss = require('postcss')
3
3
  const loaderUtils = require('loader-utils')
4
4
  const loadPostcssConfig = require('./load-postcss-config')
5
-
5
+ const { MPX_ROOT_VIEW } = require('../staticConfig')
6
6
  const trim = require('./plugins/trim')
7
7
  const rpx = require('./plugins/rpx')
8
8
  const vw = require('./plugins/vw')
9
9
  const pluginCondStrip = require('./plugins/conditional-strip')
10
10
  const scopeId = require('./plugins/scope-id')
11
+ const transSpecial = require('./plugins/trans-special')
11
12
  const matchCondition = require('../utils/match-condition')
13
+ const parseRequest = require('../utils/parse-request')
12
14
 
13
15
  module.exports = function (css, map) {
14
16
  this.cacheable()
15
17
  const cb = this.async()
16
18
  const loaderOptions = loaderUtils.getOptions(this) || {}
17
-
18
19
  const mainCompilation = getMainCompilation(this._compilation)
19
20
  const mpx = mainCompilation.__mpx__
20
21
  const defs = mpx.defs
22
+ const { resourcePath, queryObj } = parseRequest(this.resource)
23
+ const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
24
+ const componentsMap = mpx.componentsMap[packageName]
25
+ const pagesMap = mpx.pagesMap
26
+ const isApp = (!componentsMap[resourcePath] && !pagesMap[resourcePath])
21
27
 
22
28
  const transRpxRulesRaw = mpx.transRpxRules
23
29
 
@@ -38,6 +44,10 @@ module.exports = function (css, map) {
38
44
  },
39
45
  config.options
40
46
  )
47
+ // ali环境处理host选择器
48
+ if (mpx.mode === 'ali') {
49
+ plugins.push(transSpecial({ id: loaderOptions.moduleId || loaderOptions.mid }))
50
+ }
41
51
 
42
52
  if (loaderOptions.scoped) {
43
53
  const moduleId = loaderOptions.moduleId || loaderOptions.mid
@@ -79,6 +89,10 @@ module.exports = function (css, map) {
79
89
  return postcss(plugins)
80
90
  .process(css, options)
81
91
  .then(result => {
92
+ // ali环境添加全局样式抹平root差异
93
+ if (mpx.mode === 'ali' && isApp) {
94
+ result.css += `\n.${MPX_ROOT_VIEW} { display: inline; line-height: normal; }\n`
95
+ }
82
96
  if (result.messages) {
83
97
  result.messages.forEach(({ type, file }) => {
84
98
  if (type === 'dependency') {
@@ -0,0 +1,21 @@
1
+ const postcss = require('postcss')
2
+ const selectorParser = require('postcss-selector-parser')
3
+
4
+ module.exports = postcss.plugin('trans-special', ({ id }) => root => {
5
+ root.each(function rewriteSelector (node) {
6
+ if (!node.selector) return
7
+ node.selector = selectorParser(selectors => {
8
+ selectors.each(selector => {
9
+ selector.each(n => {
10
+ if (/^:host$/.test(n.value)) {
11
+ const compoundSelectors = n.nodes
12
+ n.replaceWith(selectorParser.className({
13
+ value: 'host-' + id
14
+ }))
15
+ selector.insertAfter(n, compoundSelectors)
16
+ }
17
+ })
18
+ })
19
+ }).process(node.selector).result
20
+ })
21
+ })
@@ -1,7 +1,7 @@
1
- const babylon = require('babylon')
2
- const traverse = require('babel-traverse').default
3
- const t = require('babel-types')
4
- const generate = require('babel-generator').default
1
+ const babylon = require('@babel/parser')
2
+ const traverse = require('@babel/traverse').default
3
+ const t = require('@babel/types')
4
+ const generate = require('@babel/generator').default
5
5
 
6
6
  let names = 'Infinity,undefined,NaN,isFinite,isNaN,' +
7
7
  'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
@@ -1,6 +1,7 @@
1
1
  const JSON5 = require('json5')
2
2
  const he = require('he')
3
3
  const config = require('../config')
4
+ const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID } = require('../staticConfig')
4
5
  const normalize = require('../utils/normalize')
5
6
  const isValidIdentifierStr = require('../utils/is-valid-identifier-str')
6
7
  const isEmptyObject = require('../utils/is-empty-object')
@@ -803,7 +804,7 @@ function parse (template, options) {
803
804
 
804
805
  function genTempRoot () {
805
806
  // 使用临时节点作为root,处理multi root的情况
806
- root = currentParent = getTempNode()
807
+ root = currentParent = getVirtualHostRoot(options, meta)
807
808
  stack.push(root)
808
809
  }
809
810
 
@@ -1876,10 +1877,11 @@ function processWebExternalClassesHack (el, options) {
1876
1877
  function processScoped (el, options) {
1877
1878
  if (options.hasScoped && isRealNode(el)) {
1878
1879
  const moduleId = options.moduleId
1880
+ const rootModuleId = options.isComponent ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
1879
1881
  const staticClass = getAndRemoveAttr(el, 'class').val
1880
1882
  addAttrs(el, [{
1881
1883
  name: 'class',
1882
- value: staticClass ? `${staticClass} ${moduleId}` : moduleId
1884
+ value: `${staticClass || ''} ${moduleId} ${rootModuleId}`
1883
1885
  }])
1884
1886
  }
1885
1887
  }
@@ -1899,41 +1901,67 @@ function processBuiltInComponents (el, meta) {
1899
1901
  }
1900
1902
 
1901
1903
  function processAliStyleClassHack (el, options, root) {
1904
+ let processor
1905
+ // 处理组件标签
1906
+ if (isComponentNode(el, options)) processor = ({ value, typeName }) => [typeName, value]
1907
+ // 处理组件根节点
1908
+ if (options.isComponent && el === root && isRealNode(el)) {
1909
+ processor = ({ name, value, typeName }) => {
1910
+ let sep = name === 'style' ? ';' : ' '
1911
+ value = value ? `{{${typeName}||''}}${sep}${value}` : `{{${typeName}||''}}`
1912
+ return [ name, value ]
1913
+ }
1914
+ }
1915
+ // 非上述两种不处理
1916
+ if (!processor) return
1917
+ // 处理style、class
1902
1918
  ['style', 'class'].forEach((type) => {
1903
1919
  let exp = getAndRemoveAttr(el, type).val
1904
- let sep = type === 'style' ? ';' : ' '
1905
-
1906
- let typeName = 'mpx' + type.replace(/^./, (matched) => {
1907
- return matched.toUpperCase()
1920
+ let typeName = 'mpx' + type.replace(/^./, (matched) => matched.toUpperCase())
1921
+ let [newName, newValue] = processor({
1922
+ name: type,
1923
+ value: exp,
1924
+ typeName
1908
1925
  })
1909
-
1910
- if (options.isComponent && el.parent === root && isRealNode(el)) {
1911
- if (exp !== undefined) {
1912
- exp = `{{${typeName}||''}}` + sep + exp
1913
- } else {
1914
- exp = `{{${typeName}||''}}`
1915
- }
1916
- }
1917
- if (exp !== undefined) {
1918
- if (isComponentNode(el, options)) {
1919
- addAttrs(el, [{
1920
- name: typeName,
1921
- value: exp
1922
- }])
1923
- } else {
1924
- addAttrs(el, [{
1925
- name: type,
1926
- value: exp
1927
- }])
1928
- }
1926
+ if (newValue !== undefined) {
1927
+ addAttrs(el, [{
1928
+ name: newName,
1929
+ value: newValue
1930
+ }])
1929
1931
  }
1930
1932
  })
1931
1933
  }
1934
+ // 有virtualHost情况wx组件注入virtualHost。无virtualHost阿里组件注入root-view。其他跳过。
1935
+ function getVirtualHostRoot (options, meta) {
1936
+ if (options.isComponent) {
1937
+ // 处理组件时
1938
+ if (mode === 'wx' && options.hasVirtualHost) {
1939
+ // wx组件注入virtualHost配置
1940
+ !meta.options && (meta.options = {})
1941
+ meta.options.virtualHost = true
1942
+ }
1943
+ if (mode === 'ali' && !options.hasVirtualHost) {
1944
+ // ali组件根节点实体化
1945
+ let rootView = createASTElement('view', [
1946
+ {
1947
+ name: 'class',
1948
+ value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
1949
+ }
1950
+ ])
1951
+ processElement(rootView, rootView, options, meta)
1952
+ return rootView
1953
+ }
1954
+ }
1955
+ return getTempNode()
1956
+ }
1932
1957
 
1933
1958
  function processShow (el, options, root) {
1934
1959
  let show = getAndRemoveAttr(el, config[mode].directive.show).val
1935
1960
  if (mode === 'swan') show = wrapMustache(show)
1936
- if (options.isComponent && el.parent === root && isRealNode(el)) {
1961
+ let processFlag = el.parent === root
1962
+ // 当ali且未开启virtualHost时,mpxShow打到根节点上
1963
+ if (mode === 'ali' && !options.hasVirtualHost) processFlag = el === root
1964
+ if (options.isComponent && processFlag && isRealNode(el)) {
1937
1965
  if (show !== undefined) {
1938
1966
  show = `{{${parseMustache(show).result}&&mpxShow}}`
1939
1967
  } else {
@@ -60,7 +60,8 @@ module.exports = function (raw) {
60
60
  globalComponents: Object.keys(mpx.usingComponents),
61
61
  // deprecated option
62
62
  globalMpxAttrsFilter: mpx.globalMpxAttrsFilter,
63
- forceProxyEvent: matchCondition(this.resourcePath, mpx.forceProxyEventRules)
63
+ forceProxyEvent: matchCondition(this.resourcePath, mpx.forceProxyEventRules),
64
+ hasVirtualHost: matchCondition(resourcePath, mpx.autoVirtualHostRules)
64
65
  })
65
66
 
66
67
  let ast = parsed.root
@@ -122,6 +123,10 @@ ${e.stack}`)
122
123
  };\n`
123
124
  }
124
125
 
126
+ if (meta.options) {
127
+ globalInjectCode += bindThis(`global.currentInject.injectOptions = ${JSON.stringify(meta.options)};`).code + '\n'
128
+ }
129
+
125
130
  const issuer = this._module.issuer
126
131
  const parser = issuer.parser
127
132
 
@@ -1,6 +1,6 @@
1
- const babylon = require('babylon')
2
- const t = require('babel-types')
3
- const generate = require('babel-generator').default
1
+ const babylon = require('@babel/parser')
2
+ const t = require('@babel/types')
3
+ const generate = require('@babel/generator').default
4
4
  const dash2hump = require('../utils/hump-dash').dash2hump
5
5
 
6
6
  module.exports = function transDynamicClassExpr (expr) {
@@ -39,6 +39,7 @@ module.exports = function (script, options, callback) {
39
39
  const genericsInfo = options.genericsInfo
40
40
  const componentGenerics = options.componentGenerics
41
41
  const forceDisableBuiltInLoader = options.forceDisableBuiltInLoader
42
+ const webRouteMode = options.webRouteMode
42
43
 
43
44
  const emitWarning = (msg) => {
44
45
  loaderContext.emitWarning(
@@ -254,7 +255,8 @@ module.exports = function (script, options, callback) {
254
255
  ${JSON.stringify(tabBarMap)},
255
256
  ${JSON.stringify(componentGenerics)},
256
257
  ${JSON.stringify(genericsInfo)},
257
- getWxsMixin(wxsModules)`
258
+ getWxsMixin(wxsModules),
259
+ ${JSON.stringify(webRouteMode)}`
258
260
 
259
261
  if (ctorType === 'app') {
260
262
  content += `,
@@ -17,6 +17,7 @@ module.exports = function () {
17
17
  const assetsInfo = mpx.assetsInfo
18
18
  const mode = mpx.mode
19
19
  const wxsMap = mpx.wxsMap
20
+ const getOutputPath = mpx.getOutputPath
20
21
  const rootName = mainCompilation._preparedEntrypoints[0].name
21
22
  let { resourcePath, queryObj } = parseRequest(this.resource)
22
23
  const { resourcePath: issuerResourcePath, queryObj: issuerQueryObj } = parseRequest(queryObj.issuerResource || this._module.issuer.resource)
@@ -36,9 +37,9 @@ module.exports = function () {
36
37
  if (wxsModule) {
37
38
  resourcePath = `${resourcePath}~${wxsModule}`
38
39
  }
39
-
40
- const name = path.parse(resourcePath).name + mpx.pathHash(resourcePath)
41
- let filename = path.join(/^\.([^.]+)/.exec(config[mode].wxs.ext)[1], `${name}${config[mode].wxs.ext}`)
40
+ const packageRoot = queryObj.packageRoot || ''
41
+ const ext = config[mode].wxs.ext
42
+ let filename = toPosix(path.join(packageRoot, getOutputPath(resourcePath, ext.slice(1), { ext })))
42
43
 
43
44
  filename = mpx.getPackageInfo({
44
45
  resource: this.resource,
@@ -1,7 +1,7 @@
1
- const babylon = require('babylon')
2
- const traverse = require('babel-traverse').default
3
- const t = require('babel-types')
4
- const generate = require('babel-generator').default
1
+ const babylon = require('@babel/parser')
2
+ const traverse = require('@babel/traverse').default
3
+ const t = require('@babel/types')
4
+ const generate = require('@babel/generator').default
5
5
  const getMainCompilation = require('../utils/get-main-compilation')
6
6
  const parseRequest = require('../utils/parse-request')
7
7
  const isEmptyObject = require('../utils/is-empty-object')
@@ -3,37 +3,37 @@
3
3
  Author Tobias Koppers @sokra
4
4
  Modified by @hiyuki
5
5
  */
6
- var formatCodeFrame = require('babel-code-frame')
7
- var Tokenizer = require('css-selector-tokenizer')
8
- var postcss = require('postcss')
9
- var loaderUtils = require('loader-utils')
10
- var assign = require('object-assign')
11
- var getLocalIdent = require('./getLocalIdent')
6
+ const formatCodeFrame = require('@babel/code-frame')
7
+ const Tokenizer = require('css-selector-tokenizer')
8
+ const postcss = require('postcss')
9
+ const loaderUtils = require('loader-utils')
10
+ const assign = require('object-assign')
11
+ const getLocalIdent = require('./getLocalIdent')
12
12
 
13
- var icssUtils = require('icss-utils')
14
- var localByDefault = require('postcss-modules-local-by-default')
15
- var extractImports = require('postcss-modules-extract-imports')
16
- var modulesScope = require('postcss-modules-scope')
17
- var modulesValues = require('postcss-modules-values')
18
- var valueParser = require('postcss-value-parser')
19
- var isUrlRequest = require('../utils/is-url-request')
13
+ const icssUtils = require('icss-utils')
14
+ const localByDefault = require('postcss-modules-local-by-default')
15
+ const extractImports = require('postcss-modules-extract-imports')
16
+ const modulesScope = require('postcss-modules-scope')
17
+ const modulesValues = require('postcss-modules-values')
18
+ const valueParser = require('postcss-value-parser')
19
+ const isUrlRequest = require('../utils/is-url-request')
20
20
 
21
- var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
21
+ const parserPlugin = postcss.plugin('css-loader-parser', function (options) {
22
22
  return function (css) {
23
- var imports = {}
24
- var exports = {}
25
- var importItems = []
26
- var urlItems = []
23
+ const imports = {}
24
+ let exports = {}
25
+ const importItems = []
26
+ const urlItems = []
27
27
 
28
28
  function replaceImportsInString (str) {
29
29
  if (options.import) {
30
- var tokens = valueParser(str)
30
+ const tokens = valueParser(str)
31
31
  tokens.walk(function (node) {
32
32
  if (node.type !== 'word') {
33
33
  return
34
34
  }
35
- var token = node.value
36
- var importIndex = imports['$' + token]
35
+ const token = node.value
36
+ const importIndex = imports['$' + token]
37
37
  if (typeof importIndex === 'number') {
38
38
  node.value = '___CSS_LOADER_IMPORT___' + importIndex + '___'
39
39
  }
@@ -45,8 +45,8 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
45
45
 
46
46
  if (options.import) {
47
47
  css.walkAtRules(/^import$/i, function (rule) {
48
- var values = Tokenizer.parseValues(rule.params)
49
- var url = values.nodes[0].nodes[0]
48
+ const values = Tokenizer.parseValues(rule.params)
49
+ let url = values.nodes[0].nodes[0]
50
50
  if (url && url.type === 'url') {
51
51
  url = url.url
52
52
  } else if (url && url.type === 'string') {
@@ -56,7 +56,7 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
56
56
  return
57
57
  }
58
58
  values.nodes[0].nodes.shift()
59
- var mediaQuery = Tokenizer.stringifyValues(values)
59
+ const mediaQuery = Tokenizer.stringifyValues(values)
60
60
 
61
61
  if (isUrlRequest(url, options.root)) {
62
62
  url = loaderUtils.urlToRequest(url, options.root)
@@ -70,10 +70,10 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
70
70
  })
71
71
  }
72
72
 
73
- var icss = icssUtils.extractICSS(css)
73
+ const icss = icssUtils.extractICSS(css)
74
74
  exports = icss.icssExports
75
75
  Object.keys(icss.icssImports).forEach(function (key) {
76
- var url = loaderUtils.parseString(key)
76
+ const url = loaderUtils.parseString(key)
77
77
  Object.keys(icss.icssImports[key]).forEach(function (prop) {
78
78
  imports['$' + prop] = importItems.length
79
79
  importItems.push({
@@ -101,7 +101,7 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
101
101
  item.nodes.forEach(processNode)
102
102
  break
103
103
  case 'item':
104
- var importIndex = imports['$' + item.name]
104
+ const importIndex = imports['$' + item.name]
105
105
  if (typeof importIndex === 'number') {
106
106
  item.name = '___CSS_LOADER_IMPORT___' + importIndex + '___'
107
107
  }
@@ -112,7 +112,7 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
112
112
  item.stringType = ''
113
113
  delete item.innerSpacingBefore
114
114
  delete item.innerSpacingAfter
115
- var url = item.url
115
+ const url = item.url
116
116
  item.url = '___CSS_LOADER_URL___' + urlItems.length + '___'
117
117
  urlItems.push({
118
118
  url: url
@@ -123,7 +123,7 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
123
123
  }
124
124
 
125
125
  css.walkDecls(function (decl) {
126
- var values = Tokenizer.parseValues(decl.value)
126
+ const values = Tokenizer.parseValues(decl.value)
127
127
  values.nodes.forEach(function (value) {
128
128
  value.nodes.forEach(processNode)
129
129
  })
@@ -142,17 +142,17 @@ var parserPlugin = postcss.plugin('css-loader-parser', function (options) {
142
142
  })
143
143
 
144
144
  module.exports = function processCss (inputSource, inputMap, options, callback) {
145
- var query = options.query
146
- var root = query.root && query.root.length > 0 ? query.root.replace(/\/$/, '') : query.root
147
- var context = query.context
148
- var localIdentName = query.localIdentName || '[hash:base64]'
149
- var localIdentRegExp = query.localIdentRegExp
150
- var forceMinimize = query.minimize
151
- var minimize = typeof forceMinimize !== 'undefined' ? !!forceMinimize : options.minimize
145
+ const query = options.query
146
+ const root = query.root && query.root.length > 0 ? query.root.replace(/\/$/, '') : query.root
147
+ const context = query.context
148
+ const localIdentName = query.localIdentName || '[hash:base64]'
149
+ const localIdentRegExp = query.localIdentRegExp
150
+ const forceMinimize = query.minimize
151
+ const minimize = typeof forceMinimize !== 'undefined' ? !!forceMinimize : options.minimize
152
152
 
153
- var customGetLocalIdent = query.getLocalIdent || getLocalIdent
153
+ const customGetLocalIdent = query.getLocalIdent || getLocalIdent
154
154
 
155
- var parserOptions = {
155
+ const parserOptions = {
156
156
  root: root,
157
157
  mode: options.mode,
158
158
  url: query.url !== false,
@@ -160,7 +160,7 @@ module.exports = function processCss (inputSource, inputMap, options, callback)
160
160
  resolve: options.resolve
161
161
  }
162
162
 
163
- var pipeline = postcss([
163
+ const pipeline = postcss([
164
164
  modulesValues,
165
165
  localByDefault({
166
166
  mode: options.mode,
@@ -192,8 +192,8 @@ module.exports = function processCss (inputSource, inputMap, options, callback)
192
192
  ])
193
193
 
194
194
  if (minimize) {
195
- var cssnano = require('cssnano')
196
- var minimizeOptions = assign({}, query.minimize);
195
+ const cssnano = require('cssnano')
196
+ const minimizeOptions = assign({}, query.minimize);
197
197
  ['zindex', 'normalizeUrl', 'discardUnused', 'mergeIdents', 'reduceIdents', 'autoprefixer', 'svgo'].forEach(function (name) {
198
198
  if (typeof minimizeOptions[name] === 'undefined') {
199
199
  minimizeOptions[name] = false
@@ -226,7 +226,7 @@ module.exports = function processCss (inputSource, inputMap, options, callback)
226
226
  })
227
227
  }).catch(function (err) {
228
228
  if (err.name === 'CssSyntaxError') {
229
- var wrappedError = new CSSLoaderError(
229
+ const wrappedError = new CSSLoaderError(
230
230
  'Syntax Error',
231
231
  err.reason,
232
232
  err.line != null && err.column != null
@@ -242,7 +242,7 @@ module.exports = function processCss (inputSource, inputMap, options, callback)
242
242
  }
243
243
 
244
244
  function formatMessage (message, loc, source) {
245
- var formatted = message
245
+ let formatted = message
246
246
  if (loc) {
247
247
  formatted = formatted +
248
248
  ' (' + loc.line + ':' + loc.column + ')'
@@ -260,7 +260,7 @@ function CSSLoaderError (name, message, loc, source, error) {
260
260
  this.name = name
261
261
  this.error = error
262
262
  this.message = formatMessage(message, loc, source)
263
- this.hideStack = true
263
+ this.message = formatMessage(message, loc, source)
264
264
  }
265
265
 
266
266
  CSSLoaderError.prototype = Object.create(Error.prototype)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.6.102",
3
+ "version": "2.6.107",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -15,6 +15,11 @@
15
15
  "lib"
16
16
  ],
17
17
  "dependencies": {
18
+ "@babel/code-frame": "^7.16.0",
19
+ "@babel/generator": "^7.16.0",
20
+ "@babel/parser": "^7.16.2",
21
+ "@babel/traverse": "^7.16.0",
22
+ "@babel/types": "^7.16.0",
18
23
  "@better-scroll/core": "^2.2.1",
19
24
  "@better-scroll/movable": "^2.2.1",
20
25
  "@better-scroll/observe-dom": "^2.2.1",
@@ -24,11 +29,6 @@
24
29
  "@better-scroll/zoom": "^2.2.1",
25
30
  "acorn-walk": "^7.2.0",
26
31
  "async": "^2.6.0",
27
- "babel-code-frame": "^6.26.0",
28
- "babel-generator": "^6.26.1",
29
- "babel-traverse": "^6.26.0",
30
- "babel-types": "^6.26.0",
31
- "babylon": "^6.18.0",
32
32
  "consolidate": "^0.15.1",
33
33
  "css": "^2.2.1",
34
34
  "css-selector-tokenizer": "^0.7.0",
@@ -81,5 +81,5 @@
81
81
  "@types/babel-traverse": "^6.25.4",
82
82
  "@types/babel-types": "^7.0.4"
83
83
  },
84
- "gitHead": "377633613e39511e147269e988e3459f50421de5"
84
+ "gitHead": "c5821595c58c2908d56de41e68f1462b949bf646"
85
85
  }