@mpxjs/webpack-plugin 2.8.42 → 2.9.0-beta.1

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.
@@ -24,8 +24,9 @@ function objectKeys (obj) {
24
24
  var shift = false
25
25
  for (var i = 1; i < objStr.length - 1; i++) {
26
26
  var item = objStr[i]
27
+ var lastItem = objStr[i - 1]
27
28
  if (inKey) {
28
- if (item === ':') {
29
+ if (item === ':' && lastItem === '"') {
29
30
  keys.push(key.slice(1, -1))
30
31
  key = ''
31
32
  inKey = false
@@ -93,18 +94,53 @@ function isDef (v) {
93
94
  return v !== undefined && v !== null
94
95
  }
95
96
 
97
+ var escapeMap = {
98
+ '(': '_pl_',
99
+ ')': '_pr_',
100
+ '[': '_bl_',
101
+ ']': '_br_',
102
+ '{': '_cl_',
103
+ '#': '_h_',
104
+ '!': '_i_',
105
+ '/': '_s_',
106
+ '.': '_d_',
107
+ ':': '_c_',
108
+ ',': '_2c_',
109
+ '%': '_p_',
110
+ // wxs can not use '\'' as key
111
+ // wxs环境中'\''!=="'",此文件不能格式化,否则会导致程序错误
112
+ "'": '_q_',
113
+ // wxs can not use '"' as key
114
+ '"': '_dq_',
115
+ '+': '_a_',
116
+ '$': '_si_'
117
+ }
118
+
119
+ var escapeReg = genRegExp('[()[\]{}#!/.:,%\'"+$]', 'g')
120
+
121
+ function mpEscape (str) {
122
+ return str.replace(escapeReg, function (match) {
123
+ if (escapeMap[match]) return escapeMap[match]
124
+ // fix wxs can not use '}' as key
125
+ if (match === '}') return '_cr_'
126
+ // unknown escaped
127
+ return '_u_'
128
+ })
129
+ }
130
+
131
+
96
132
  function stringifyDynamicClass (value) {
97
- if (!value) return ''
98
133
  if (isArray(value)) {
99
- return stringifyArray(value)
100
- }
101
- if (isObject(value)) {
102
- return stringifyObject(value)
134
+ value = stringifyArray(value)
135
+ } else if (isObject(value)) {
136
+ value = stringifyObject(value)
103
137
  }
138
+
104
139
  if (typeof value === 'string') {
105
- return value
140
+ return mpEscape(value)
141
+ } else {
142
+ return ''
106
143
  }
107
- return ''
108
144
  }
109
145
 
110
146
  function stringifyArray (value) {
@@ -762,7 +762,7 @@ function parse (template, options) {
762
762
  },
763
763
  comment: function comment (text) {
764
764
  if (!currentParent) genTempRoot()
765
- if (options.hasComment) {
765
+ if (options.hasComment || /mpx_config_/.test(text)) {
766
766
  currentParent.children.push({
767
767
  type: 3,
768
768
  text: text,
@@ -967,7 +967,7 @@ function processComponentIs (el, options) {
967
967
 
968
968
  const is = getAndRemoveAttr(el, 'is').val
969
969
  if (is) {
970
- el.is = parseMustache(is).result
970
+ el.is = parseMustacheWithContext(is).result
971
971
  } else {
972
972
  warn$1('<component> tag should have attrs[is].')
973
973
  }
@@ -979,7 +979,7 @@ function parseFuncStr2 (str) {
979
979
  const funcRE = /^([^()]+)(\((.*)\))?/
980
980
  const match = funcRE.exec(str)
981
981
  if (match) {
982
- const funcName = parseMustache(match[1]).result
982
+ const funcName = parseMustacheWithContext(match[1]).result
983
983
  const hasArgs = !!match[2]
984
984
  let args = match[3] ? `,${match[3]}` : ''
985
985
  const ret = /(,|^)\s*(\$event)\s*(,|$)/.exec(args)
@@ -1163,19 +1163,9 @@ function wrapMustache (val) {
1163
1163
  return val && !tagRE.test(val) ? `{{${val}}}` : val
1164
1164
  }
1165
1165
 
1166
- function parseMustache (raw = '') {
1167
- let replaced = false
1168
- if (tagRE.test(raw)) {
1169
- const ret = []
1170
- let lastLastIndex = 0
1171
- let match
1172
- while (match = tagREG.exec(raw)) {
1173
- const pre = raw.substring(lastLastIndex, match.index)
1174
- if (pre) {
1175
- ret.push(stringify(pre))
1176
- }
1177
- let exp = match[1]
1178
-
1166
+ function parseMustacheWithContext (raw = '') {
1167
+ return parseMustache(raw, (exp) => {
1168
+ if (defs) {
1179
1169
  // eval处理的话,和别的判断条件,比如运行时的判断混用情况下得不到一个结果,还是正则替换
1180
1170
  const defKeys = Object.keys(defs)
1181
1171
  defKeys.forEach((defKey) => {
@@ -1183,42 +1173,70 @@ function parseMustache (raw = '') {
1183
1173
  const defREG = new RegExp(`\\b${defKey}\\b`, 'g')
1184
1174
  if (defRE.test(exp)) {
1185
1175
  exp = exp.replace(defREG, stringify(defs[defKey]))
1186
- replaced = true
1187
1176
  }
1188
1177
  })
1178
+ }
1189
1179
 
1190
- if (i18n) {
1191
- for (const i18nFuncName of i18nFuncNames) {
1192
- const funcNameRE = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`)
1193
- const funcNameREG = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`, 'g')
1194
- if (funcNameRE.test(exp)) {
1195
- if (i18n.useComputed || !i18nFuncName.startsWith('\\$')) {
1196
- const i18nInjectComputedKey = `_i${i18nInjectableComputed.length + 1}`
1197
- i18nInjectableComputed.push(`${i18nInjectComputedKey} () {\nreturn ${exp.trim()}}`)
1198
- exp = i18nInjectComputedKey
1199
- } else {
1200
- exp = exp.replace(funcNameREG, `${i18nModuleName}.$1(null, _l, _fl, `)
1201
- }
1202
- hasI18n = true
1203
- replaced = true
1204
- break
1180
+ if (i18n) {
1181
+ for (const i18nFuncName of i18nFuncNames) {
1182
+ const funcNameRE = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`)
1183
+ const funcNameREG = new RegExp(`(?<![A-Za-z0-9_$.])${i18nFuncName}\\(`, 'g')
1184
+ if (funcNameRE.test(exp)) {
1185
+ if (i18n.useComputed || !i18nFuncName.startsWith('\\$')) {
1186
+ const i18nInjectComputedKey = `_i${i18nInjectableComputed.length + 1}`
1187
+ i18nInjectableComputed.push(`${i18nInjectComputedKey} () {\nreturn ${exp.trim()}}`)
1188
+ exp = i18nInjectComputedKey
1189
+ } else {
1190
+ exp = exp.replace(funcNameREG, `${i18nModuleName}.$1(null, _l, _fl, `)
1205
1191
  }
1192
+ hasI18n = true
1193
+ break
1206
1194
  }
1207
1195
  }
1196
+ }
1197
+
1198
+ return exp
1199
+ })
1200
+ }
1201
+
1202
+ function parseMustache (raw = '', expHandler = exp => exp, strHandler = str => str) {
1203
+ let replaced = false
1204
+ if (tagRE.test(raw)) {
1205
+ const ret = []
1206
+ let lastLastIndex = 0
1207
+ let match
1208
+ while (match = tagREG.exec(raw)) {
1209
+ const pre = raw.substring(lastLastIndex, match.index)
1210
+ if (pre) {
1211
+ const pre2 = strHandler(pre)
1212
+ if (pre2 !== pre) replaced = true
1213
+ if (pre2) ret.push(stringify(pre2))
1214
+ }
1215
+
1216
+ const exp = match[1].trim()
1217
+ if (exp) {
1218
+ const exp2 = expHandler(exp)
1219
+ if (exp2 !== exp) replaced = true
1220
+ if (exp2) ret.push(`(${exp2})`)
1221
+ }
1208
1222
 
1209
- ret.push(`(${exp.trim()})`)
1210
1223
  lastLastIndex = tagREG.lastIndex
1211
1224
  }
1225
+
1212
1226
  const post = raw.substring(lastLastIndex)
1213
1227
  if (post) {
1214
- ret.push(stringify(post))
1228
+ const post2 = strHandler(post)
1229
+ if (post2 !== post) replaced = true
1230
+ if (post2) ret.push(stringify(post2))
1215
1231
  }
1232
+
1216
1233
  let result
1217
1234
  if (ret.length === 1) {
1218
1235
  result = ret[0]
1219
1236
  } else {
1220
1237
  result = `(${ret.join('+')})`
1221
1238
  }
1239
+
1222
1240
  return {
1223
1241
  result,
1224
1242
  hasBinding: true,
@@ -1226,10 +1244,14 @@ function parseMustache (raw = '') {
1226
1244
  replaced
1227
1245
  }
1228
1246
  }
1247
+
1248
+ const raw2 = strHandler(raw)
1249
+ if (raw2 !== raw) replaced = true
1250
+
1229
1251
  return {
1230
- result: stringify(raw),
1252
+ result: stringify(raw2),
1231
1253
  hasBinding: false,
1232
- val: raw,
1254
+ val: raw2,
1233
1255
  replaced
1234
1256
  }
1235
1257
  }
@@ -1247,14 +1269,14 @@ function processIf (el) {
1247
1269
  let val = getAndRemoveAttr(el, config[mode].directive.if).val
1248
1270
  if (val) {
1249
1271
  if (mode === 'swan') val = wrapMustache(val)
1250
- const parsed = parseMustache(val)
1272
+ const parsed = parseMustacheWithContext(val)
1251
1273
  el.if = {
1252
1274
  raw: parsed.val,
1253
1275
  exp: parsed.result
1254
1276
  }
1255
1277
  } else if (val = getAndRemoveAttr(el, config[mode].directive.elseif).val) {
1256
1278
  if (mode === 'swan') val = wrapMustache(val)
1257
- const parsed = parseMustache(val)
1279
+ const parsed = parseMustacheWithContext(val)
1258
1280
  el.elseif = {
1259
1281
  raw: parsed.val,
1260
1282
  exp: parsed.result
@@ -1296,7 +1318,7 @@ function processFor (el) {
1296
1318
  }
1297
1319
  } else {
1298
1320
  if (mode === 'swan') val = wrapMustache(val)
1299
- const parsed = parseMustache(val)
1321
+ const parsed = parseMustacheWithContext(val)
1300
1322
  el.for = {
1301
1323
  raw: parsed.val,
1302
1324
  exp: parsed.result
@@ -1408,14 +1430,14 @@ function processAttrs (el, options) {
1408
1430
  const isTemplateData = el.tag === 'template' && attr.name === 'data'
1409
1431
  const needWrap = isTemplateData && mode !== 'swan'
1410
1432
  const value = needWrap ? `{${attr.value}}` : attr.value
1411
- const parsed = parseMustache(value)
1433
+ const parsed = parseMustacheWithContext(value)
1412
1434
  if (parsed.hasBinding) {
1413
1435
  // 该属性判断用于提供给运行时对于计算属性作为props传递时提出警告
1414
1436
  const isProps = isComponentNode(el, options) && !(attr.name === 'class' || attr.name === 'style')
1415
1437
  addExp(el, parsed.result, isProps)
1416
- }
1417
- if (parsed.replaced) {
1418
- modifyAttr(el, attr.name, needWrap ? parsed.val.slice(1, -1) : parsed.val)
1438
+ if (parsed.replaced) {
1439
+ modifyAttr(el, attr.name, needWrap ? parsed.val.slice(1, -1) : parsed.val)
1440
+ }
1419
1441
  }
1420
1442
  })
1421
1443
  }
@@ -1547,7 +1569,7 @@ function processText (el) {
1547
1569
  if (el.type !== 3 || el.isComment) {
1548
1570
  return
1549
1571
  }
1550
- const parsed = parseMustache(el.text)
1572
+ const parsed = parseMustacheWithContext(el.text)
1551
1573
  if (parsed.hasBinding) {
1552
1574
  addExp(el, parsed.result)
1553
1575
  }
@@ -1592,8 +1614,8 @@ function processClass (el, meta) {
1592
1614
  let staticClass = getAndRemoveAttr(el, type).val || ''
1593
1615
  staticClass = staticClass.replace(/\s+/g, ' ')
1594
1616
  if (dynamicClass) {
1595
- const staticClassExp = parseMustache(staticClass).result
1596
- const dynamicClassExp = transDynamicClassExpr(parseMustache(dynamicClass).result, {
1617
+ const staticClassExp = parseMustacheWithContext(staticClass).result
1618
+ const dynamicClassExp = transDynamicClassExpr(parseMustacheWithContext(dynamicClass).result, {
1597
1619
  error: error$1
1598
1620
  })
1599
1621
  addAttrs(el, [{
@@ -1628,8 +1650,8 @@ function processStyle (el, meta) {
1628
1650
  let staticStyle = getAndRemoveAttr(el, type).val || ''
1629
1651
  staticStyle = staticStyle.replace(/\s+/g, ' ')
1630
1652
  if (dynamicStyle) {
1631
- const staticStyleExp = parseMustache(staticStyle).result
1632
- const dynamicStyleExp = parseMustache(dynamicStyle).result
1653
+ const staticStyleExp = parseMustacheWithContext(staticStyle).result
1654
+ const dynamicStyleExp = parseMustacheWithContext(dynamicStyle).result
1633
1655
  addAttrs(el, [{
1634
1656
  name: targetType,
1635
1657
  value: `{{${stringifyModuleName}.stringifyStyle(${staticStyleExp}, ${dynamicStyleExp})}}`
@@ -1870,7 +1892,7 @@ function processShow (el, options, root) {
1870
1892
  if (options.hasVirtualHost) {
1871
1893
  if (options.isComponent && el.parent === root && isRealNode(el)) {
1872
1894
  if (show !== undefined) {
1873
- show = `{{${parseMustache(show).result}&&mpxShow}}`
1895
+ show = `{{${parseMustacheWithContext(show).result}&&mpxShow}}`
1874
1896
  } else {
1875
1897
  show = '{{mpxShow}}'
1876
1898
  }
@@ -1892,7 +1914,7 @@ function processShow (el, options, root) {
1892
1914
 
1893
1915
  function processShowStyle () {
1894
1916
  if (show !== undefined) {
1895
- const showExp = parseMustache(show).result
1917
+ const showExp = parseMustacheWithContext(show).result
1896
1918
  let oldStyle = getAndRemoveAttr(el, 'style').val
1897
1919
  oldStyle = oldStyle ? oldStyle + ';' : ''
1898
1920
  addAttrs(el, [{
@@ -2376,6 +2398,7 @@ module.exports = {
2376
2398
  makeAttrsMap,
2377
2399
  stringifyAttr,
2378
2400
  parseMustache,
2401
+ parseMustacheWithContext,
2379
2402
  stringifyWithResolveComputed,
2380
2403
  addAttrs
2381
2404
  }
@@ -1,10 +1,9 @@
1
1
  module.exports = (loaders, loaderIndex) => {
2
- for (let len = loaders.length; len > 0; --len) {
3
- const currentLoader = loaders[len - 1]
2
+ for (let i = loaderIndex; i >= 0; i--) {
3
+ const currentLoader = loaders[i]
4
4
  if (currentLoader.path.endsWith('ts-loader/dist/stringify-loader.js')) {
5
- break
5
+ return i
6
6
  }
7
- loaderIndex--
8
7
  }
9
8
  return loaderIndex
10
9
  }
@@ -0,0 +1,56 @@
1
+ const addQuery = require('../utils/add-query')
2
+ const normalize = require('../utils/normalize')
3
+ const optionProcessorPath = normalize.lib('runtime/optionProcessor')
4
+ const { buildComponentsMap, buildPagesMap, buildGlobalParams, shallowStringify, stringifyRequest, buildI18n } = require('./script-helper')
5
+
6
+ module.exports = function (script, {
7
+ loaderContext,
8
+ ctorType,
9
+ srcMode,
10
+ moduleId,
11
+ isProduction,
12
+ jsonConfig,
13
+ localComponentsMap,
14
+ tabBar,
15
+ tabBarMap,
16
+ tabBarStr,
17
+ localPagesMap,
18
+ resource
19
+ }, callback) {
20
+ const { i18n, webConfig } = loaderContext.getMpx()
21
+
22
+ const { pagesMap, firstPage, globalTabBar } = buildPagesMap({ localPagesMap, loaderContext, tabBar, tabBarMap, tabBarStr })
23
+
24
+ const componentsMap = buildComponentsMap({ localComponentsMap, loaderContext })
25
+
26
+ const scriptSrcMode = script ? script.mode || srcMode : srcMode
27
+
28
+ let output = `\n import { processAppOption, getComponent } from ${stringifyRequest(loaderContext, optionProcessorPath)}
29
+ import '@mpxjs/webpack-plugin/lib/runtime/base.styl'
30
+ import Vue from 'vue'
31
+ import VueRouter from 'vue-router'
32
+ import Mpx from '@mpxjs/core'
33
+ import App from ${stringifyRequest(loaderContext, addQuery(resource, { isApp: true }))}
34
+ Vue.use(VueRouter)
35
+ \n`
36
+
37
+ if (i18n) {
38
+ output += buildI18n({ i18n, loaderContext })
39
+ }
40
+
41
+ output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, jsonConfig, webConfig, isMain: true, globalTabBar })
42
+ output += `export default processAppOption({
43
+ App,
44
+ tabBarMap: ${JSON.stringify(tabBarMap)},
45
+ firstPage: ${JSON.stringify(firstPage)},
46
+ pagesMap: ${shallowStringify(pagesMap)},
47
+ componentsMap: ${shallowStringify(componentsMap)},
48
+ Vue,
49
+ VueRouter,
50
+ webConfig: ${JSON.stringify(webConfig)}
51
+ })`
52
+
53
+ callback(null, {
54
+ output
55
+ })
56
+ }
@@ -1,33 +1,8 @@
1
1
  const genComponentTag = require('../utils/gen-component-tag')
2
2
  const loaderUtils = require('loader-utils')
3
- const addQuery = require('../utils/add-query')
4
3
  const normalize = require('../utils/normalize')
5
- const hasOwn = require('../utils/has-own')
6
- const createHelpers = require('../helpers')
7
4
  const optionProcessorPath = normalize.lib('runtime/optionProcessor')
8
- const tabBarContainerPath = normalize.lib('runtime/components/web/mpx-tab-bar-container.vue')
9
- const tabBarPath = normalize.lib('runtime/components/web/mpx-tab-bar.vue')
10
-
11
- function shallowStringify (obj) {
12
- const arr = []
13
- for (const key in obj) {
14
- if (hasOwn(obj, key)) {
15
- let value = obj[key]
16
- if (Array.isArray(value)) {
17
- value = `[${value.join(',')}]`
18
- }
19
- arr.push(`'${key}':${value}`)
20
- }
21
- }
22
- return `{${arr.join(',')}}`
23
- }
24
-
25
- function getAsyncChunkName (chunkName) {
26
- if (chunkName && typeof chunkName !== 'boolean') {
27
- return `/* webpackChunkName: "${chunkName}" */`
28
- }
29
- return ''
30
- }
5
+ const { buildComponentsMap, getRequireScript, buildGlobalParams, shallowStringify } = require('./script-helper')
31
6
 
32
7
  module.exports = function (script, {
33
8
  loaderContext,
@@ -38,50 +13,14 @@ module.exports = function (script, {
38
13
  componentGenerics,
39
14
  jsonConfig,
40
15
  outputPath,
41
- tabBarMap,
42
- tabBarStr,
43
16
  builtInComponentsMap,
44
17
  genericsInfo,
45
18
  wxsModuleMap,
46
- localComponentsMap,
47
- localPagesMap
19
+ localComponentsMap
48
20
  }, callback) {
49
- const {
50
- i18n,
51
- projectRoot,
52
- webConfig,
53
- appInfo
54
- } = loaderContext.getMpx()
55
- const { getRequire } = createHelpers(loaderContext)
56
- const tabBar = jsonConfig.tabBar
57
-
58
- const emitWarning = (msg) => {
59
- loaderContext.emitWarning(
60
- new Error('[script processor][' + loaderContext.resource + ']: ' + msg)
61
- )
62
- }
21
+ const { projectRoot, appInfo } = loaderContext.getMpx()
63
22
 
64
23
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
65
- const tabBarPagesMap = {}
66
- if (tabBar && tabBarMap) {
67
- // 挂载tabBar组件
68
- const tabBarRequest = stringifyRequest(addQuery(tabBar.custom ? './custom-tab-bar/index' : tabBarPath, { isComponent: true }))
69
- tabBarPagesMap['mpx-tab-bar'] = `getComponent(require(${tabBarRequest}))`
70
- // 挂载tabBar页面
71
- Object.keys(tabBarMap).forEach((pagePath) => {
72
- const pageCfg = localPagesMap[pagePath]
73
- if (pageCfg) {
74
- const pageRequest = stringifyRequest(pageCfg.resource)
75
- if (pageCfg.async) {
76
- tabBarPagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)}${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
77
- } else {
78
- tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
79
- }
80
- } else {
81
- emitWarning(`TabBar page path ${pagePath} is not exist in local page map, please check!`)
82
- }
83
- })
84
- }
85
24
 
86
25
  let output = '/* script */\n'
87
26
 
@@ -101,58 +40,7 @@ module.exports = function (script, {
101
40
  return attrs
102
41
  },
103
42
  content (script) {
104
- let content = `\n import processOption, { getComponent, getWxsMixin } from ${stringifyRequest(optionProcessorPath)}\n`
105
- // add import
106
- if (ctorType === 'app') {
107
- content += ` import '@mpxjs/webpack-plugin/lib/runtime/base.styl'
108
- import Vue from 'vue'
109
- import VueRouter from 'vue-router'
110
- import Mpx from '@mpxjs/core'
111
- Vue.use(VueRouter)
112
- global.getApp = function(){}
113
- global.getCurrentPages = function(){
114
- if(!global.__mpxRouter) return []
115
- // @ts-ignore
116
- return global.__mpxRouter.stack.map(item => {
117
- let page
118
- const vnode = item.vnode
119
- if(vnode && vnode.componentInstance) {
120
- page = vnode.tag.endsWith('mpx-tab-bar-container') ? vnode.componentInstance.$refs.tabBarPage : vnode.componentInstance
121
- }
122
- return page || { route: item.path.slice(1) }
123
- })
124
- }
125
- global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
126
- global.__mpxGenericsMap = {}
127
- global.__mpxOptionsMap = {}
128
- global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
129
- global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}
130
- global.__mpxTransRpxFn = ${webConfig.transRpxFn}\n`
131
- if (i18n) {
132
- const i18nObj = Object.assign({}, i18n)
133
- content += ` import VueI18n from 'vue-i18n'
134
- import { createI18n } from 'vue-i18n-bridge'
135
-
136
- Vue.use(VueI18n , { bridge: true })\n`
137
- const requestObj = {}
138
- const i18nKeys = ['messages', 'dateTimeFormats', 'numberFormats']
139
- i18nKeys.forEach((key) => {
140
- if (i18nObj[`${key}Path`]) {
141
- requestObj[key] = stringifyRequest(i18nObj[`${key}Path`])
142
- delete i18nObj[`${key}Path`]
143
- }
144
- })
145
- content += ` const i18nCfg = ${JSON.stringify(i18nObj)}\n`
146
- Object.keys(requestObj).forEach((key) => {
147
- content += ` i18nCfg.${key} = require(${requestObj[key]})\n`
148
- })
149
- content += ' i18nCfg.legacy = false\n'
150
- content += ` const i18n = createI18n(i18nCfg, VueI18n)
151
- Vue.use(i18n)
152
- Mpx.i18n = i18n
153
- \n`
154
- }
155
- }
43
+ let content = `\n import processComponentOption, { getComponent, getWxsMixin } from ${stringifyRequest(optionProcessorPath)}\n`
156
44
  let hasApp = true
157
45
  if (!appInfo.name) {
158
46
  hasApp = false
@@ -166,63 +54,10 @@ module.exports = function (script, {
166
54
  content += ` wxsModules.${module} = ${expression}\n`
167
55
  })
168
56
  }
169
- let firstPage = ''
170
- const pagesMap = {}
171
- const componentsMap = {}
172
- Object.keys(localPagesMap).forEach((pagePath) => {
173
- const pageCfg = localPagesMap[pagePath]
174
- const pageRequest = stringifyRequest(pageCfg.resource)
175
- if (tabBarMap && tabBarMap[pagePath]) {
176
- pagesMap[pagePath] = `getComponent(require(${stringifyRequest(tabBarContainerPath)}), { __mpxBuiltIn: true })`
177
- } else {
178
- if (pageCfg.async) {
179
- pagesMap[pagePath] = `()=>import(${getAsyncChunkName(pageCfg.async)} ${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
180
- } else {
181
- // 为了保持小程序中app->page->component的js执行顺序,所有的page和component都改为require引入
182
- pagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
183
- }
184
- }
185
57
 
186
- if (pageCfg.isFirst) {
187
- firstPage = pagePath
188
- }
189
- })
190
-
191
- Object.keys(localComponentsMap).forEach((componentName) => {
192
- const componentCfg = localComponentsMap[componentName]
193
- const componentRequest = stringifyRequest(componentCfg.resource)
194
- if (componentCfg.async) {
195
- componentsMap[componentName] = `()=>import(${getAsyncChunkName(componentCfg.async)}${componentRequest}).then(res => getComponent(res))`
196
- } else {
197
- componentsMap[componentName] = `getComponent(require(${componentRequest}))`
198
- }
199
- })
200
-
201
- Object.keys(builtInComponentsMap).forEach((componentName) => {
202
- const componentCfg = builtInComponentsMap[componentName]
203
- const componentRequest = stringifyRequest(componentCfg.resource)
204
- componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
205
- })
206
-
207
- content += ` global.currentModuleId = ${JSON.stringify(moduleId)}\n`
208
- content += ` global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
209
- content += ` global.currentInject = ${JSON.stringify({ moduleId })}\n`
210
- if (!isProduction) {
211
- content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
212
- }
58
+ // 获取组件集合
59
+ const componentsMap = buildComponentsMap({ localComponentsMap, builtInComponentsMap, loaderContext })
213
60
 
214
- content += ' /** script content **/\n'
215
-
216
- // 传递ctorType以补全js内容
217
- const extraOptions = {
218
- ctorType,
219
- lang: script.lang || 'js'
220
- }
221
- // todo 仅靠vueContentCache保障模块唯一性还是不够严谨,后续需要考虑去除原始query后构建request
222
- content += ` ${getRequire('script', script, extraOptions)}\n`
223
-
224
- // createApp/Page/Component执行完成后立刻获取当前的option并暂存
225
- content += ` const currentOption = global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
226
61
  // 获取pageConfig
227
62
  const pageConfig = {}
228
63
  if (ctorType === 'page') {
@@ -237,36 +72,21 @@ module.exports = function (script, {
237
72
  pageConfig[key] = jsonConfig[key]
238
73
  })
239
74
  }
240
- // 为了执行顺序正确,tabBarPagesMap在app逻辑执行完成后注入,保障小程序中app->page->component的js执行顺序
241
- if (tabBarStr && tabBarPagesMap) {
242
- content += ` global.__tabBar = ${tabBarStr}
243
- Vue.observable(global.__tabBar)
244
- // @ts-ignore
245
- global.__tabBarPagesMap = ${shallowStringify(tabBarPagesMap)}\n`
246
- }
247
- // 配置平台转换通过createFactory在core中convertor中定义和进行
248
- // 通过processOption进行组件注册和路由注入
249
- content += ` export default processOption(
250
- currentOption,
251
- ${JSON.stringify(ctorType)},
252
- ${JSON.stringify(firstPage)},
253
- ${JSON.stringify(outputPath)},
254
- ${JSON.stringify(pageConfig)},
255
- // @ts-ignore
256
- ${shallowStringify(pagesMap)},
75
+
76
+ content += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction })
77
+ content += getRequireScript({ ctorType, script, loaderContext })
78
+ content += ` export default processComponentOption({
79
+ option: global.__mpxOptionsMap[${JSON.stringify(moduleId)}],
80
+ ctorType: ${JSON.stringify(ctorType)},
81
+ outputPath: ${JSON.stringify(outputPath)},
82
+ pageConfig: ${JSON.stringify(pageConfig)},
257
83
  // @ts-ignore
258
- ${shallowStringify(componentsMap)},
259
- ${JSON.stringify(tabBarMap)},
260
- ${JSON.stringify(componentGenerics)},
261
- ${JSON.stringify(genericsInfo)},
262
- getWxsMixin(wxsModules),
263
- ${hasApp}`
264
- if (ctorType === 'app') {
265
- content += `,
266
- Vue,
267
- VueRouter`
268
- }
269
- content += '\n )\n'
84
+ componentsMap: ${shallowStringify(componentsMap)},
85
+ componentGenerics: ${JSON.stringify(componentGenerics)},
86
+ genericsInfo: ${JSON.stringify(genericsInfo)},
87
+ mixin: getWxsMixin(wxsModules),
88
+ hasApp: ${hasApp}`
89
+ content += '\n })\n'
270
90
  return content
271
91
  }
272
92
  })
@@ -38,7 +38,8 @@ module.exports = function (template, {
38
38
  wxsContentMap,
39
39
  decodeHTMLText,
40
40
  externalClasses,
41
- checkUsingComponents
41
+ checkUsingComponents,
42
+ webConfig
42
43
  // autoVirtualHostRules
43
44
  } = mpx
44
45
  const { resourcePath } = parseRequest(loaderContext.resource)
@@ -48,9 +49,11 @@ module.exports = function (template, {
48
49
  let output = '/* template */\n'
49
50
 
50
51
  if (ctorType === 'app') {
52
+ const { el } = webConfig
53
+ const idName = el?.match(/#(.*)/)?.[1] || 'app'
51
54
  template = {
52
55
  tag: 'template',
53
- content: '<div class="app"><mpx-keep-alive><router-view class="page"></router-view></mpx-keep-alive></div>'
56
+ content: `<div id="${idName}" class="app"><mpx-keep-alive><router-view class="page"></router-view></mpx-keep-alive></div>`
54
57
  }
55
58
  builtInComponentsMap['mpx-keep-alive'] = {
56
59
  resource: addQuery('@mpxjs/webpack-plugin/lib/runtime/components/web/mpx-keep-alive.vue', { isComponent: true })