@mpxjs/webpack-plugin 2.7.17 → 2.7.20

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.
@@ -114,8 +114,8 @@ class DynamicEntryDependency extends NullDependency {
114
114
  updateHash (hash, context) {
115
115
  const { resultPath, relativePath } = this
116
116
  if (resultPath) hash.update(resultPath)
117
- // relativePath为MPX_CURRENT_CHUNK时,插入随机数hash使当前module的codeGeneration cache失效,以执行dep.apply动态获取当前module所属的chunk路径
118
- if (relativePath === MPX_CURRENT_CHUNK) hash.update('' + Math.random())
117
+ // relativePath为MPX_CURRENT_CHUNK时,插入随机hash使当前module的codeGeneration cache失效,从而执行dep.apply动态获取当前module所属的chunk路径
118
+ if (relativePath === MPX_CURRENT_CHUNK) hash.update('' + (+new Date()) + Math.random())
119
119
  super.updateHash(hash, context)
120
120
  }
121
121
 
package/lib/index.js CHANGED
@@ -951,6 +951,9 @@ class MpxWebpackPlugin {
951
951
  parser.state.current.addDependency(dep)
952
952
  }
953
953
  return true
954
+ } else {
955
+ compilation.errors.push(new Error(`The require async JS [${request}] need to declare subpackage name by root`))
956
+ return true
954
957
  }
955
958
  }
956
959
  }
@@ -969,46 +972,6 @@ class MpxWebpackPlugin {
969
972
  stage: -1000
970
973
  }, (expr, calleeMembers, callExpr) => requireAsyncHandler(callExpr, calleeMembers))
971
974
 
972
- const transHandler = (expr) => {
973
- const module = parser.state.module
974
- const current = parser.state.current
975
- const { queryObj, resourcePath } = parseRequest(module.resource)
976
- const localSrcMode = queryObj.mode
977
- const globalSrcMode = mpx.srcMode
978
- const srcMode = localSrcMode || globalSrcMode
979
- const mode = mpx.mode
980
-
981
- let target
982
-
983
- if (expr.type === 'Identifier') {
984
- target = expr
985
- } else if (expr.type === 'MemberExpression') {
986
- target = expr.object
987
- }
988
- if (!matchCondition(resourcePath, this.options.transMpxRules) || resourcePath.indexOf('@mpxjs') !== -1 || !target || mode === srcMode) {
989
- return
990
- }
991
-
992
- const type = target.name
993
-
994
- const name = type === 'wx' ? 'mpx' : 'createFactory'
995
- const replaceContent = type === 'wx' ? 'mpx' : `createFactory(${JSON.stringify(type)})`
996
-
997
- const dep = new ReplaceDependency(replaceContent, target.range)
998
- current.addPresentationalDependency(dep)
999
-
1000
- let needInject = true
1001
- for (let dep of module.dependencies) {
1002
- if (dep instanceof CommonJsVariableDependency && dep.name === name) {
1003
- needInject = false
1004
- break
1005
- }
1006
- }
1007
- if (needInject) {
1008
- const dep = new CommonJsVariableDependency(`@mpxjs/core/src/runtime/${name}`, name)
1009
- module.addDependency(dep)
1010
- }
1011
- }
1012
975
  // hack babel polyfill global
1013
976
  parser.hooks.statementIf.tap('MpxWebpackPlugin', (expr) => {
1014
977
  if (/core-js.+microtask/.test(parser.state.module.resource)) {
@@ -1043,90 +1006,119 @@ class MpxWebpackPlugin {
1043
1006
  }
1044
1007
  })
1045
1008
 
1009
+ // 处理跨平台转换
1046
1010
  if (mpx.srcMode !== mpx.mode) {
1047
- // 全量替换未声明的wx identifier
1048
- parser.hooks.expression.for('wx').tap('MpxWebpackPlugin', transHandler)
1049
-
1050
- // parser.hooks.evaluate.for('MemberExpression').tap('MpxWebpackPlugin', (expr) => {
1051
- // // Undeclared varible for wx[identifier]()
1052
- // // TODO Unable to handle wx[identifier]
1053
- // if (expr.object.name === 'wx' && !parser.scope.definitions.has('wx')) {
1054
- // transHandler(expr)
1055
- // }
1056
- // })
1057
- // // Trans for wx.xx, wx['xx'], wx.xx(), wx['xx']()
1058
- // parser.hooks.expressionMemberChain.for('wx').tap('MpxWebpackPlugin', transHandler)
1011
+ // 处理跨平台全局对象转换
1012
+ const transGlobalObject = (expr) => {
1013
+ const module = parser.state.module
1014
+ const current = parser.state.current
1015
+ const { queryObj, resourcePath } = parseRequest(module.resource)
1016
+ const localSrcMode = queryObj.mode
1017
+ const globalSrcMode = mpx.srcMode
1018
+ const srcMode = localSrcMode || globalSrcMode
1019
+ const mode = mpx.mode
1020
+
1021
+ let target
1022
+ if (expr.type === 'Identifier') {
1023
+ target = expr
1024
+ } else if (expr.type === 'MemberExpression') {
1025
+ target = expr.object
1026
+ }
1027
+
1028
+ if (!matchCondition(resourcePath, this.options.transMpxRules) || resourcePath.indexOf('@mpxjs') !== -1 || !target || mode === srcMode) return
1029
+
1030
+ const type = target.name
1031
+ const name = type === 'wx' ? 'mpx' : 'createFactory'
1032
+ const replaceContent = type === 'wx' ? 'mpx' : `createFactory(${JSON.stringify(type)})`
1033
+
1034
+ const dep = new ReplaceDependency(replaceContent, target.range)
1035
+ current.addPresentationalDependency(dep)
1036
+
1037
+ let needInject = true
1038
+ for (let dep of module.dependencies) {
1039
+ if (dep instanceof CommonJsVariableDependency && dep.name === name) {
1040
+ needInject = false
1041
+ break
1042
+ }
1043
+ }
1044
+ if (needInject) {
1045
+ const dep = new CommonJsVariableDependency(`@mpxjs/core/src/runtime/${name}`, name)
1046
+ module.addDependency(dep)
1047
+ }
1048
+ }
1049
+
1050
+ // 转换wx全局对象
1051
+ parser.hooks.expression.for('wx').tap('MpxWebpackPlugin', transGlobalObject)
1059
1052
  // Proxy ctor for transMode
1060
1053
  if (!this.options.forceDisableProxyCtor) {
1061
1054
  parser.hooks.call.for('Page').tap('MpxWebpackPlugin', (expr) => {
1062
- transHandler(expr.callee)
1055
+ transGlobalObject(expr.callee)
1063
1056
  })
1064
1057
  parser.hooks.call.for('Component').tap('MpxWebpackPlugin', (expr) => {
1065
- transHandler(expr.callee)
1058
+ transGlobalObject(expr.callee)
1066
1059
  })
1067
1060
  parser.hooks.call.for('App').tap('MpxWebpackPlugin', (expr) => {
1068
- transHandler(expr.callee)
1061
+ transGlobalObject(expr.callee)
1069
1062
  })
1070
1063
  if (mpx.mode === 'ali' || mpx.mode === 'web') {
1071
1064
  // 支付宝和web不支持Behaviors
1072
1065
  parser.hooks.call.for('Behavior').tap('MpxWebpackPlugin', (expr) => {
1073
- transHandler(expr.callee)
1066
+ transGlobalObject(expr.callee)
1074
1067
  })
1075
1068
  }
1076
1069
  }
1077
- }
1078
1070
 
1079
- const apiBlackListMap = [
1080
- 'createApp',
1081
- 'createPage',
1082
- 'createComponent',
1083
- 'createStore',
1084
- 'createStoreWithThis',
1085
- 'mixin',
1086
- 'injectMixins',
1087
- 'toPureObject',
1088
- 'observable',
1089
- 'watch',
1090
- 'use',
1091
- 'set',
1092
- 'remove',
1093
- 'delete: del',
1094
- 'setConvertRule',
1095
- 'getMixin',
1096
- 'getComputed',
1097
- 'implement'
1098
- ].reduce((map, api) => {
1099
- map[api] = true
1100
- return map
1101
- }, {})
1102
-
1103
- const handler = (expr) => {
1104
- const callee = expr.callee
1105
- const args = expr.arguments
1106
- const name = callee.object.name
1107
- const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1108
- const localSrcMode = queryObj.mode
1109
- const globalSrcMode = mpx.srcMode
1110
- const srcMode = localSrcMode || globalSrcMode
1111
-
1112
- if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) {
1113
- return
1114
- }
1071
+ // 为跨平台api调用注入srcMode参数指导api运行时转换
1072
+ const apiBlackListMap = [
1073
+ 'createApp',
1074
+ 'createPage',
1075
+ 'createComponent',
1076
+ 'createStore',
1077
+ 'createStoreWithThis',
1078
+ 'mixin',
1079
+ 'injectMixins',
1080
+ 'toPureObject',
1081
+ 'observable',
1082
+ 'watch',
1083
+ 'use',
1084
+ 'set',
1085
+ 'remove',
1086
+ 'delete',
1087
+ 'setConvertRule',
1088
+ 'getMixin',
1089
+ 'getComputed',
1090
+ 'implement'
1091
+ ].reduce((map, api) => {
1092
+ map[api] = true
1093
+ return map
1094
+ }, {})
1115
1095
 
1116
- const srcModeString = `__mpx_src_mode_${srcMode}__`
1117
- const dep = new InjectDependency({
1118
- content: args.length
1119
- ? `, ${JSON.stringify(srcModeString)}`
1120
- : JSON.stringify(srcModeString),
1121
- index: expr.end - 1
1122
- })
1123
- parser.state.current.addPresentationalDependency(dep)
1124
- }
1096
+ const injectSrcModeForTransApi = (expr, members) => {
1097
+ // members为空数组时,callee并不是memberExpression
1098
+ if (!members.length) return
1099
+ const callee = expr.callee
1100
+ const args = expr.arguments
1101
+ const name = callee.object.name
1102
+ const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1103
+ const localSrcMode = queryObj.mode
1104
+ const globalSrcMode = mpx.srcMode
1105
+ const srcMode = localSrcMode || globalSrcMode
1106
+
1107
+ if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
1108
+
1109
+ const srcModeString = `__mpx_src_mode_${srcMode}__`
1110
+ const dep = new InjectDependency({
1111
+ content: args.length
1112
+ ? `, ${JSON.stringify(srcModeString)}`
1113
+ : JSON.stringify(srcModeString),
1114
+ index: expr.end - 1
1115
+ })
1116
+ parser.state.current.addPresentationalDependency(dep)
1117
+ }
1125
1118
 
1126
- if (mpx.srcMode !== mpx.mode) {
1127
- parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', handler)
1128
- parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', handler)
1129
- parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', handler)
1119
+ parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1120
+ parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1121
+ parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1130
1122
  }
1131
1123
  })
1132
1124
 
@@ -12,7 +12,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning, custom
12
12
  const resolveMode = mpx.resolveMode
13
13
  const externals = mpx.externals
14
14
  const root = mpx.projectRoot
15
- const publicPath = loaderContext._compilation.outputOptions.publicPath || ''
15
+ const publicPath = loaderContext._compilation?.outputOptions.publicPath || ''
16
16
  const pathHash = mpx.pathHash
17
17
  const getOutputPath = mpx.getOutputPath
18
18
  const mode = mpx.mode
@@ -96,6 +96,7 @@ module.exports = function (content) {
96
96
  } else {
97
97
  fs.readFile(file, (err, content) => {
98
98
  if (err) return callback(err)
99
+ if (!this._compilation) return callback()
99
100
  let targetPath = path.relative(context, file)
100
101
  this._compilation.assets[targetPath] = {
101
102
  size: function size () {
@@ -350,7 +351,7 @@ module.exports = function (content) {
350
351
  }
351
352
 
352
353
  const recordIndependent = (root, request) => {
353
- this._module.addPresentationalDependency(new RecordIndependentDependency(root, request))
354
+ this._module && this._module.addPresentationalDependency(new RecordIndependentDependency(root, request))
354
355
  }
355
356
 
356
357
  const processIndependent = (otherConfig, context, tarRoot, callback) => {
@@ -181,9 +181,36 @@ module.exports = function getSpec ({ warn, error }) {
181
181
  }
182
182
  }
183
183
  },
184
+ {
185
+ // style样式绑定
186
+ test: /^(style|wx:style)$/,
187
+ web ({ value }, { el }) {
188
+ if (el.isStyleParsed) {
189
+ return false
190
+ }
191
+ let styleBinding = []
192
+ el.isStyleParsed = true
193
+ el.attrsList.map((item, index) => {
194
+ const parsed = parseMustache(item.value)
195
+ if (item.name === 'style') {
196
+ if (parsed.hasBinding || parsed.result.indexOf('rpx') > -1) {
197
+ styleBinding.push(parseMustache(item.value).result)
198
+ } else {
199
+ styleBinding.push(JSON.stringify(item.value))
200
+ }
201
+ } else if (item.name === 'wx:style') {
202
+ styleBinding.push(parseMustache(item.value).result)
203
+ }
204
+ })
205
+ return {
206
+ name: ':style',
207
+ value: `[${styleBinding}] | transRpxStyle`
208
+ }
209
+ }
210
+ },
184
211
  {
185
212
  // 样式类名绑定
186
- test: /^wx:(class|style)$/,
213
+ test: /^wx:class$/,
187
214
  web ({ name, value }) {
188
215
  const dir = this.test.exec(name)[1]
189
216
  const parsed = parseMustache(value)
@@ -85,6 +85,51 @@ export default function processOption (
85
85
  }
86
86
  })
87
87
 
88
+ Vue.filter('transRpxStyle', style => {
89
+ const defaultTransRpxFn = function (match, $1) {
90
+ const rpx2vwRatio = +(100 / 750).toFixed(8)
91
+ return '' + ($1 * rpx2vwRatio) + 'vw'
92
+ }
93
+ const transRpxFn = global.__mpxTransRpxFn || defaultTransRpxFn
94
+ const parsedStyleObj = {}
95
+ const rpxRegExpG = /\b(\d+(\.\d+)?)rpx\b/g
96
+ const parseStyleText = (cssText) => {
97
+ const listDelimiter = /;(?![^(]*\))/g
98
+ const propertyDelimiter = /:(.+)/
99
+ if (typeof cssText === 'string') {
100
+ cssText.split(listDelimiter).forEach((item) => {
101
+ if (item) {
102
+ var tmp = item.split(propertyDelimiter)
103
+ tmp.length > 1 && (parsedStyleObj[tmp[0].trim()] = tmp[1].trim())
104
+ }
105
+ })
106
+ } else if (typeof cssText === 'object') {
107
+ if (Array.isArray(cssText)) {
108
+ cssText.forEach(cssItem => {
109
+ parseStyleText(cssItem)
110
+ })
111
+ } else {
112
+ Object.assign(parsedStyleObj, cssText)
113
+ }
114
+ }
115
+ }
116
+ const transRpxStyleFn = (val) => {
117
+ if (typeof val === 'string' && val.indexOf('rpx') > 0) {
118
+ return val.replace(rpxRegExpG, transRpxFn).replace(/"/g, '')
119
+ }
120
+ return val
121
+ }
122
+ if (style) {
123
+ style.forEach(item => {
124
+ parseStyleText(item)
125
+ for (let key in parsedStyleObj) {
126
+ parsedStyleObj[key] = transRpxStyleFn(parsedStyleObj[key])
127
+ }
128
+ })
129
+ }
130
+ return parsedStyleObj
131
+ })
132
+
88
133
  const routes = []
89
134
 
90
135
  for (const pagePath in pagesMap) {
@@ -1901,20 +1901,20 @@ function getVirtualHostRoot (options, meta) {
1901
1901
  }
1902
1902
 
1903
1903
  function processShow (el, options, root) {
1904
+ // 开启 virtualhost 全部走 props 传递处理
1905
+ // 未开启 virtualhost 直接绑定 display:none 到节点上
1904
1906
  let show = getAndRemoveAttr(el, config[mode].directive.show).val
1905
1907
  if (mode === 'swan') show = wrapMustache(show)
1906
- let processFlag = el.parent === root
1907
- // 当ali且未开启virtualHost时,mpxShow打到根节点上
1908
- if (mode === 'ali' && !options.hasVirtualHost) processFlag = el === root
1909
- if (options.isComponent && processFlag && isRealNode(el)) {
1910
- if (show !== undefined) {
1911
- show = `{{${parseMustache(show).result}&&mpxShow}}`
1912
- } else {
1913
- show = '{{mpxShow}}'
1908
+
1909
+ if (options.hasVirtualHost) {
1910
+ if (options.isComponent && el.parent === root && isRealNode(el)) {
1911
+ if (show !== undefined) {
1912
+ show = `{{${parseMustache(show).result}&&mpxShow}}`
1913
+ } else {
1914
+ show = '{{mpxShow}}'
1915
+ }
1914
1916
  }
1915
- }
1916
- if (show !== undefined) {
1917
- if (isComponentNode(el, options)) {
1917
+ if (isComponentNode(el, options) && show !== undefined) {
1918
1918
  if (show === '') {
1919
1919
  show = '{{false}}'
1920
1920
  }
@@ -1923,6 +1923,14 @@ function processShow (el, options, root) {
1923
1923
  value: show
1924
1924
  }])
1925
1925
  } else {
1926
+ processShowStyle()
1927
+ }
1928
+ } else {
1929
+ processShowStyle()
1930
+ }
1931
+
1932
+ function processShowStyle () {
1933
+ if (show !== undefined) {
1926
1934
  const showExp = parseMustache(show).result
1927
1935
  let oldStyle = getAndRemoveAttr(el, 'style').val
1928
1936
  oldStyle = oldStyle ? oldStyle + ';' : ''
@@ -1,6 +1,7 @@
1
1
  const path = require('path')
2
2
 
3
3
  module.exports = function evalJSONJS (source, filename, loaderContext) {
4
+ if (!loaderContext._compiler) return {}
4
5
  const fs = loaderContext._compiler.inputFileSystem
5
6
  const defs = loaderContext.getMpx().defs
6
7
  const defKeys = Object.keys(defs)
@@ -1,8 +1,8 @@
1
1
  module.exports = function (loaderContext) {
2
- const compilation = loaderContext._compilation
3
- const moduleGraph = compilation.moduleGraph
2
+ if (!loaderContext._compilation) return ''
3
+ const moduleGraph = loaderContext._compilation.moduleGraph
4
4
  let entryName = ''
5
- for (const [name, { dependencies }] of compilation.entries) {
5
+ for (const [name, { dependencies }] of loaderContext._compilation.entries) {
6
6
  const entryModule = moduleGraph.getModule(dependencies[0])
7
7
  if (entryModule.resource === loaderContext.resource) {
8
8
  entryName = name
@@ -5,7 +5,6 @@ const async = require('async')
5
5
  const { JSON_JS_EXT } = require('./const')
6
6
 
7
7
  module.exports = function getJSONContent (json, loaderContext, callback) {
8
- // error process
9
8
  if (!loaderContext._compiler) return callback(null, '{}')
10
9
  const fs = loaderContext._compiler.inputFileSystem
11
10
  async.waterfall([
@@ -219,8 +219,7 @@ module.exports = function (json, {
219
219
  }
220
220
 
221
221
  pagesMap[resourcePath] = outputPath
222
- loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'page', outputPath))
223
-
222
+ loaderContext._module && loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'page', outputPath))
224
223
  localPagesMap[outputPath] = {
225
224
  resource: addQuery(resource, { isPage: true }),
226
225
  async: tarRoot || queryObj.async,
@@ -269,8 +268,7 @@ module.exports = function (json, {
269
268
  }
270
269
  const { resourcePath, queryObj } = parseRequest(resource)
271
270
  componentsMap[resourcePath] = outputPath
272
- loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'component', outputPath))
273
-
271
+ loaderContext._module && loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'component', outputPath))
274
272
  localComponentsMap[name] = {
275
273
  resource: addQuery(resource, {
276
274
  isComponent: true,
@@ -129,8 +129,8 @@ module.exports = function (script, {
129
129
  global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
130
130
  global.__mpxGenericsMap = {}
131
131
  global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
132
- global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}\n`
133
-
132
+ global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}
133
+ global.__mpxTransRpxFn = ${mpx.webConfig.transRpxFn}\n`
134
134
  if (i18n) {
135
135
  const i18nObj = Object.assign({}, i18n)
136
136
  content += ` import VueI18n from 'vue-i18n'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.17",
3
+ "version": "2.7.20",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -80,5 +80,5 @@
80
80
  "engines": {
81
81
  "node": ">=14.14.0"
82
82
  },
83
- "gitHead": "6079aab5d336ecfac4a94a2fef44aa989cdf6614"
83
+ "gitHead": "b4a3fea64b6a0135989ce9b3b26ccb24318b8027"
84
84
  }