@mpxjs/webpack-plugin 2.7.0-beta.4 → 2.7.0-beta.8

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/CommonJsVariableDependency.js +1 -3
  2. package/lib/dependencies/DynamicEntryDependency.js +2 -1
  3. package/lib/dependencies/{RecordStaticResourceDependency.js → RecordResourceMapDependency.js} +12 -7
  4. package/lib/dependencies/ResolveDependency.js +8 -7
  5. package/lib/extractor.js +4 -4
  6. package/lib/file-loader.js +2 -2
  7. package/lib/index.js +154 -118
  8. package/lib/json-compiler/helper.js +14 -11
  9. package/lib/json-compiler/index.js +19 -13
  10. package/lib/loader.js +27 -36
  11. package/lib/platform/json/wx/index.js +7 -2
  12. package/lib/platform/template/wx/component-config/button.js +3 -3
  13. package/lib/platform/template/wx/component-config/navigator.js +1 -1
  14. package/lib/runtime/base.styl +5 -0
  15. package/lib/runtime/components/web/getInnerListeners.js +51 -45
  16. package/lib/runtime/components/web/mpx-keep-alive.vue +4 -1
  17. package/lib/runtime/components/web/mpx-tab-bar-container.vue +2 -2
  18. package/lib/runtime/optionProcessor.js +5 -20
  19. package/lib/runtime/stringify.wxs +3 -3
  20. package/lib/style-compiler/index.js +4 -5
  21. package/lib/template-compiler/bind-this.js +4 -4
  22. package/lib/template-compiler/compiler.js +100 -36
  23. package/lib/template-compiler/index.js +3 -6
  24. package/lib/template-compiler/trans-dynamic-class-expr.js +3 -3
  25. package/lib/utils/const.js +3 -1
  26. package/lib/web/processJSON.js +105 -113
  27. package/lib/web/processScript.js +30 -24
  28. package/lib/web/processTemplate.js +56 -37
  29. package/lib/wxs/loader.js +24 -27
  30. package/lib/wxs/pre-loader.js +4 -4
  31. package/lib/wxss/processCss.js +44 -44
  32. package/package.json +8 -8
  33. package/lib/built-in-loader.js +0 -45
  34. package/lib/record-loader.js +0 -11
@@ -6,13 +6,15 @@ const parseRequest = require('../utils/parse-request')
6
6
  const loaderUtils = require('loader-utils')
7
7
  const resolve = require('../utils/resolve')
8
8
 
9
- module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
9
+ module.exports = function createJSONHelper ({ loaderContext, emitWarning, customGetDynamicEntry }) {
10
10
  const mpx = loaderContext.getMpx()
11
11
  const resolveMode = mpx.resolveMode
12
12
  const externals = mpx.externals
13
13
  const root = mpx.projectRoot
14
14
  const publicPath = loaderContext._compilation.outputOptions.publicPath || ''
15
15
  const pathHash = mpx.pathHash
16
+ const getOutputPath = mpx.getOutputPath
17
+ const mode = mpx.mode
16
18
 
17
19
  const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
18
20
  const urlToRequest = r => loaderUtils.urlToRequest(r)
@@ -22,6 +24,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
22
24
  let dynamicEntryCount = 0
23
25
 
24
26
  const getDynamicEntry = (resource, type, outputPath = '', packageRoot = '', relativePath = '') => {
27
+ if (typeof customGetDynamicEntry === 'function') return customGetDynamicEntry(resource, type, outputPath, packageRoot, relativePath)
25
28
  const key = `mpx_dynamic_entry_${dynamicEntryCount++}`
26
29
  const value = `__mpx_dynamic_entry__( ${JSON.stringify(resource)},${JSON.stringify(type)},${JSON.stringify(outputPath)},${JSON.stringify(packageRoot)},${JSON.stringify(relativePath)})`
27
30
  dynamicEntryMap.set(key, value)
@@ -43,7 +46,9 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
43
46
 
44
47
  resolve(context, component, loaderContext, (err, resource, info) => {
45
48
  if (err) return callback(err)
46
- const resourcePath = parseRequest(resource).resourcePath
49
+ const { resourcePath, queryObj } = parseRequest(resource)
50
+ // 目前只有微信支持分包异步化
51
+ if (queryObj.root && mode === 'wx') tarRoot = queryObj.root
47
52
  const parsed = path.parse(resourcePath)
48
53
  const ext = parsed.ext
49
54
  const resourceName = path.join(parsed.dir, parsed.name)
@@ -64,8 +69,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
64
69
  let relative = path.relative(root, resourceName)
65
70
  outputPath = path.join('components', name + pathHash(root), relative)
66
71
  } else {
67
- let componentName = parsed.name
68
- outputPath = path.join('components', componentName + pathHash(resourcePath), componentName)
72
+ outputPath = getOutputPath(resourcePath, 'component')
69
73
  }
70
74
  }
71
75
  if (ext === '.js') {
@@ -77,11 +81,6 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
77
81
  })
78
82
  }
79
83
 
80
- const getPageName = (resourcePath, ext) => {
81
- const baseName = path.basename(resourcePath, ext)
82
- return path.join('pages', baseName + pathHash(resourcePath), baseName)
83
- }
84
-
85
84
  const processPage = (page, context, tarRoot = '', callback) => {
86
85
  let aliasPath = ''
87
86
  if (typeof page !== 'string') {
@@ -103,7 +102,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
103
102
  const relative = path.relative(context, resourcePath)
104
103
  if (/^\./.test(relative)) {
105
104
  // 如果当前page不存在于context中,对其进行重命名
106
- outputPath = getPageName(resourcePath, ext)
105
+ outputPath = getOutputPath(resourcePath, 'page')
107
106
  emitWarning(`Current page [${resourcePath}] is not in current pages directory [${context}], the page path will be replaced with [${outputPath}], use ?resolve to get the page path and navigate to it!`)
108
107
  } else {
109
108
  outputPath = /^(.*?)(\.[^.]*)?$/.exec(relative)[1]
@@ -113,7 +112,11 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
113
112
  resource = `!!${nativeLoaderPath}!${resource}`
114
113
  }
115
114
  const entry = getDynamicEntry(resource, 'page', outputPath, tarRoot, publicPath + tarRoot)
116
- callback(null, entry, { isFirst })
115
+ const key = [resourcePath, outputPath, tarRoot].join('|')
116
+ callback(null, entry, {
117
+ isFirst,
118
+ key
119
+ })
117
120
  })
118
121
  }
119
122
 
@@ -216,20 +216,15 @@ module.exports = function (content) {
216
216
  // app.json
217
217
  const localPages = []
218
218
  const subPackagesCfg = {}
219
- // 添加首页标识
220
- if (json.pages && json.pages[0]) {
221
- if (typeof json.pages[0] !== 'string') {
222
- json.pages[0].src = addQuery(json.pages[0].src, { isFirst: true })
223
- } else {
224
- json.pages[0] = addQuery(json.pages[0], { isFirst: true })
225
- }
226
- }
219
+ const pageKeySet = new Set()
227
220
 
228
221
  const processPages = (pages, context, tarRoot = '', callback) => {
229
222
  if (pages) {
230
223
  async.each(pages, (page, callback) => {
231
- processPage(page, context, tarRoot, (err, entry, { isFirst } = {}) => {
224
+ processPage(page, context, tarRoot, (err, entry, { isFirst, key } = {}) => {
232
225
  if (err) return callback(err === RESOLVE_IGNORED_ERR ? null : err)
226
+ if (pageKeySet.has(key)) return callback()
227
+ pageKeySet.add(key)
233
228
  if (tarRoot && subPackagesCfg) {
234
229
  subPackagesCfg[tarRoot].pages.push(entry)
235
230
  } else {
@@ -467,7 +462,10 @@ module.exports = function (content) {
467
462
  const relativePath = useRelativePath ? publicPath + tarRoot : ''
468
463
  async.eachOf(plugin.genericsImplementation, (genericComponents, name, callback) => {
469
464
  async.eachOf(genericComponents, (genericComponentPath, name, callback) => {
470
- processComponent(genericComponentPath, context, { tarRoot, relativePath }, (err, entry) => {
465
+ processComponent(genericComponentPath, context, {
466
+ tarRoot,
467
+ relativePath
468
+ }, (err, entry) => {
471
469
  if (err === RESOLVE_IGNORED_ERR) {
472
470
  delete genericComponents[name]
473
471
  return callback()
@@ -508,14 +506,22 @@ module.exports = function (content) {
508
506
 
509
507
  async.parallel([
510
508
  (callback) => {
511
- processPlugins(json.plugins, this.context, '', callback)
512
- },
513
- (callback) => {
509
+ // 添加首页标识
510
+ if (json.pages && json.pages[0]) {
511
+ if (typeof json.pages[0] !== 'string') {
512
+ json.pages[0].src = addQuery(json.pages[0].src, { isFirst: true })
513
+ } else {
514
+ json.pages[0] = addQuery(json.pages[0], { isFirst: true })
515
+ }
516
+ }
514
517
  processPages(json.pages, this.context, '', callback)
515
518
  },
516
519
  (callback) => {
517
520
  processComponents(json.usingComponents, this.context, callback)
518
521
  },
522
+ (callback) => {
523
+ processPlugins(json.plugins, this.context, '', callback)
524
+ },
519
525
  (callback) => {
520
526
  processWorkers(json.workers, this.context, callback)
521
527
  },
package/lib/loader.js CHANGED
@@ -15,6 +15,7 @@ const getJSONContent = require('./utils/get-json-content')
15
15
  const normalize = require('./utils/normalize')
16
16
  const getEntryName = require('./utils/get-entry-name')
17
17
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
18
+ const { MPX_APP_MODULE_ID } = require('./utils/const')
18
19
 
19
20
  module.exports = function (content) {
20
21
  this.cacheable()
@@ -27,11 +28,8 @@ module.exports = function (content) {
27
28
  const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
28
29
  const pagesMap = mpx.pagesMap
29
30
  const componentsMap = mpx.componentsMap[packageName]
30
- const resolveMode = mpx.resolveMode
31
- const projectRoot = mpx.projectRoot
32
31
  const mode = mpx.mode
33
32
  const env = mpx.env
34
- const defs = mpx.defs
35
33
  const i18n = mpx.i18n
36
34
  const globalSrcMode = mpx.srcMode
37
35
  const localSrcMode = queryObj.mode
@@ -39,10 +37,10 @@ module.exports = function (content) {
39
37
  const vueContentCache = mpx.vueContentCache
40
38
  const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
41
39
 
42
- // 支持资源query传入pagecomponent支持页面/组件单独编译
43
- if ((queryObj.component && !componentsMap[resourcePath]) || (queryObj.page && !pagesMap[resourcePath])) {
40
+ // 支持资源query传入isPageisComponent支持页面/组件单独编译
41
+ if ((queryObj.isComponent && !componentsMap[resourcePath]) || (queryObj.isPage && !pagesMap[resourcePath])) {
44
42
  const entryName = getEntryName(this)
45
- if (queryObj.component) {
43
+ if (queryObj.isComponent) {
46
44
  componentsMap[resourcePath] = entryName || 'noEntryComponent'
47
45
  } else {
48
46
  pagesMap[resourcePath] = entryName || 'noEntryPage'
@@ -58,18 +56,11 @@ module.exports = function (content) {
58
56
  ctorType = 'component'
59
57
  }
60
58
 
61
- if (ctorType === 'app') {
62
- const appName = getEntryName(this)
63
- this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
64
- }
65
-
66
59
  const loaderContext = this
67
60
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
68
61
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
69
-
70
62
  const filePath = resourcePath
71
-
72
- const moduleId = 'm' + mpx.pathHash(filePath)
63
+ const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
73
64
 
74
65
  const parts = parseComponent(content, {
75
66
  filePath,
@@ -120,8 +111,8 @@ module.exports = function (content) {
120
111
 
121
112
  // 处理mode为web时输出vue格式文件
122
113
  if (mode === 'web') {
123
- if (ctorType === 'app' && !queryObj.app) {
124
- const request = addQuery(this.resource, { app: true })
114
+ if (ctorType === 'app' && !queryObj.isApp) {
115
+ const request = addQuery(this.resource, { isApp: true })
125
116
  output += `
126
117
  import App from ${stringifyRequest(request)}
127
118
  import Vue from 'vue'
@@ -142,20 +133,15 @@ module.exports = function (content) {
142
133
  async.parallel([
143
134
  (callback) => {
144
135
  processTemplate(parts.template, {
136
+ loaderContext,
145
137
  hasScoped,
146
138
  hasComment,
147
139
  isNative,
148
- mode,
149
140
  srcMode,
150
- defs,
151
- loaderContext,
152
141
  moduleId,
153
142
  ctorType,
154
143
  usingComponents,
155
- componentGenerics,
156
- decodeHTMLText: mpx.decodeHTMLText,
157
- externalClasses: mpx.externalClasses,
158
- checkUsingComponents: mpx.checkUsingComponents
144
+ componentGenerics
159
145
  }, callback)
160
146
  },
161
147
  (callback) => {
@@ -167,15 +153,9 @@ module.exports = function (content) {
167
153
  },
168
154
  (callback) => {
169
155
  processJSON(parts.json, {
170
- mode,
171
- env,
172
- resolveMode,
173
156
  loaderContext,
174
157
  pagesMap,
175
- pagesEntryMap: mpx.pagesEntryMap,
176
- pathHash: mpx.pathHash,
177
- componentsMap,
178
- projectRoot
158
+ componentsMap
179
159
  }, callback)
180
160
  }
181
161
  ], (err, res) => {
@@ -191,23 +171,20 @@ module.exports = function (content) {
191
171
  }
192
172
 
193
173
  processScript(parts.script, {
174
+ loaderContext,
194
175
  ctorType,
195
176
  srcMode,
196
- loaderContext,
197
177
  isProduction,
198
- i18n,
199
178
  componentGenerics,
200
- projectRoot,
201
179
  jsonConfig: jsonRes.jsonObj,
202
- componentId: queryObj.componentId || '',
180
+ outputPath: queryObj.outputPath || '',
203
181
  tabBarMap: jsonRes.tabBarMap,
204
182
  tabBarStr: jsonRes.tabBarStr,
205
183
  builtInComponentsMap: templateRes.builtInComponentsMap,
206
184
  genericsInfo: templateRes.genericsInfo,
207
185
  wxsModuleMap: templateRes.wxsModuleMap,
208
186
  localComponentsMap: jsonRes.localComponentsMap,
209
- localPagesMap: jsonRes.localPagesMap,
210
- forceDisableBuiltInLoader: mpx.forceDisableBuiltInLoader
187
+ localPagesMap: jsonRes.localPagesMap
211
188
  }, callback)
212
189
  }
213
190
  ], (err, scriptRes) => {
@@ -218,6 +195,19 @@ module.exports = function (content) {
218
195
  })
219
196
  }
220
197
 
198
+ const moduleGraph = this._compilation.moduleGraph
199
+
200
+ const issuer = moduleGraph.getIssuer(this._module)
201
+
202
+ if (issuer) {
203
+ return callback(new Error(`Current ${ctorType} [${this.resourcePath}] is issued by [${issuer.resource}], which is not allowed!`))
204
+ }
205
+
206
+ if (ctorType === 'app') {
207
+ const appName = getEntryName(this)
208
+ this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
209
+ }
210
+
221
211
  const {
222
212
  getRequire
223
213
  } = createHelpers(loaderContext)
@@ -252,6 +242,7 @@ module.exports = function (content) {
252
242
  output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
253
243
  return match.toLowerCase()
254
244
  }))}\n`
245
+ output += `global.currentResourceType = '${ctorType}'\n`
255
246
 
256
247
  // template
257
248
  output += '/* template */\n'
@@ -73,7 +73,12 @@ module.exports = function getSpec ({ warn, error }) {
73
73
  swan: deletePath()
74
74
  },
75
75
  {
76
- test: 'onReachBottomDistance|disableScroll',
76
+ test: 'onReachBottomDistance',
77
+ qq: deletePath(),
78
+ jd: deletePath()
79
+ },
80
+ {
81
+ test: 'disableScroll',
77
82
  ali: deletePath(),
78
83
  qq: deletePath(),
79
84
  jd: deletePath()
@@ -84,7 +89,7 @@ module.exports = function getSpec ({ warn, error }) {
84
89
  swan: deletePath()
85
90
  },
86
91
  {
87
- test: 'navigationBarTextStyle|navigationStyle|backgroundColor|backgroundTextStyle',
92
+ test: 'navigationBarTextStyle|navigationStyle|backgroundTextStyle',
88
93
  ali: deletePath()
89
94
  },
90
95
  {
@@ -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
  }
@@ -44,7 +44,7 @@ module.exports = function ({ print }) {
44
44
  // 如果是个变量,报warning~
45
45
  aliPropLog(attr)
46
46
  } else {
47
- let supportedList = ['navigate', 'redirect', 'switchTab', 'navigateBack', 'reLaunch']
47
+ let supportedList = ['navigate', 'redirect', 'switchTab', 'navigateBack', 'reLaunch', 'exit']
48
48
  if (supportedList.indexOf(attr.value) === -1) {
49
49
  aliValueLogError(attr)
50
50
  }
@@ -120,3 +120,8 @@ html, body, .app {
120
120
  font-family "weui"
121
121
  src url('data:application/octet-stream;base64,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') format('truetype')
122
122
  }
123
+
124
+ .mpx-root-view {
125
+ display: inline
126
+ line-height: normal
127
+ }
@@ -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: {
@@ -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,' +