@mpxjs/webpack-plugin 2.9.11-test.0 → 2.9.13

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/index.js CHANGED
@@ -9,6 +9,7 @@ const NullFactory = require('webpack/lib/NullFactory')
9
9
  const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
10
10
  const CommonJsAsyncDependency = require('./dependencies/CommonJsAsyncDependency')
11
11
  const CommonJsExtractDependency = require('./dependencies/CommonJsExtractDependency')
12
+ const harmonySpecifierTag = require('webpack/lib/dependencies/HarmonyImportDependencyParserPlugin').harmonySpecifierTag
12
13
  const NormalModule = require('webpack/lib/NormalModule')
13
14
  const EntryPlugin = require('webpack/lib/EntryPlugin')
14
15
  const JavascriptModulesPlugin = require('webpack/lib/javascript/JavascriptModulesPlugin')
@@ -327,30 +328,39 @@ class MpxWebpackPlugin {
327
328
  compiler.options.resolve.plugins.push(new FixDescriptionInfoPlugin())
328
329
 
329
330
  const optimization = compiler.options.optimization
330
- optimization.runtimeChunk = {
331
- name: (entrypoint) => {
332
- for (const packageName in mpx.independentSubpackagesMap) {
333
- if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
334
- return `${packageName}/bundle`
331
+ if (this.options.mode !== 'web') {
332
+ optimization.runtimeChunk = {
333
+ name: (entrypoint) => {
334
+ for (const packageName in mpx.independentSubpackagesMap) {
335
+ if (hasOwn(mpx.independentSubpackagesMap, packageName) && isChunkInPackage(entrypoint.name, packageName)) {
336
+ return `${packageName}/bundle`
337
+ }
335
338
  }
339
+ return 'bundle'
336
340
  }
337
- return 'bundle'
338
341
  }
339
342
  }
340
- const splitChunksOptions = Object.assign({
341
- defaultSizeTypes: ['javascript', 'unknown'],
342
- chunks: 'all',
343
- usedExports: optimization.usedExports === true,
344
- minChunks: 1,
345
- minSize: 1000,
346
- enforceSizeThreshold: Infinity,
347
- maxAsyncRequests: 30,
348
- maxInitialRequests: 30,
349
- automaticNameDelimiter: '-'
350
- }, optimization.splitChunks)
351
- delete optimization.splitChunks
352
- const splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
353
- splitChunksPlugin.apply(compiler)
343
+
344
+ let splitChunksOptions = null
345
+ let splitChunksPlugin = null
346
+ // 输出web ssr需要将optimization.splitChunks设置为false以关闭splitChunks
347
+ if (optimization.splitChunks !== false) {
348
+ splitChunksOptions = Object.assign({
349
+ chunks: 'all',
350
+ usedExports: optimization.usedExports === true,
351
+ minChunks: 1,
352
+ minSize: 1000,
353
+ enforceSizeThreshold: Infinity,
354
+ maxAsyncRequests: 30,
355
+ maxInitialRequests: 30,
356
+ automaticNameDelimiter: '-',
357
+ cacheGroups: {}
358
+ }, optimization.splitChunks)
359
+ splitChunksOptions.defaultSizeTypes = ['javascript', 'unknown']
360
+ delete optimization.splitChunks
361
+ splitChunksPlugin = new SplitChunksPlugin(splitChunksOptions)
362
+ splitChunksPlugin.apply(compiler)
363
+ }
354
364
 
355
365
  // 代理writeFile
356
366
  if (this.options.writeMode === 'changed') {
@@ -447,7 +457,6 @@ class MpxWebpackPlugin {
447
457
  },
448
458
  name: `${packageName}/bundle`,
449
459
  minChunks: 2,
450
- minSize: 1000,
451
460
  priority: 100,
452
461
  chunks: 'all'
453
462
  }
@@ -952,15 +961,35 @@ class MpxWebpackPlugin {
952
961
  }
953
962
  }
954
963
  }
955
- // 自动跟进分包配置修改splitChunksPlugin配置
964
+ // 自动使用分包配置修改splitChunksPlugin配置
956
965
  if (splitChunksPlugin) {
957
966
  let needInit = false
958
- Object.keys(mpx.componentsMap).forEach((packageName) => {
959
- if (!hasOwn(splitChunksOptions.cacheGroups, packageName)) {
967
+ if (mpx.mode === 'web') {
968
+ // web独立处理splitChunk
969
+ if (!hasOwn(splitChunksOptions.cacheGroups, 'main')) {
970
+ splitChunksOptions.cacheGroups.main = {
971
+ chunks: 'initial',
972
+ name: 'bundle',
973
+ test: /[\\/]node_modules[\\/]/
974
+ }
960
975
  needInit = true
961
- splitChunksOptions.cacheGroups[packageName] = getPackageCacheGroup(packageName)
962
976
  }
963
- })
977
+ if (!hasOwn(splitChunksOptions.cacheGroups, 'async')) {
978
+ splitChunksOptions.cacheGroups.async = {
979
+ chunks: 'async',
980
+ name: 'async',
981
+ minChunks: 2
982
+ }
983
+ needInit = true
984
+ }
985
+ } else {
986
+ Object.keys(mpx.componentsMap).forEach((packageName) => {
987
+ if (!hasOwn(splitChunksOptions.cacheGroups, packageName)) {
988
+ splitChunksOptions.cacheGroups[packageName] = getPackageCacheGroup(packageName)
989
+ needInit = true
990
+ }
991
+ })
992
+ }
964
993
  if (needInit) {
965
994
  splitChunksPlugin.options = new SplitChunksPlugin(splitChunksOptions).options
966
995
  }
@@ -1304,56 +1333,56 @@ class MpxWebpackPlugin {
1304
1333
  }
1305
1334
 
1306
1335
  // 为跨平台api调用注入srcMode参数指导api运行时转换
1307
- // const apiBlackListMap = [
1308
- // 'createApp',
1309
- // 'createPage',
1310
- // 'createComponent',
1311
- // 'createStore',
1312
- // 'createStoreWithThis',
1313
- // 'mixin',
1314
- // 'injectMixins',
1315
- // 'toPureObject',
1316
- // 'observable',
1317
- // 'watch',
1318
- // 'use',
1319
- // 'set',
1320
- // 'remove',
1321
- // 'delete',
1322
- // 'setConvertRule',
1323
- // 'getMixin',
1324
- // 'getComputed',
1325
- // 'implement'
1326
- // ].reduce((map, api) => {
1327
- // map[api] = true
1328
- // return map
1329
- // }, {})
1330
- //
1331
- // const injectSrcModeForTransApi = (expr, members) => {
1332
- // // members为空数组时,callee并不是memberExpression
1333
- // if (!members.length) return
1334
- // const callee = expr.callee
1335
- // const args = expr.arguments
1336
- // const name = callee.object.name
1337
- // const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1338
- // const localSrcMode = queryObj.mode
1339
- // const globalSrcMode = mpx.srcMode
1340
- // const srcMode = localSrcMode || globalSrcMode
1341
- //
1342
- // if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
1343
- //
1344
- // const srcModeString = `__mpx_src_mode_${srcMode}__`
1345
- // const dep = new InjectDependency({
1346
- // content: args.length
1347
- // ? `, ${JSON.stringify(srcModeString)}`
1348
- // : JSON.stringify(srcModeString),
1349
- // index: expr.end - 1
1350
- // })
1351
- // parser.state.current.addPresentationalDependency(dep)
1352
- // }
1353
- //
1354
- // parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1355
- // parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1356
- // parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1336
+ const apiBlackListMap = [
1337
+ 'createApp',
1338
+ 'createPage',
1339
+ 'createComponent',
1340
+ 'createStore',
1341
+ 'createStoreWithThis',
1342
+ 'mixin',
1343
+ 'injectMixins',
1344
+ 'toPureObject',
1345
+ 'observable',
1346
+ 'watch',
1347
+ 'use',
1348
+ 'set',
1349
+ 'remove',
1350
+ 'delete',
1351
+ 'setConvertRule',
1352
+ 'getMixin',
1353
+ 'getComputed',
1354
+ 'implement'
1355
+ ].reduce((map, api) => {
1356
+ map[api] = true
1357
+ return map
1358
+ }, {})
1359
+
1360
+ const injectSrcModeForTransApi = (expr, members) => {
1361
+ // members为空数组时,callee并不是memberExpression
1362
+ if (!members.length) return
1363
+ const callee = expr.callee
1364
+ const args = expr.arguments
1365
+ const name = callee.object.name
1366
+ const { queryObj, resourcePath } = parseRequest(parser.state.module.resource)
1367
+ const localSrcMode = queryObj.mode
1368
+ const globalSrcMode = mpx.srcMode
1369
+ const srcMode = localSrcMode || globalSrcMode
1370
+
1371
+ if (srcMode === globalSrcMode || apiBlackListMap[callee.property.name || callee.property.value] || (name !== 'mpx' && name !== 'wx') || (name === 'wx' && !matchCondition(resourcePath, this.options.transMpxRules))) return
1372
+
1373
+ const srcModeString = `__mpx_src_mode_${srcMode}__`
1374
+ const dep = new InjectDependency({
1375
+ content: args.length
1376
+ ? `, ${JSON.stringify(srcModeString)}`
1377
+ : JSON.stringify(srcModeString),
1378
+ index: expr.end - 1
1379
+ })
1380
+ parser.state.current.addPresentationalDependency(dep)
1381
+ }
1382
+
1383
+ parser.hooks.callMemberChain.for(harmonySpecifierTag).tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1384
+ parser.hooks.callMemberChain.for('mpx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1385
+ parser.hooks.callMemberChain.for('wx').tap('MpxWebpackPlugin', injectSrcModeForTransApi)
1357
1386
  }
1358
1387
  }
1359
1388
  normalModuleFactory.hooks.parser.for('javascript/auto').tap('MpxWebpackPlugin', normalModuleFactoryParserCallback)
@@ -14,7 +14,7 @@ web的额外逻辑,因为小程序组件和web存在差异,比如事件相
14
14
 
15
15
  Mpx的转换一个重要原则是转不了的东西通过控制台打印提示用户,要求用户提供一份符合对应平台的代码通过条件编译支持。因此错误输出格式保持一致是有必要的。
16
16
 
17
- 在 index.web.js 中,会汇总每个组件的转换规则函数,为了使错误信息标准化,一致化,错误打印函数的生成函数实现在index.js里。
17
+ 在 index.js 中,会汇总每个组件的转换规则函数,为了使错误信息标准化,一致化,错误打印函数的生成函数实现在index.js里。
18
18
 
19
19
  每个组件文件是一个方法,接受错误打印生成方法,根据组件名生成对应的错误打印方法。
20
20
 
@@ -39,7 +39,7 @@
39
39
  render: function render () {
40
40
  const slot = this.$slots.default
41
41
  const vnode = getFirstComponentChild(slot)
42
- if (!isBrowser) {
42
+ if (!isBrowser || !vnode) {
43
43
  return vnode || (slot && slot[0])
44
44
  }
45
45
  const router = global.__mpxRouter
@@ -4,8 +4,7 @@
4
4
 
5
5
  <script>
6
6
  import { getCustomEvent } from './getInnerListeners'
7
- import promisify from './promisify'
8
- import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy'
7
+ import { redirectTo, navigateTo, navigateBack, reLaunch, switchTab } from '@mpxjs/api-proxy/src/web/api/index'
9
8
 
10
9
  const eventLoad = 'load'
11
10
  const eventError = 'error'
@@ -96,7 +95,7 @@
96
95
  messageCallback (event) {
97
96
  const hostValidate = this.hostValidate(event.origin)
98
97
  const data = event.data
99
- let value = data.payload
98
+ const value = data.payload
100
99
  if (!hostValidate) {
101
100
  return
102
101
  }
@@ -109,19 +108,19 @@
109
108
  })
110
109
  break
111
110
  case 'navigateTo':
112
- asyncCallback = promisify(value, navigateTo)
111
+ asyncCallback = navigateTo(value)
113
112
  break
114
113
  case 'navigateBack':
115
- asyncCallback = promisify(value = {}, navigateBack)
114
+ asyncCallback = value ? navigateBack(value) : navigateBack()
116
115
  break
117
116
  case 'redirectTo':
118
- asyncCallback = promisify(value, redirectTo)
117
+ asyncCallback = redirectTo(value)
119
118
  break
120
119
  case 'switchTab':
121
- asyncCallback = promisify(value, switchTab)
120
+ asyncCallback = switchTab(value)
122
121
  break
123
122
  case 'reLaunch':
124
- asyncCallback = promisify(value, reLaunch)
123
+ asyncCallback = reLaunch(value)
125
124
  break
126
125
  case 'getLocation':
127
126
  const getLocation = mpx.config.webviewConfig.apiImplementations && mpx.config.webviewConfig.apiImplementations.getLocation
@@ -325,7 +325,7 @@ function createApp ({ componentsMap, Vue, pagesMap, firstPage, VueRouter, App, t
325
325
  }
326
326
  }
327
327
 
328
- export function processAppOption ({ firstPage, pagesMap, componentsMap, App, Vue, VueRouter, tabBarMap, webConfig }) {
328
+ export function processAppOption ({ firstPage, pagesMap, componentsMap, App, Vue, VueRouter, tabBarMap, el }) {
329
329
  if (!isBrowser) {
330
330
  return context => {
331
331
  const { app, router, pinia = {} } = createApp({
@@ -364,6 +364,6 @@ export function processAppOption ({ firstPage, pagesMap, componentsMap, App, Vue
364
364
  if (window.__INITIAL_STATE__ && pinia) {
365
365
  pinia.state.value = window.__INITIAL_STATE__
366
366
  }
367
- app.$mount(webConfig.el || '#app')
367
+ app.$mount(el)
368
368
  }
369
369
  }
@@ -1,3 +1,4 @@
1
+ const path = require('path')
1
2
  const postcss = require('postcss')
2
3
  const loadPostcssConfig = require('./load-postcss-config')
3
4
  const { MPX_ROOT_VIEW, MPX_APP_MODULE_ID } = require('../utils/const')
@@ -27,7 +28,7 @@ module.exports = function (css, map) {
27
28
  return matchCondition(this.resourcePath, { include, exclude })
28
29
  }
29
30
 
30
- const inlineConfig = Object.assign({}, mpx.postcssInlineConfig, { defs })
31
+ const inlineConfig = Object.assign({}, mpx.postcssInlineConfig, { defs, inlineConfigFile: path.join(mpx.projectRoot, 'vue.config.js') })
31
32
  loadPostcssConfig(this, inlineConfig).then(config => {
32
33
  const plugins = [] // init with trim plugin
33
34
  const options = Object.assign(
@@ -82,9 +83,9 @@ module.exports = function (css, map) {
82
83
  }
83
84
  }
84
85
 
85
- plugins.push(...config.plugins) // push user config plugins
86
+ const finalPlugins = config.prePlugins.concat(plugins, config.plugins)
86
87
 
87
- return postcss(plugins)
88
+ return postcss(finalPlugins)
88
89
  .process(css, options)
89
90
  .then(result => {
90
91
  // ali环境添加全局样式抹平root差异
@@ -1,7 +1,12 @@
1
1
  const load = require('postcss-load-config')
2
+ const loadPlugins = require('postcss-load-config/src/plugins')
2
3
 
3
4
  let loaded
4
5
 
6
+ function formatPlugins (plugins, file) {
7
+ return plugins ? loadPlugins({ plugins }, file) : []
8
+ }
9
+
5
10
  module.exports = function loadPostcssConfig (loaderContext, inlineConfig = {}) {
6
11
  if (inlineConfig.ignoreConfigFile) {
7
12
  loaded = Promise.resolve({
@@ -28,19 +33,26 @@ module.exports = function loadPostcssConfig (loaderContext, inlineConfig = {}) {
28
33
  })
29
34
  }
30
35
 
31
- return loaded.then(config => {
32
- let plugins = inlineConfig.plugins || []
36
+ return loaded.then((config = {}) => {
37
+ let plugins = formatPlugins(inlineConfig.plugins, inlineConfig.inlineConfigFile)
38
+ let prePlugins = formatPlugins(inlineConfig.mpxPrePlugins, inlineConfig.inlineConfigFile)
33
39
  let options = inlineConfig.options || {}
34
40
 
35
41
  // merge postcss config file
36
- if (config && config.plugins) {
42
+ if (config.plugins) {
37
43
  plugins = plugins.concat(config.plugins)
38
44
  }
39
- if (config && config.options) {
45
+ if (config.options) {
46
+ if (config.options.mpxPrePlugins) {
47
+ // 使入参和postcss格式保持一致
48
+ prePlugins = prePlugins.concat(formatPlugins(config.options.mpxPrePlugins, config.file))
49
+ delete config.options.mpxPrePlugins
50
+ }
40
51
  options = Object.assign({}, config.options, options)
41
52
  }
42
53
 
43
54
  return {
55
+ prePlugins,
44
56
  plugins,
45
57
  options
46
58
  }
@@ -121,24 +121,19 @@ function checkDelAndGetPath (path) {
121
121
  }
122
122
 
123
123
  if (t.isLogicalExpression(container)) { // case: a || ((b || c) && d)
124
- ignore = true
125
- break
126
- }
127
-
128
- // case: a ??= b
129
- if (
130
- key === 'right' &&
131
- t.isAssignmentExpression(container) &&
132
- ['??=', '||=', '&&='].includes(container.operator)
133
- ) {
124
+ canDel = false
134
125
  ignore = true
135
126
  break
136
127
  }
137
128
 
138
129
  if (t.isConditionalExpression(container)) {
139
- if (key === 'test') canDel = false
140
- else ignore = true
141
- break
130
+ if (key === 'test') {
131
+ canDel = false
132
+ break
133
+ } else {
134
+ ignore = true
135
+ replace = true
136
+ }
142
137
  }
143
138
 
144
139
  if (
@@ -229,11 +224,10 @@ module.exports = {
229
224
  // 删除局部作用域的变量
230
225
  if (scopeBinding) {
231
226
  if (renderReduce) {
232
- const { delPath, canDel, ignore, replace } = checkDelAndGetPath(path)
233
- if (canDel && !ignore) {
227
+ const { delPath, canDel, replace } = checkDelAndGetPath(path)
228
+ if (canDel) {
234
229
  delPath.delInfo = {
235
230
  isLocal: true,
236
- canDel,
237
231
  replace
238
232
  }
239
233
  }
@@ -252,14 +246,16 @@ module.exports = {
252
246
  if (!renderReduce) return
253
247
 
254
248
  const { delPath, canDel, ignore, replace } = checkDelAndGetPath(path)
255
- if (ignore) return
256
249
 
257
- delPath.delInfo = {
258
- keyPath,
259
- canDel,
260
- replace
250
+ if (canDel) {
251
+ delPath.delInfo = {
252
+ keyPath,
253
+ replace
254
+ }
261
255
  }
262
256
 
257
+ if (ignore) return // ignore不计数,不需要被统计
258
+
263
259
  const { bindings } = bindingsMap.get(currentBlock)
264
260
  const target = bindings[keyPath] || []
265
261
  target.push({
@@ -310,28 +306,26 @@ module.exports = {
310
306
  enter (path) {
311
307
  // 删除重复变量
312
308
  if (path.delInfo) {
313
- const { keyPath, canDel, isLocal, replace } = path.delInfo
309
+ const { keyPath, isLocal, replace } = path.delInfo
314
310
  delete path.delInfo
315
311
 
316
- if (canDel) {
317
- if (isLocal) { // 局部作用域里的变量,可直接删除
318
- dealRemove(path, replace)
319
- return
320
- }
321
- const data = bindingsMap.get(currentBlock)
322
- const { bindings, pBindings } = data
323
- const allBindings = Object.assign({}, pBindings, bindings)
324
-
325
- // 优先判断前缀,再判断全等
326
- if (checkPrefix(Object.keys(allBindings), keyPath) || pBindings[keyPath]) {
327
- dealRemove(path, replace)
328
- } else {
329
- const currentBlockVars = bindings[keyPath]
330
- if (currentBlockVars.length > 1) {
331
- const index = currentBlockVars.findIndex(item => !item.canDel)
332
- if (index !== -1 || currentBlockVars[0].path !== path) { // 当前block中存在不可删除的变量 || 不是第一个可删除变量,即可删除该变量
333
- dealRemove(path, replace)
334
- }
312
+ if (isLocal) { // 局部作用域里的变量,可直接删除
313
+ dealRemove(path, replace)
314
+ return
315
+ }
316
+ const data = bindingsMap.get(currentBlock)
317
+ const { bindings, pBindings } = data
318
+ const allBindings = Object.assign({}, pBindings, bindings)
319
+
320
+ // 优先判断前缀,再判断全等
321
+ if (checkPrefix(Object.keys(allBindings), keyPath) || pBindings[keyPath]) {
322
+ dealRemove(path, replace)
323
+ } else {
324
+ const currentBlockVars = bindings[keyPath] || [] // 对于只出现一次的可忽略变量,需要兜底
325
+ if (currentBlockVars.length >= 1) {
326
+ const index = currentBlockVars.findIndex(item => !item.canDel)
327
+ if (index !== -1 || currentBlockVars[0].path !== path) { // 当前block中存在不可删除的变量 || 不是第一个可删除变量,即可删除该变量
328
+ dealRemove(path, replace)
335
329
  }
336
330
  }
337
331
  }
@@ -1,3 +1,4 @@
1
+ // 该文件下的字符串语句需要使用 es5 语法
1
2
  const addQuery = require('../utils/add-query')
2
3
  const normalize = require('../utils/normalize')
3
4
  const optionProcessorPath = normalize.lib('runtime/optionProcessor')
@@ -64,18 +65,18 @@ module.exports = function (script, {
64
65
  globalTabBar
65
66
  })
66
67
 
67
- output += `\n const App = require(${stringifyRequest(loaderContext, addQuery(resource, { isApp: true }))}).default\n`
68
+ output += `\n var App = require(${stringifyRequest(loaderContext, addQuery(resource, { isApp: true }))}).default\n`
68
69
 
69
70
  output += `
70
71
  export default processAppOption({
71
- App,
72
+ App: App,
72
73
  tabBarMap: ${JSON.stringify(tabBarMap)},
73
74
  firstPage: ${JSON.stringify(firstPage)},
74
75
  pagesMap: ${shallowStringify(pagesMap)},
75
76
  componentsMap: ${shallowStringify(componentsMap)},
76
- Vue,
77
- VueRouter,
78
- webConfig: ${JSON.stringify(webConfig)}
77
+ Vue: Vue,
78
+ VueRouter: VueRouter,
79
+ el: ${JSON.stringify(webConfig.el || '#app')}
79
80
  })\n`
80
81
 
81
82
  callback(null, {
@@ -56,7 +56,7 @@ module.exports = function (script, {
56
56
  }
57
57
 
58
58
  // 获取组件集合
59
- const componentsMap = buildComponentsMap({ localComponentsMap, builtInComponentsMap, loaderContext })
59
+ const componentsMap = buildComponentsMap({ localComponentsMap, builtInComponentsMap, loaderContext, jsonConfig })
60
60
 
61
61
  // 获取pageConfig
62
62
  const pageConfig = {}
@@ -31,14 +31,27 @@ function getAsyncChunkName (chunkName) {
31
31
  return ''
32
32
  }
33
33
 
34
- function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderContext }) {
34
+ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderContext, jsonConfig }) {
35
35
  const componentsMap = {}
36
36
  if (localComponentsMap) {
37
37
  Object.keys(localComponentsMap).forEach((componentName) => {
38
38
  const componentCfg = localComponentsMap[componentName]
39
39
  const componentRequest = stringifyRequest(loaderContext, componentCfg.resource)
40
40
  if (componentCfg.async) {
41
- componentsMap[componentName] = `()=>import(${getAsyncChunkName(componentCfg.async)}${componentRequest}).then(res => getComponent(res))`
41
+ // todo 暂时只处理局部注册的组件作为componentPlaceholder,暂不支持全局组件和原生组件,如使用了支持范围外的组件将不进行placeholder渲染及替换
42
+ if (jsonConfig.componentPlaceholder && jsonConfig.componentPlaceholder[componentName] && localComponentsMap[jsonConfig.componentPlaceholder[componentName]]) {
43
+ const placeholder = jsonConfig.componentPlaceholder[componentName]
44
+ const placeholderCfg = localComponentsMap[placeholder]
45
+ const placeholderRequest = stringifyRequest(loaderContext, placeholderCfg.resource)
46
+ if (placeholderCfg.async) {
47
+ loaderContext.emitWarning(
48
+ new Error(`[json processor][${loaderContext.resource}]: componentPlaceholder ${placeholder} should not be a async component, please check!`)
49
+ )
50
+ }
51
+ componentsMap[componentName] = `function(){return {component: import(${getAsyncChunkName(componentCfg.async)}${componentRequest}).then(function(res){return getComponent(res)}), loading: getComponent(require(${placeholderRequest}))}}`
52
+ } else {
53
+ componentsMap[componentName] = `function(){return import(${getAsyncChunkName(componentCfg.async)}${componentRequest}).then(function(res){return getComponent(res)})}`
54
+ }
42
55
  } else {
43
56
  componentsMap[componentName] = `getComponent(require(${componentRequest}))`
44
57
  }
@@ -48,7 +61,7 @@ function buildComponentsMap ({ localComponentsMap, builtInComponentsMap, loaderC
48
61
  Object.keys(builtInComponentsMap).forEach((componentName) => {
49
62
  const componentCfg = builtInComponentsMap[componentName]
50
63
  const componentRequest = stringifyRequest(loaderContext, componentCfg.resource)
51
- componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
64
+ componentsMap[componentName] = `getComponent(require(${componentRequest}), {__mpxBuiltIn: true})`
52
65
  })
53
66
  }
54
67
  return componentsMap
@@ -69,13 +82,13 @@ function buildPagesMap ({ localPagesMap, loaderContext, tabBar, tabBarMap, tabBa
69
82
  if (pageCfg) {
70
83
  const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
71
84
  if (pageCfg.async) {
72
- tabBarPagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)}${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
85
+ tabBarPagesMap[pagePath] = `function(){return import(${getAsyncChunkName(pageCfg.async)}${pageRequest}).then(function(res) {return getComponent(res, {__mpxPageRoute: ${JSON.stringify(pagePath)}})})}`
73
86
  } else {
74
- tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
87
+ tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), {__mpxPageRoute: ${JSON.stringify(pagePath)}})`
75
88
  }
76
89
  } else {
77
90
  loaderContext.emitWarning(
78
- new Error('[json processor][' + loaderContext.resource + ']: ' + `TabBar page path ${pagePath} is not exist in local page map, please check!`)
91
+ new Error(`[json processor][${loaderContext.resource}]: TabBar page path ${pagePath} is not exist in local page map, please check!`)
79
92
  )
80
93
  }
81
94
  })
@@ -91,13 +104,13 @@ function buildPagesMap ({ localPagesMap, loaderContext, tabBar, tabBarMap, tabBa
91
104
  const pageCfg = localPagesMap[pagePath]
92
105
  const pageRequest = stringifyRequest(loaderContext, pageCfg.resource)
93
106
  if (tabBarMap && tabBarMap[pagePath]) {
94
- pagesMap[pagePath] = `getComponent(require(${stringifyRequest(loaderContext, tabBarContainerPath)}), { __mpxBuiltIn: true })`
107
+ pagesMap[pagePath] = `getComponent(require(${stringifyRequest(loaderContext, tabBarContainerPath)}), {__mpxBuiltIn: true})`
95
108
  } else {
96
109
  if (pageCfg.async) {
97
- pagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)} ${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
110
+ pagesMap[pagePath] = `function(){return import(${getAsyncChunkName(pageCfg.async)} ${pageRequest}).then(function(res){return getComponent(res, {__mpxPageRoute: ${JSON.stringify(pagePath)}})})}`
98
111
  } else {
99
112
  // 为了保持小程序中app->page->component的js执行顺序,所有的page和component都改为require引入
100
- pagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
113
+ pagesMap[pagePath] = `getComponent(require(${pageRequest}), {__mpxPageRoute: ${JSON.stringify(pagePath)}})`
101
114
  }
102
115
  }
103
116
 
@@ -123,7 +136,16 @@ function getRequireScript ({ ctorType, script, loaderContext }) {
123
136
  return content
124
137
  }
125
138
 
126
- function buildGlobalParams ({ moduleId, scriptSrcMode, loaderContext, isProduction, jsonConfig, webConfig, isMain, globalTabBar }) {
139
+ function buildGlobalParams ({
140
+ moduleId,
141
+ scriptSrcMode,
142
+ loaderContext,
143
+ isProduction,
144
+ jsonConfig,
145
+ webConfig,
146
+ isMain,
147
+ globalTabBar
148
+ }) {
127
149
  let content = ''
128
150
  if (isMain) {
129
151
  content += `
@@ -132,12 +154,12 @@ function buildGlobalParams ({ moduleId, scriptSrcMode, loaderContext, isProducti
132
154
  if (!(typeof window !== 'undefined')) {
133
155
  console.error('[Mpx runtime error]: Dangerous API! global.getCurrentPages is running in non browser environment, It may cause some problems, please use this method with caution')
134
156
  }
135
- const router = global.__mpxRouter
157
+ var router = global.__mpxRouter
136
158
  if(!router) return []
137
159
  // @ts-ignore
138
- return (router.lastStack || router.stack).map(item => {
139
- let page
140
- const vnode = item.vnode
160
+ return (router.lastStack || router.stack).map(function(item){
161
+ var page
162
+ var vnode = item.vnode
141
163
  if (vnode && vnode.componentInstance) {
142
164
  page = vnode.tag.endsWith('mpx-tab-bar-container') ? vnode.componentInstance.$refs.tabBarPage : vnode.componentInstance
143
165
  }
@@ -178,13 +200,13 @@ function buildI18n ({ i18n, loaderContext }) {
178
200
  delete i18nObj[`${key}Path`]
179
201
  }
180
202
  })
181
- i18nContent += ` const i18nCfg = ${JSON.stringify(i18nObj)}\n`
203
+ i18nContent += ` var i18nCfg = ${JSON.stringify(i18nObj)}\n`
182
204
  Object.keys(requestObj).forEach((key) => {
183
205
  i18nContent += ` i18nCfg.${key} = require(${requestObj[key]})\n`
184
206
  })
185
207
  i18nContent += `
186
208
  i18nCfg.legacy = false
187
- const i18n = createI18n(i18nCfg, VueI18n)
209
+ var i18n = createI18n(i18nCfg, VueI18n)
188
210
  Vue.use(i18n)
189
211
  Mpx.i18n = i18n\n`
190
212
  return i18nContent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.11-test.0",
3
+ "version": "2.9.13",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -83,5 +83,5 @@
83
83
  "engines": {
84
84
  "node": ">=14.14.0"
85
85
  },
86
- "gitHead": "d244d661acb081b709fc99ca8f6add541f793877"
86
+ "gitHead": "2c67b32fe01ff15fc1b728f91b4b5652244c2f35"
87
87
  }
@@ -1,19 +0,0 @@
1
- function promisify (obj = {}, callback) {
2
- return new Promise((resolve, reject) => {
3
- const originSuccess = obj.success
4
- const originFail = obj.fail
5
- obj.success = function (res) {
6
- originSuccess && originSuccess.call(this, res)
7
- resolve(res)
8
- }
9
- obj.fail = function (e) {
10
- originFail && originFail.call(this, e)
11
- reject(e)
12
- }
13
- if (callback) {
14
- callback(obj)
15
- }
16
- })
17
- }
18
-
19
- export default promisify