@mpxjs/webpack-plugin 2.7.0-beta.5 → 2.7.0-beta.6

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.
@@ -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: {
@@ -4,7 +4,7 @@ export default function processOption (
4
4
  option,
5
5
  ctorType,
6
6
  firstPage,
7
- componentId,
7
+ outputPath,
8
8
  pageConfig,
9
9
  pagesMap,
10
10
  componentsMap,
@@ -25,23 +25,6 @@ export default function processOption (
25
25
  }
26
26
  }
27
27
 
28
- // 注册v-ex-classes自定义指令处理externalClasses
29
- Vue.directive('ex-classes', (el, binding, vnode) => {
30
- const context = vnode.context
31
- if (context) {
32
- const externalClasses = context.$options.externalClasses || []
33
- const classList = el.classList
34
- binding.value.forEach((className) => {
35
- const actualExternalClassNames = context.$attrs[className]
36
- if (externalClasses.indexOf(className) !== -1 && actualExternalClassNames) {
37
- classList.remove(className)
38
- actualExternalClassNames.split(/\s+/).forEach((actualExternalClassName) => {
39
- if (actualExternalClassName) classList.add(actualExternalClassName)
40
- })
41
- }
42
- })
43
- }
44
- })
45
28
  Vue.directive('animation', (el, binding) => {
46
29
  const newActions = binding && binding.value && binding.value.actions
47
30
  if (el.actions === newActions) {
@@ -121,7 +104,9 @@ export default function processOption (
121
104
  redirect: '/' + firstPage
122
105
  })
123
106
  }
107
+ const webRouteConfig = global.__mpx.config.webRouteConfig
124
108
  global.__mpxRouter = option.router = new VueRouter({
109
+ ...webRouteConfig,
125
110
  routes: routes
126
111
  })
127
112
  global.__mpxRouter.stack = []
@@ -354,8 +339,8 @@ registered in parent context!`)
354
339
  option.mixins = [mixin]
355
340
  }
356
341
 
357
- if (componentId) {
358
- option.componentPath = '/' + componentId
342
+ if (outputPath) {
343
+ option.componentPath = '/' + outputPath
359
344
  }
360
345
 
361
346
  return option
@@ -93,7 +93,7 @@ function isDef (v) {
93
93
  return v !== undefined && v !== null
94
94
  }
95
95
 
96
- function stringifyClass (value) {
96
+ function stringifyDynamicClass (value) {
97
97
  if (!value) return ''
98
98
  if (likeArray(value)) {
99
99
  return stringifyArray(value)
@@ -111,7 +111,7 @@ function stringifyArray (value) {
111
111
  var res = ''
112
112
  var stringified
113
113
  for (var i = 0; i < value.length; i++) {
114
- if (isDef(stringified = stringifyClass(value[i])) && stringified !== '') {
114
+ if (isDef(stringified = stringifyDynamicClass(value[i])) && stringified !== '') {
115
115
  if (res) res += ' '
116
116
  res += stringified
117
117
  }
@@ -207,7 +207,7 @@ module.exports = {
207
207
  if (typeof staticClass !== 'string') {
208
208
  return console.log('Template attr class must be a string!')
209
209
  }
210
- return concat(staticClass, stringifyClass(dynamicClass))
210
+ return concat(staticClass, stringifyDynamicClass(dynamicClass))
211
211
  },
212
212
  stringifyStyle: function (staticStyle, dynamicStyle) {
213
213
  var normalizedDynamicStyle = normalizeDynamicStyle(dynamicStyle)
@@ -1,5 +1,6 @@
1
1
  const postcss = require('postcss')
2
2
  const loadPostcssConfig = require('./load-postcss-config')
3
+ const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID } = require('../utils/const')
3
4
  const trim = require('./plugins/trim')
4
5
  const rpx = require('./plugins/rpx')
5
6
  const vw = require('./plugins/vw')
@@ -15,12 +16,10 @@ module.exports = function (css, map) {
15
16
  const { resourcePath, queryObj } = parseRequest(this.resource)
16
17
  const id = queryObj.moduleId || queryObj.mid
17
18
  const mpx = this.getMpx()
19
+ const appInfo = mpx.appInfo
18
20
  const defs = mpx.defs
19
21
  const mode = mpx.mode
20
- const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
21
- const componentsMap = mpx.componentsMap[packageName]
22
- const pagesMap = mpx.pagesMap
23
- const isApp = !(pagesMap[resourcePath] || componentsMap[resourcePath])
22
+ const isApp = resourcePath === appInfo.resourcePath
24
23
  const transRpxRulesRaw = mpx.transRpxRules
25
24
  const transRpxRules = transRpxRulesRaw ? (Array.isArray(transRpxRulesRaw) ? transRpxRulesRaw : [transRpxRulesRaw]) : []
26
25
 
@@ -85,7 +84,7 @@ module.exports = function (css, map) {
85
84
  .then(result => {
86
85
  // ali环境添加全局样式抹平root差异
87
86
  if (mode === 'ali' && isApp) {
88
- result.css += '\n.mpx-root-view { display: inline; line-height: normal; }\n'
87
+ result.css += `\n.${MPX_ROOT_VIEW} { display: initial }\n.${MPX_APP_MODULE_ID} { line-height: normal }`
89
88
  }
90
89
  if (result.messages) {
91
90
  result.messages.forEach(({ type, file }) => {
@@ -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('../utils/const')
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')
@@ -1710,31 +1711,71 @@ function processAliExternalClassesHack (el, options) {
1710
1711
  }
1711
1712
  }
1712
1713
 
1714
+ // externalClasses只能模拟静态传递
1713
1715
  function processWebExternalClassesHack (el, options) {
1714
- // todo 处理scoped的情况, 处理组件多层传递externalClass的情况,通过externalClass属性传递实际类名及scopeId信息,可以使用特殊的类名形式代表scopeId,如#idstring
1715
- let staticClass = el.attrsMap['class']
1716
- let dynamicClass = el.attrsMap[':class']
1717
- if (staticClass || dynamicClass) {
1718
- const externalClasses = []
1716
+ const staticClass = getAndRemoveAttr(el, 'class').val
1717
+ if (staticClass) {
1718
+ const classNames = staticClass.split(/\s+/)
1719
+ const replacements = []
1719
1720
  options.externalClasses.forEach((className) => {
1720
- const reg = new RegExp('\\b' + className + '\\b')
1721
- if (reg.test(staticClass) || reg.test(dynamicClass)) {
1722
- externalClasses.push(className)
1721
+ const index = classNames.indexOf(className)
1722
+ if (index > -1) {
1723
+ replacements.push(`$attrs[${JSON.stringify(className)}]`)
1724
+ classNames.splice(index, 1)
1723
1725
  }
1724
1726
  })
1725
- if (externalClasses.length) {
1727
+
1728
+ if (classNames.length) {
1729
+ addAttrs(el, [{
1730
+ name: 'class',
1731
+ value: classNames.join(' ')
1732
+ }])
1733
+ }
1734
+
1735
+ if (replacements.length) {
1736
+ const dynamicClass = getAndRemoveAttr(el, ':class').val
1737
+ if (dynamicClass) replacements.push(dynamicClass)
1738
+
1726
1739
  addAttrs(el, [{
1727
- name: 'v-ex-classes',
1728
- value: JSON.stringify(externalClasses)
1740
+ name: ':class',
1741
+ value: `[${replacements.join(',')}]`
1729
1742
  }])
1730
1743
  }
1731
1744
  }
1745
+
1746
+ // 处理externalClasses多层透传
1747
+ const isComponent = isComponentNode(el, options)
1748
+ if (isComponent) {
1749
+ options.externalClasses.forEach((classLikeAttrName) => {
1750
+ let classLikeAttrValue = getAndRemoveAttr(el, classLikeAttrName).val
1751
+ if (classLikeAttrValue) {
1752
+ const classNames = classLikeAttrValue.split(/\s+/)
1753
+ const replacements = []
1754
+ options.externalClasses.forEach((className) => {
1755
+ const index = classNames.indexOf(className)
1756
+ if (index > -1) {
1757
+ replacements.push(`$attrs[${JSON.stringify(className)}]`)
1758
+ classNames.splice(index, 1)
1759
+ }
1760
+ })
1761
+
1762
+ if (classNames.length) {
1763
+ replacements.unshift(JSON.stringify(classNames.join(' ')))
1764
+ }
1765
+
1766
+ addAttrs(el, [{
1767
+ name: ':' + classLikeAttrName,
1768
+ value: `[${replacements.join(',')}].join(' ')`
1769
+ }])
1770
+ }
1771
+ })
1772
+ }
1732
1773
  }
1733
1774
 
1734
1775
  function processScoped (el, options) {
1735
1776
  if (options.hasScoped && isRealNode(el)) {
1736
1777
  const moduleId = options.moduleId
1737
- const rootModuleId = options.isComponent ? '' : 'mpx-app-scope' // 处理app全局样式对页面的影响
1778
+ const rootModuleId = options.isComponent ? '' : MPX_APP_MODULE_ID // 处理app全局样式对页面的影响
1738
1779
  const staticClass = getAndRemoveAttr(el, 'class').val
1739
1780
  addAttrs(el, [{
1740
1781
  name: 'class',
@@ -1757,17 +1798,33 @@ function processBuiltInComponents (el, meta) {
1757
1798
  }
1758
1799
  }
1759
1800
 
1760
- function processAliStyleClassHack (el, options) {
1761
- if (!isComponentNode(el, options)) return
1801
+ function processAliStyleClassHack (el, options, root) {
1802
+ let processor
1803
+ // 处理组件标签
1804
+ if (isComponentNode(el, options)) processor = ({ value, typeName }) => [typeName, value]
1805
+ // 处理组件根节点
1806
+ if (options.isComponent && el === root && isRealNode(el)) {
1807
+ processor = ({ name, value, typeName }) => {
1808
+ let sep = name === 'style' ? ';' : ' '
1809
+ value = value ? `{{${typeName}||''}}${sep}${value}` : `{{${typeName}||''}}`
1810
+ return [name, value]
1811
+ }
1812
+ }
1813
+ // 非上述两种不处理
1814
+ if (!processor) return
1815
+ // 处理style、class
1762
1816
  ['style', 'class'].forEach((type) => {
1763
1817
  let exp = getAndRemoveAttr(el, type).val
1764
- let typeName = 'mpx' + type.replace(/^./, (matched) => {
1765
- return matched.toUpperCase()
1818
+ let typeName = 'mpx' + type.replace(/^./, (matched) => matched.toUpperCase())
1819
+ let [newName, newValue] = processor({
1820
+ name: type,
1821
+ value: exp,
1822
+ typeName
1766
1823
  })
1767
- if (exp !== undefined) {
1824
+ if (newValue !== undefined) {
1768
1825
  addAttrs(el, [{
1769
- name: typeName,
1770
- value: exp
1826
+ name: newName,
1827
+ value: newValue
1771
1828
  }])
1772
1829
  }
1773
1830
  })
@@ -1775,21 +1832,24 @@ function processAliStyleClassHack (el, options) {
1775
1832
 
1776
1833
  // 有virtualHost情况wx组件注入virtualHost。无virtualHost阿里组件注入root-view。其他跳过。
1777
1834
  function getVirtualHostRoot (options, meta) {
1778
- if (mode === 'wx' && options.hasVirtualHost && options.isComponent) {
1779
- !meta.options && (meta.options = {})
1780
- meta.options.virtualHost = true
1781
- }
1782
- if (mode === 'ali' && !options.hasVirtualHost && options.isComponent) {
1783
- return createASTElement('view', [
1784
- {
1785
- name: 'class',
1786
- value: `mpx-root-view host-${options.moduleId} ${options.hasScoped ? options.moduleId : ''} {{mpxClass||''}}`
1787
- },
1788
- {
1789
- name: 'style',
1790
- value: `{{mpxStyle||''}}`
1791
- }
1792
- ])
1835
+ if (options.isComponent) {
1836
+ // 处理组件时
1837
+ if (mode === 'wx' && options.hasVirtualHost) {
1838
+ // wx组件注入virtualHost配置
1839
+ !meta.options && (meta.options = {})
1840
+ meta.options.virtualHost = true
1841
+ }
1842
+ if (mode === 'ali' && !options.hasVirtualHost) {
1843
+ // ali组件根节点实体化
1844
+ let rootView = createASTElement('view', [
1845
+ {
1846
+ name: 'class',
1847
+ value: `${MPX_ROOT_VIEW} host-${options.moduleId}`
1848
+ }
1849
+ ])
1850
+ processElement(rootView, rootView, options, meta)
1851
+ return rootView
1852
+ }
1793
1853
  }
1794
1854
  return getTempNode()
1795
1855
  }
@@ -1797,7 +1857,10 @@ function getVirtualHostRoot (options, meta) {
1797
1857
  function processShow (el, options, root) {
1798
1858
  let show = getAndRemoveAttr(el, config[mode].directive.show).val
1799
1859
  if (mode === 'swan') show = wrapMustache(show)
1800
- if (options.isComponent && el.parent === root && isRealNode(el)) {
1860
+ let processFlag = el.parent === root
1861
+ // 当ali且未开启virtualHost时,mpxShow打到根节点上
1862
+ if (mode === 'ali' && !options.hasVirtualHost) processFlag = el === root
1863
+ if (options.isComponent && processFlag && isRealNode(el)) {
1801
1864
  if (show !== undefined) {
1802
1865
  show = `{{${parseMustache(show).result}&&mpxShow}}`
1803
1866
  } else {
@@ -2279,5 +2342,6 @@ module.exports = {
2279
2342
  makeAttrsMap,
2280
2343
  stringifyAttr,
2281
2344
  parseMustache,
2282
- stringifyWithResolveComputed
2345
+ stringifyWithResolveComputed,
2346
+ addAttrs
2283
2347
  }
@@ -38,7 +38,7 @@ module.exports = function (raw) {
38
38
  )
39
39
  }
40
40
 
41
- const parsed = compiler.parse(raw, {
41
+ const { root: ast, meta } = compiler.parse(raw, {
42
42
  warn,
43
43
  error,
44
44
  usingComponents,
@@ -57,13 +57,10 @@ module.exports = function (raw) {
57
57
  i18n,
58
58
  checkUsingComponents: mpx.checkUsingComponents,
59
59
  globalComponents: Object.keys(mpx.usingComponents),
60
- forceProxyEvent: matchCondition(this.resourcePath, mpx.forceProxyEventRules),
61
- hasVirtualHost: matchCondition(this.resourcePath, mpx.autoVirtualHostRules)
60
+ forceProxyEvent: matchCondition(resourcePath, mpx.forceProxyEventRules),
61
+ hasVirtualHost: matchCondition(resourcePath, mpx.autoVirtualHostRules)
62
62
  })
63
63
 
64
- let ast = parsed.root
65
- let meta = parsed.meta
66
-
67
64
  if (meta.wxsContentMap) {
68
65
  for (let module in meta.wxsContentMap) {
69
66
  wxsContentMap[`${resourcePath}~${module}`] = meta.wxsContentMap[module]
@@ -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) {
@@ -3,5 +3,7 @@ module.exports = {
3
3
  MPX_DISABLE_EXTRACTOR_CACHE: 'mpx_disable_extractor_cache',
4
4
  DEFAULT_RESULT_SOURCE: '',
5
5
  RESOLVE_IGNORED_ERR: new Error('Resolve ignored!'),
6
- JSON_JS_EXT: '.json.js'
6
+ JSON_JS_EXT: '.json.js',
7
+ MPX_ROOT_VIEW: 'mpx-root-view', // 根节点类名
8
+ MPX_APP_MODULE_ID: 'mpx-app-scope' // app文件moduleId
7
9
  }