@mpxjs/webpack-plugin 2.9.37 → 2.9.39

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.
@@ -0,0 +1,13 @@
1
+ const uselessAttrs = ['parent', 'exps', 'unary', 'attrsMap']
2
+ const uselessArrAttrs = ['children', 'attrsList']
3
+
4
+ function stringify (ast) {
5
+ return JSON.stringify(ast, (k, v) => {
6
+ if (uselessAttrs.includes(k)) return undefined
7
+ if (uselessArrAttrs.includes(k) && v && !v.length) return undefined
8
+ if (k === 'tag' && v === 'temp-node') return 'block'
9
+ return v
10
+ })
11
+ }
12
+
13
+ module.exports.stringify = stringify
@@ -3,6 +3,10 @@ const bindThis = require('./bind-this')
3
3
  const parseRequest = require('../utils/parse-request')
4
4
  const { matchCondition } = require('../utils/match-condition')
5
5
  const loaderUtils = require('loader-utils')
6
+ const { MPX_DISABLE_EXTRACTOR_CACHE } = require('../utils/const')
7
+ const RecordRuntimeInfoDependency = require('../dependencies/RecordRuntimeInfoDependency')
8
+ const { createTemplateEngine, createSetupTemplate } = require('@mpxjs/template-engine')
9
+ const { stringify } = require('./dynamic')
6
10
 
7
11
  module.exports = function (raw) {
8
12
  this.cacheable()
@@ -18,15 +22,15 @@ module.exports = function (raw) {
18
22
  const globalSrcMode = mpx.srcMode
19
23
  const localSrcMode = queryObj.mode
20
24
  const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
21
- const componentsMap = mpx.componentsMap[packageName]
22
- const pagesMap = mpx.pagesMap
23
25
  const wxsContentMap = mpx.wxsContentMap
24
26
  const optimizeRenderRules = mpx.optimizeRenderRules
25
27
  const usingComponents = queryObj.usingComponents || []
26
28
  const componentPlaceholder = queryObj.componentPlaceholder || []
27
29
  const hasComment = queryObj.hasComment
28
30
  const isNative = queryObj.isNative
31
+ const ctorType = queryObj.ctorType
29
32
  const hasScoped = queryObj.hasScoped
33
+ const runtimeCompile = queryObj.isDynamic
30
34
  const moduleId = queryObj.moduleId || '_' + mpx.pathHash(resourcePath)
31
35
 
32
36
  let optimizeRenderLevel = 0
@@ -51,12 +55,12 @@ module.exports = function (raw) {
51
55
  const { root: ast, meta } = compiler.parse(raw, {
52
56
  warn,
53
57
  error,
58
+ runtimeCompile,
54
59
  usingComponents,
55
60
  componentPlaceholder,
56
61
  hasComment,
57
62
  isNative,
58
- isComponent: !!componentsMap[resourcePath],
59
- isPage: !!pagesMap[resourcePath],
63
+ ctorType,
60
64
  mode,
61
65
  env,
62
66
  srcMode: localSrcMode || globalSrcMode,
@@ -70,7 +74,7 @@ module.exports = function (raw) {
70
74
  i18n,
71
75
  checkUsingComponents: matchCondition(resourcePath, mpx.checkUsingComponentsRules),
72
76
  globalComponents: Object.keys(mpx.usingComponents),
73
- forceProxyEvent: matchCondition(resourcePath, mpx.forceProxyEventRules),
77
+ forceProxyEvent: matchCondition(resourcePath, mpx.forceProxyEventRules) || runtimeCompile,
74
78
  hasVirtualHost: matchCondition(resourcePath, mpx.autoVirtualHostRules)
75
79
  })
76
80
 
@@ -80,7 +84,7 @@ module.exports = function (raw) {
80
84
  }
81
85
  }
82
86
 
83
- const result = compiler.serialize(ast)
87
+ let result = runtimeCompile ? '' : compiler.serialize(ast)
84
88
 
85
89
  if (isNative) {
86
90
  return result
@@ -98,7 +102,11 @@ global.currentInject = {
98
102
  moduleId: ${JSON.stringify(moduleId)}
99
103
  };\n`
100
104
 
101
- const rawCode = compiler.genNode(ast)
105
+ if (runtimeCompile || queryObj.dynamicRuntime) {
106
+ resultSource += 'global.currentInject.dynamic = true;\n'
107
+ }
108
+
109
+ const rawCode = runtimeCompile ? '' : compiler.genNode(ast)
102
110
  if (rawCode) {
103
111
  try {
104
112
  const ignoreMap = Object.assign({
@@ -160,5 +168,26 @@ global.currentInject.getRefsData = function () {
160
168
  extractedResultSource: resultSource
161
169
  })
162
170
 
171
+ if (queryObj.mpxCustomElement) {
172
+ this.cacheable(false)
173
+ const templateEngine = createTemplateEngine(mpx.mode)
174
+ result += `${createSetupTemplate()}\n` + templateEngine.buildTemplate(mpx.getPackageInjectedTemplateConfig(packageName))
175
+ }
176
+
177
+ // 运行时编译的组件直接返回基础模板的内容,并产出动态文本内容
178
+ if (runtimeCompile) {
179
+ // 包含了运行时组件的template模块必须每次都创建(但并不是每次都需要build),用于收集组件节点信息,传递信息以禁用父级extractor的缓存
180
+ this.emitFile(MPX_DISABLE_EXTRACTOR_CACHE, '', undefined, { skipEmit: true })
181
+
182
+ const templateInfo = {
183
+ templateAst: stringify(ast),
184
+ ...meta.runtimeInfo
185
+ }
186
+
187
+ // 以 package 为维度存储,meta 上的数据也只是存储了这个组件的 template 上获取的信息,需要在 dependency 里面再次进行合并操作
188
+ this._module.addPresentationalDependency(new RecordRuntimeInfoDependency(packageName, resourcePath, { type: 'template', info: templateInfo }))
189
+ // 运行时组件的模版直接返回空,在生成模版静态文件的时候(beforeModuleAssets)再动态注入
190
+ }
191
+
163
192
  return result
164
193
  }
@@ -0,0 +1,148 @@
1
+ // todo 待讨论 parser + interpreter 的部分是否需要单独抽个 package 出去
2
+ const acorn = require('acorn')
3
+ const walk = require('acorn-walk')
4
+
5
+ /**
6
+ * 基于目前小程序所支持的模版语法实现,对于不支持的语法在编译阶段直接报错
7
+ */
8
+
9
+ const NODE_TYPE = {
10
+ Program: 1,
11
+ Identifier: 2,
12
+ Literal: 3,
13
+ ArrayExpression: 28,
14
+ ObjectExpression: 29,
15
+ Property: 31,
16
+ UnaryExpression: 33,
17
+ // UpdateExpression: 34,
18
+ BinaryExpression: 35,
19
+ LogicalExpression: 37,
20
+ MemberExpression: 38,
21
+ ConditionalExpression: 39,
22
+ ExpressionStatement: 40
23
+ }
24
+
25
+ const error = function (msg) {
26
+ throw new Error(`[Mpx dynamic expression parser error]: ${msg}`)
27
+ }
28
+
29
+ walk.full = function full (node, baseVisitor, state, override) {
30
+ const stack = []
31
+ ; (function c (node, st, override, s) {
32
+ const type = override || node.type
33
+ if (!baseVisitor[type]) {
34
+ error(`${type} grammar is not supported in the template`)
35
+ }
36
+ baseVisitor[type](node, st, c, s)
37
+ })(node, state, override, stack)
38
+
39
+ // 限定 bodyStack 长度,仅支持单表达式的写法
40
+ const bodyStackIndex = 1
41
+ if (stack[bodyStackIndex].length > 1) {
42
+ error('only support one expression in the template')
43
+ }
44
+ return stack
45
+ }
46
+
47
+ const baseVisitor = {}
48
+
49
+ baseVisitor.UnaryExpression = function (node, st, c, s) {
50
+ // const nodeType = node.type === 'UnaryExpression' ? NODE_TYPE.UnaryExpression : NODE_TYPE.UpdateExpression
51
+ const nodeType = NODE_TYPE.UnaryExpression
52
+ const argumentNodeStack = []
53
+ s.push(nodeType, node.operator, argumentNodeStack, node.prefix)
54
+ c(node.argument, st, 'Expression', argumentNodeStack)
55
+ }
56
+
57
+ baseVisitor.BinaryExpression = baseVisitor.LogicalExpression = function (node, st, c, s) {
58
+ const nodeType = node.type === 'BinaryExpression' ? NODE_TYPE.BinaryExpression : NODE_TYPE.LogicalExpression
59
+ const leftNodeStack = []
60
+ const rightNodeStack = []
61
+ // todo operator 可以严格按照小程序模版能力进行限制
62
+ s.push(nodeType, node.operator, leftNodeStack, rightNodeStack)
63
+ c(node.left, st, 'Expression', leftNodeStack)
64
+ c(node.right, st, 'Expression', rightNodeStack)
65
+ }
66
+
67
+ baseVisitor.ConditionalExpression = (node, st, c, s) => {
68
+ const testNodeStack = []
69
+ const consequentNodeStack = []
70
+ const alternateNodeStack = []
71
+ s.push(NODE_TYPE.ConditionalExpression, testNodeStack, consequentNodeStack, alternateNodeStack)
72
+ c(node.test, st, 'Expression', testNodeStack)
73
+ c(node.consequent, st, 'Expression', consequentNodeStack)
74
+ c(node.alternate, st, 'Expression', alternateNodeStack)
75
+ }
76
+
77
+ const visitor = walk.make({
78
+ Program (node, st, c, s) {
79
+ const bodyStack = []
80
+ s.push(NODE_TYPE.Program, bodyStack)
81
+ for (let i = 0, list = node.body; i < list.length; i += 1) {
82
+ const stmt = list[i]
83
+ bodyStack[i] = []
84
+ c(stmt, st, 'Statement', bodyStack[i])
85
+ }
86
+ },
87
+ ExpressionStatement (node, st, c, s) {
88
+ const expressionStack = []
89
+ s.push(NODE_TYPE.ExpressionStatement, expressionStack)
90
+ c(node.expression, st, null, expressionStack)
91
+ },
92
+ MemberExpression (node, st, c, s) {
93
+ const objectNodeStack = []
94
+ const propertyNodeStack = []
95
+ s.push(NODE_TYPE.MemberExpression, objectNodeStack, propertyNodeStack, node.computed)
96
+ c(node.object, st, 'Expression', objectNodeStack)
97
+ c(node.property, st, 'Expression', propertyNodeStack)
98
+ },
99
+ ArrayExpression (node, st, c, s) {
100
+ const elementsStack = []
101
+ s.push(NODE_TYPE.ArrayExpression, elementsStack)
102
+ node.elements.forEach((elt, index) => {
103
+ if (elt) {
104
+ elementsStack[index] = []
105
+ c(elt, st, 'Expression', elementsStack[index])
106
+ }
107
+ })
108
+ },
109
+ ObjectExpression (node, st, c, s) {
110
+ const propertiesStack = []
111
+ s.push(NODE_TYPE.ObjectExpression, propertiesStack)
112
+ node.properties.forEach((prop, index) => {
113
+ propertiesStack[index] = []
114
+ c(prop, st, null, propertiesStack[index])
115
+ })
116
+ },
117
+ Property (node, st, c, s) {
118
+ const keyNodeStack = []
119
+ const valueNodeStack = []
120
+ s.push(NODE_TYPE.Property, keyNodeStack, valueNodeStack, node.kind)
121
+ c(node.key, st, 'Expression', keyNodeStack)
122
+ c(node.value, st, 'Expression', valueNodeStack)
123
+ },
124
+ Literal (node, st, c, s) {
125
+ // todo node.raw/-1 目前应该都用不到,后续可以优化
126
+ s.push(NODE_TYPE.Literal, node.value, node.raw, -1) // -1?
127
+ },
128
+ Identifier (node, st, c, s) {
129
+ s.push(NODE_TYPE.Identifier, node.name)
130
+ },
131
+ Expression (node, st, c, s) {
132
+ c(node, st, null, s)
133
+ },
134
+ Statement (node, st, c, s) {
135
+ c(node, st, null, s)
136
+ }
137
+ }, baseVisitor)
138
+
139
+ module.exports = {
140
+ parseExp (str) {
141
+ // 确保 str 都是为 expressionStatement
142
+ if (!/^\(*\)$/.test(str)) {
143
+ str = `(${str})`
144
+ }
145
+ return walk.full(acorn.parse(str, { ecmaVersion: 5 }), visitor)
146
+ },
147
+ NODE_TYPE
148
+ }
@@ -0,0 +1,7 @@
1
+ module.exports = function (packageName) {
2
+ let subPath = ''
3
+ if (packageName !== 'main') {
4
+ subPath = '/' + packageName
5
+ }
6
+ return subPath + `/mpx-custom-element-${packageName}`
7
+ }
@@ -0,0 +1,17 @@
1
+ const hasOwn = require('./has-own')
2
+
3
+ module.exports = function shallowStringify (obj, isTemplateExp) {
4
+ const arr = []
5
+ for (const key in obj) {
6
+ if (hasOwn(obj, key)) {
7
+ let value = obj[key]
8
+ if (Array.isArray(value)) {
9
+ value = `[${value.join(',')}]`
10
+ } else if (typeof value === 'object') {
11
+ value = shallowStringify(value, isTemplateExp)
12
+ }
13
+ arr.push(isTemplateExp ? `${key}:${value}` : `'${key}':${value}`)
14
+ }
15
+ }
16
+ return isTemplateExp ? `({${arr.join(',')}})` : `{${arr.join(',')}}`
17
+ }
@@ -75,8 +75,7 @@ module.exports = function (template, {
75
75
  usingComponents,
76
76
  hasComment,
77
77
  isNative,
78
- isComponent: ctorType === 'component',
79
- isPage: ctorType === 'page',
78
+ ctorType,
80
79
  mode,
81
80
  env,
82
81
  srcMode: templateSrcMode,
@@ -5,6 +5,7 @@ const config = require('../config')
5
5
  const createHelpers = require('../helpers')
6
6
  const isUrlRequest = require('../utils/is-url-request')
7
7
  const parseRequest = require('../utils/parse-request')
8
+ const genDynamicTemplate = require('../runtime-render/gen-dynamic-template')
8
9
 
9
10
  let count = 0
10
11
 
@@ -26,6 +27,14 @@ module.exports = function (content) {
26
27
  const mode = mpx.mode
27
28
  const localSrcMode = queryObj.mode
28
29
  const customAttributes = options.attributes || mpx.attributes || []
30
+ const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
31
+ const isDynamic = queryObj.isDynamic
32
+
33
+ const exportsString = 'module.exports = '
34
+
35
+ if (isDynamic) {
36
+ return exportsString + JSON.stringify(genDynamicTemplate(packageName)) + ';'
37
+ }
29
38
 
30
39
  const { getRequestString } = createHelpers(this)
31
40
 
@@ -71,8 +80,6 @@ module.exports = function (content) {
71
80
  content = content.join('')
72
81
  content = JSON.stringify(content)
73
82
 
74
- const exportsString = 'module.exports = '
75
-
76
83
  return exportsString + content.replace(/__HTMLLINK__\d+__/g, (match) => {
77
84
  if (!data[match]) return match
78
85
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.9.37",
3
+ "version": "2.9.39",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -27,6 +27,8 @@
27
27
  "@better-scroll/slide": "^2.5.1",
28
28
  "@better-scroll/wheel": "^2.5.1",
29
29
  "@better-scroll/zoom": "^2.5.1",
30
+ "@mpxjs/template-engine": "^2.8.7",
31
+ "acorn": "^8.11.3",
30
32
  "acorn-walk": "^7.2.0",
31
33
  "async": "^2.6.0",
32
34
  "css": "^2.2.1",
@@ -82,5 +84,5 @@
82
84
  "engines": {
83
85
  "node": ">=14.14.0"
84
86
  },
85
- "gitHead": "d97cf71f4c2fa8fd96f02f2f094544e4dfb4b15e"
87
+ "gitHead": "87957d360b18806f16d169612d924d383ac043c4"
86
88
  }