@mpxjs/webpack-plugin 2.9.39 → 2.9.41-react.0

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 (63) hide show
  1. package/lib/config.js +63 -97
  2. package/lib/dependencies/{RecordVueContentDependency.js → RecordLoaderContentDependency.js} +5 -5
  3. package/lib/dependencies/ResolveDependency.js +2 -2
  4. package/lib/helpers.js +5 -1
  5. package/lib/index.js +26 -21
  6. package/lib/loader.js +43 -97
  7. package/lib/native-loader.js +0 -1
  8. package/lib/platform/index.js +3 -0
  9. package/lib/platform/style/wx/index.js +414 -0
  10. package/lib/platform/template/wx/component-config/button.js +36 -0
  11. package/lib/platform/template/wx/component-config/image.js +15 -0
  12. package/lib/platform/template/wx/component-config/input.js +41 -0
  13. package/lib/platform/template/wx/component-config/scroll-view.js +27 -1
  14. package/lib/platform/template/wx/component-config/swiper-item.js +13 -1
  15. package/lib/platform/template/wx/component-config/swiper.js +25 -1
  16. package/lib/platform/template/wx/component-config/text.js +15 -0
  17. package/lib/platform/template/wx/component-config/textarea.js +39 -0
  18. package/lib/platform/template/wx/component-config/unsupported.js +18 -0
  19. package/lib/platform/template/wx/component-config/view.js +14 -0
  20. package/lib/platform/template/wx/index.js +88 -4
  21. package/lib/react/index.js +104 -0
  22. package/lib/react/processJSON.js +361 -0
  23. package/lib/react/processMainScript.js +21 -0
  24. package/lib/react/processScript.js +70 -0
  25. package/lib/react/processStyles.js +69 -0
  26. package/lib/react/processTemplate.js +153 -0
  27. package/lib/react/script-helper.js +133 -0
  28. package/lib/react/style-helper.js +91 -0
  29. package/lib/resolver/PackageEntryPlugin.js +1 -0
  30. package/lib/runtime/components/react/event.config.ts +32 -0
  31. package/lib/runtime/components/react/getInnerListeners.ts +289 -0
  32. package/lib/runtime/components/react/getInnerListeners.type.ts +68 -0
  33. package/lib/runtime/components/react/mpx-button.tsx +402 -0
  34. package/lib/runtime/components/react/mpx-image/index.tsx +351 -0
  35. package/lib/runtime/components/react/mpx-image/svg.tsx +21 -0
  36. package/lib/runtime/components/react/mpx-input.tsx +389 -0
  37. package/lib/runtime/components/react/mpx-scroll-view.tsx +412 -0
  38. package/lib/runtime/components/react/mpx-swiper/carouse.tsx +398 -0
  39. package/lib/runtime/components/react/mpx-swiper/index.tsx +68 -0
  40. package/lib/runtime/components/react/mpx-swiper/type.ts +69 -0
  41. package/lib/runtime/components/react/mpx-swiper-item.tsx +42 -0
  42. package/lib/runtime/components/react/mpx-text.tsx +106 -0
  43. package/lib/runtime/components/react/mpx-textarea.tsx +46 -0
  44. package/lib/runtime/components/react/mpx-view.tsx +397 -0
  45. package/lib/runtime/components/react/useNodesRef.ts +39 -0
  46. package/lib/runtime/components/react/utils.ts +92 -0
  47. package/lib/runtime/optionProcessorReact.d.ts +9 -0
  48. package/lib/runtime/optionProcessorReact.js +21 -0
  49. package/lib/runtime/stringify.wxs +3 -8
  50. package/lib/style-compiler/index.js +2 -1
  51. package/lib/template-compiler/compiler.js +293 -38
  52. package/lib/template-compiler/gen-node-react.js +95 -0
  53. package/lib/template-compiler/index.js +15 -24
  54. package/lib/utils/env.js +17 -0
  55. package/lib/utils/make-map.js +1 -1
  56. package/lib/utils/shallow-stringify.js +12 -12
  57. package/lib/web/index.js +123 -0
  58. package/lib/web/processJSON.js +3 -3
  59. package/lib/web/processMainScript.js +25 -23
  60. package/lib/web/processScript.js +12 -16
  61. package/lib/web/processTemplate.js +13 -12
  62. package/lib/web/script-helper.js +14 -22
  63. package/package.json +4 -3
@@ -0,0 +1,361 @@
1
+ const async = require('async')
2
+ const path = require('path')
3
+ const JSON5 = require('json5')
4
+ const loaderUtils = require('loader-utils')
5
+ const parseRequest = require('../utils/parse-request')
6
+ const toPosix = require('../utils/to-posix')
7
+ const addQuery = require('../utils/add-query')
8
+ const parseComponent = require('../parser')
9
+ const getJSONContent = require('../utils/get-json-content')
10
+ const resolve = require('../utils/resolve')
11
+ const createJSONHelper = require('../json-compiler/helper')
12
+ const getRulesRunner = require('../platform/index')
13
+ const { RESOLVE_IGNORED_ERR } = require('../utils/const')
14
+ const RecordResourceMapDependency = require('../dependencies/RecordResourceMapDependency')
15
+ const RecordGlobalComponentsDependency = require('../dependencies/RecordGlobalComponentsDependency')
16
+
17
+ module.exports = function (json, {
18
+ loaderContext,
19
+ ctorType,
20
+ pagesMap,
21
+ componentsMap
22
+ }, rawCallback) {
23
+ const localPagesMap = {}
24
+ const localComponentsMap = {}
25
+ const output = '/* json */\n'
26
+ let jsonObj = {}
27
+ let tabBarMap
28
+ let tabBarStr
29
+ const mpx = loaderContext.getMpx()
30
+ const {
31
+ mode,
32
+ srcMode,
33
+ env,
34
+ projectRoot
35
+ } = mpx
36
+
37
+ const context = loaderContext.context
38
+
39
+ const emitWarning = (msg) => {
40
+ loaderContext.emitWarning(
41
+ new Error('[json processor][' + loaderContext.resource + ']: ' + msg)
42
+ )
43
+ }
44
+
45
+ const emitError = (msg) => {
46
+ loaderContext.emitError(
47
+ new Error('[json compiler][' + loaderContext.resource + ']: ' + msg)
48
+ )
49
+ }
50
+
51
+ const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
52
+
53
+ const {
54
+ isUrlRequest,
55
+ urlToRequest,
56
+ processPage,
57
+ processComponent
58
+ } = createJSONHelper({
59
+ loaderContext,
60
+ emitWarning,
61
+ emitError,
62
+ customGetDynamicEntry (resource, type, outputPath, packageRoot) {
63
+ return {
64
+ resource,
65
+ // 输出react时组件outputPath不需要拼接packageRoot
66
+ outputPath: type === 'page' ? toPosix(path.join(packageRoot, outputPath)) : outputPath,
67
+ packageRoot
68
+ }
69
+ }
70
+ })
71
+
72
+ const callback = (err) => {
73
+ return rawCallback(err, {
74
+ output,
75
+ jsonObj,
76
+ localPagesMap,
77
+ localComponentsMap,
78
+ tabBarMap,
79
+ tabBarStr
80
+ })
81
+ }
82
+
83
+ const isApp = ctorType === 'app'
84
+ if (!json) {
85
+ return callback()
86
+ }
87
+ // 由于json需要提前读取在template处理中使用,src的场景已经在loader中处理了,此处无需考虑json.src的场景
88
+ try {
89
+ jsonObj = JSON5.parse(json.content)
90
+ // 处理runner
91
+ const rulesRunnerOptions = {
92
+ mode,
93
+ srcMode,
94
+ type: 'json',
95
+ waterfall: true,
96
+ warn: emitWarning,
97
+ error: emitError,
98
+ data: {
99
+ // polyfill global usingComponents & record globalComponents
100
+ globalComponents: mpx.usingComponents
101
+ }
102
+ }
103
+
104
+ if (!isApp) {
105
+ rulesRunnerOptions.mainKey = ctorType
106
+ }
107
+
108
+ const rulesRunner = getRulesRunner(rulesRunnerOptions)
109
+
110
+ if (rulesRunner) {
111
+ rulesRunner(jsonObj)
112
+ }
113
+ if (isApp) {
114
+ // 收集全局组件
115
+ Object.assign(mpx.usingComponents, jsonObj.usingComponents)
116
+ // 在 rulesRunner 运行后保存全局注册组件
117
+ loaderContext._module.addPresentationalDependency(new RecordGlobalComponentsDependency(mpx.usingComponents, loaderContext.context))
118
+ }
119
+ } catch (e) {
120
+ return callback(e)
121
+ }
122
+
123
+ const fs = loaderContext._compiler.inputFileSystem
124
+
125
+ const defaultTabbar = {
126
+ borderStyle: 'black',
127
+ position: 'bottom',
128
+ custom: false,
129
+ isShow: true
130
+ }
131
+
132
+ const processTabBar = (tabBar, callback) => {
133
+ if (tabBar) {
134
+ tabBar = Object.assign({}, defaultTabbar, tabBar)
135
+ tabBarMap = {}
136
+ jsonObj.tabBar.list.forEach(({ pagePath }) => {
137
+ tabBarMap[pagePath] = true
138
+ })
139
+ tabBarStr = JSON.stringify(tabBar)
140
+ tabBarStr = tabBarStr.replace(/"(iconPath|selectedIconPath)":"([^"]+)"/g, function (matched, $1, $2) {
141
+ if (isUrlRequest($2, projectRoot)) {
142
+ return `"${$1}":require(${stringifyRequest(urlToRequest($2, projectRoot))})`
143
+ }
144
+ return matched
145
+ })
146
+ }
147
+ callback()
148
+ }
149
+
150
+ const processPackages = (packages, context, callback) => {
151
+ if (packages) {
152
+ async.each(packages, (packagePath, callback) => {
153
+ const { queryObj } = parseRequest(packagePath)
154
+ async.waterfall([
155
+ (callback) => {
156
+ resolve(context, packagePath, loaderContext, (err, result) => {
157
+ if (err) return callback(err)
158
+ const { rawResourcePath } = parseRequest(result)
159
+ callback(err, rawResourcePath)
160
+ })
161
+ },
162
+ (result, callback) => {
163
+ fs.readFile(result, (err, content) => {
164
+ if (err) return callback(err)
165
+ callback(err, result, content.toString('utf-8'))
166
+ })
167
+ },
168
+ (result, content, callback) => {
169
+ const extName = path.extname(result)
170
+ if (extName === '.mpx') {
171
+ const parts = parseComponent(content, {
172
+ filePath: result,
173
+ needMap: loaderContext.sourceMap,
174
+ mode,
175
+ env
176
+ })
177
+ getJSONContent(parts.json || {}, result, loaderContext, (err, content) => {
178
+ callback(err, result, content)
179
+ })
180
+ } else {
181
+ callback(null, result, content)
182
+ }
183
+ },
184
+ (result, content, callback) => {
185
+ try {
186
+ content = JSON5.parse(content)
187
+ } catch (err) {
188
+ return callback(err)
189
+ }
190
+
191
+ const processSelfQueue = []
192
+ const context = path.dirname(result)
193
+
194
+ if (content.pages) {
195
+ const tarRoot = queryObj.root
196
+ if (tarRoot) {
197
+ delete queryObj.root
198
+ const subPackage = {
199
+ tarRoot,
200
+ pages: content.pages,
201
+ ...queryObj
202
+ }
203
+
204
+ if (content.plugins) {
205
+ subPackage.plugins = content.plugins
206
+ }
207
+
208
+ processSelfQueue.push((callback) => {
209
+ processSubPackage(subPackage, context, callback)
210
+ })
211
+ } else {
212
+ processSelfQueue.push((callback) => {
213
+ processPages(content.pages, context, '', callback)
214
+ })
215
+ }
216
+ }
217
+ if (content.packages) {
218
+ processSelfQueue.push((callback) => {
219
+ processPackages(content.packages, context, callback)
220
+ })
221
+ }
222
+ if (processSelfQueue.length) {
223
+ async.parallel(processSelfQueue, callback)
224
+ } else {
225
+ callback()
226
+ }
227
+ }
228
+ ], (err) => {
229
+ callback(err === RESOLVE_IGNORED_ERR ? null : err)
230
+ })
231
+ }, callback)
232
+ } else {
233
+ callback()
234
+ }
235
+ }
236
+
237
+ const pageKeySet = new Set()
238
+
239
+ const processPages = (pages, context, tarRoot = '', callback) => {
240
+ if (pages) {
241
+ async.each(pages, (page, callback) => {
242
+ processPage(page, context, tarRoot, (err, { resource, outputPath } = {}, { isFirst, key } = {}) => {
243
+ if (err) return callback(err === RESOLVE_IGNORED_ERR ? null : err)
244
+ if (pageKeySet.has(key)) return callback()
245
+ pageKeySet.add(key)
246
+ const { resourcePath, queryObj } = parseRequest(resource)
247
+ if (localPagesMap[outputPath]) {
248
+ const { resourcePath: oldResourcePath } = parseRequest(localPagesMap[outputPath].resource)
249
+ if (oldResourcePath !== resourcePath) {
250
+ const oldOutputPath = outputPath
251
+ outputPath = mpx.getOutputPath(resourcePath, 'page', { conflictPath: outputPath })
252
+ emitWarning(new Error(`Current page [${resourcePath}] is registered with a conflict outputPath [${oldOutputPath}] which is already existed in system, will be renamed with [${outputPath}], use ?resolve to get the real outputPath!`))
253
+ }
254
+ }
255
+
256
+ pagesMap[resourcePath] = outputPath
257
+ loaderContext._module && loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'page', outputPath))
258
+ localPagesMap[outputPath] = {
259
+ resource: addQuery(resource, { isPage: true }),
260
+ async: queryObj.async || tarRoot,
261
+ isFirst
262
+ }
263
+ callback()
264
+ })
265
+ }, callback)
266
+ } else {
267
+ callback()
268
+ }
269
+ }
270
+
271
+ const processSubPackage = (subPackage, context, callback) => {
272
+ if (subPackage) {
273
+ if (typeof subPackage.root === 'string' && subPackage.root.startsWith('.')) {
274
+ emitError(`Current subpackage root [${subPackage.root}] is not allow starts with '.'`)
275
+ return callback()
276
+ }
277
+ const tarRoot = subPackage.tarRoot || subPackage.root || ''
278
+ const srcRoot = subPackage.srcRoot || subPackage.root || ''
279
+ if (!tarRoot) return callback()
280
+ context = path.join(context, srcRoot)
281
+ processPages(subPackage.pages, context, tarRoot, callback)
282
+ } else {
283
+ callback()
284
+ }
285
+ }
286
+
287
+ const processSubPackages = (subPackages, context, callback) => {
288
+ if (subPackages) {
289
+ async.each(subPackages, (subPackage, callback) => {
290
+ processSubPackage(subPackage, context, callback)
291
+ }, callback)
292
+ } else {
293
+ callback()
294
+ }
295
+ }
296
+
297
+ const processComponents = (components, context, callback) => {
298
+ if (components) {
299
+ async.eachOf(components, (component, name, callback) => {
300
+ processComponent(component, context, {}, (err, { resource, outputPath } = {}, { tarRoot } = {}) => {
301
+ if (err) return callback(err === RESOLVE_IGNORED_ERR ? null : err)
302
+ const { resourcePath, queryObj } = parseRequest(resource)
303
+ componentsMap[resourcePath] = outputPath
304
+ loaderContext._module && loaderContext._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'component', outputPath))
305
+ localComponentsMap[name] = {
306
+ resource: addQuery(resource, {
307
+ isComponent: true,
308
+ outputPath
309
+ }),
310
+ async: queryObj.async || tarRoot
311
+ }
312
+ callback()
313
+ })
314
+ }, callback)
315
+ } else {
316
+ callback()
317
+ }
318
+ }
319
+
320
+ const processGenerics = (generics, context, callback) => {
321
+ if (generics) {
322
+ const genericsComponents = {}
323
+ Object.keys(generics).forEach((name) => {
324
+ const generic = generics[name]
325
+ if (generic.default) genericsComponents[`${name}default`] = generic.default
326
+ })
327
+ processComponents(genericsComponents, context, callback)
328
+ } else {
329
+ callback()
330
+ }
331
+ }
332
+
333
+ async.parallel([
334
+ (callback) => {
335
+ // 添加首页标识
336
+ if (jsonObj.pages && jsonObj.pages[0]) {
337
+ if (typeof jsonObj.pages[0] !== 'string') {
338
+ jsonObj.pages[0].src = addQuery(jsonObj.pages[0].src, { isFirst: true })
339
+ } else {
340
+ jsonObj.pages[0] = addQuery(jsonObj.pages[0], { isFirst: true })
341
+ }
342
+ }
343
+ processPages(jsonObj.pages, context, '', callback)
344
+ },
345
+ (callback) => {
346
+ processComponents(jsonObj.usingComponents, context, callback)
347
+ },
348
+ (callback) => {
349
+ processPackages(jsonObj.packages, context, callback)
350
+ },
351
+ (callback) => {
352
+ processSubPackages(jsonObj.subPackages || jsonObj.subpackages, context, callback)
353
+ },
354
+ (callback) => {
355
+ processGenerics(jsonObj.componentGenerics, context, callback)
356
+ },
357
+ (callback) => {
358
+ processTabBar(jsonObj.tabBar, callback)
359
+ }
360
+ ], callback)
361
+ }
@@ -0,0 +1,21 @@
1
+ // 该文件下的字符串语句需要使用 es5 语法
2
+ const addQuery = require('../utils/add-query')
3
+
4
+ const {
5
+ stringifyRequest
6
+ } = require('./script-helper')
7
+
8
+ module.exports = function (script, {
9
+ loaderContext
10
+ }, callback) {
11
+ const { projectName } = loaderContext.getMpx()
12
+
13
+ let output = 'import { AppRegistry } from \'react-native\'\n'
14
+ // 此处可添加前置于App执行的语句
15
+ output += `var App = require(${stringifyRequest(loaderContext, addQuery(loaderContext.resource, { isApp: true }))}).default\n`
16
+ output += `AppRegistry.registerComponent(${JSON.stringify(projectName)}, () => App)\n`
17
+
18
+ callback(null, {
19
+ output
20
+ })
21
+ }
@@ -0,0 +1,70 @@
1
+ const normalize = require('../utils/normalize')
2
+ const optionProcessorPath = normalize.lib('runtime/optionProcessorReact')
3
+ const { buildPagesMap, buildComponentsMap, getRequireScript, buildGlobalParams, stringifyRequest } = require('./script-helper')
4
+
5
+ module.exports = function (script, {
6
+ loaderContext,
7
+ ctorType,
8
+ srcMode,
9
+ moduleId,
10
+ isProduction,
11
+ jsonConfig,
12
+ builtInComponentsMap,
13
+ localComponentsMap,
14
+ localPagesMap
15
+ }, callback) {
16
+ let scriptSrcMode = srcMode
17
+ if (script) {
18
+ scriptSrcMode = script.mode || scriptSrcMode
19
+ } else {
20
+ script = { tag: 'script' }
21
+ }
22
+
23
+ let output = '/* script */\n'
24
+ if (ctorType === 'app') {
25
+ output += `
26
+ import { getComponent } from ${stringifyRequest(loaderContext, optionProcessorPath)}
27
+ import { NavigationContainer, createNavigationContainerRef, StackActions } from '@react-navigation/native'
28
+ import { createNativeStackNavigator } from '@react-navigation/native-stack'
29
+ import { RootSiblingParent } from 'react-native-root-siblings'
30
+ global.__navigationHelper = {
31
+ NavigationContainer: NavigationContainer,
32
+ createNavigationContainerRef: createNavigationContainerRef,
33
+ createNativeStackNavigator: createNativeStackNavigator,
34
+ StackActions: StackActions,
35
+ RootSiblingParent: RootSiblingParent
36
+ }\n`
37
+ const { pagesMap, firstPage } = buildPagesMap({
38
+ localPagesMap,
39
+ loaderContext,
40
+ jsonConfig
41
+ })
42
+ const componentsMap = buildComponentsMap({
43
+ localComponentsMap,
44
+ loaderContext,
45
+ jsonConfig
46
+ })
47
+ output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, ctorType, jsonConfig, componentsMap, pagesMap, firstPage })
48
+ output += getRequireScript({ ctorType, script, loaderContext })
49
+ output += `export default global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
50
+ } else {
51
+ // RN环境暂不支持异步加载
52
+ // output += 'import { lazy } from \'react\'\n'
53
+ output += `import { getComponent } from ${stringifyRequest(loaderContext, optionProcessorPath)}\n`
54
+ // 获取组件集合
55
+ const componentsMap = buildComponentsMap({
56
+ localComponentsMap,
57
+ builtInComponentsMap,
58
+ loaderContext,
59
+ jsonConfig
60
+ })
61
+
62
+ output += buildGlobalParams({ moduleId, scriptSrcMode, loaderContext, isProduction, componentsMap })
63
+ output += getRequireScript({ ctorType, script, loaderContext })
64
+ output += `export default global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
65
+ }
66
+
67
+ callback(null, {
68
+ output
69
+ })
70
+ }
@@ -0,0 +1,69 @@
1
+ const createHelpers = require('../helpers')
2
+ const async = require('async')
3
+ const getClassMap = require('./style-helper').getClassMap
4
+ const shallowStringify = require('../utils/shallow-stringify')
5
+
6
+ module.exports = function (styles, {
7
+ loaderContext,
8
+ srcMode,
9
+ ctorType,
10
+ autoScope,
11
+ moduleId
12
+ }, callback) {
13
+ const { getRequestString } = createHelpers(loaderContext)
14
+ let content = ''
15
+ let output = '/* styles */\n'
16
+ if (styles.length) {
17
+ const { mode } = loaderContext.getMpx()
18
+ async.eachOfSeries(styles, (style, i, callback) => {
19
+ const scoped = style.scoped || autoScope
20
+ const extraOptions = {
21
+ moduleId,
22
+ scoped,
23
+ extract: false
24
+ }
25
+ loaderContext.importModule(JSON.parse(getRequestString('styles', style, extraOptions, i))).then((result) => {
26
+ if (Array.isArray(result)) {
27
+ result = result.map((item) => {
28
+ return item[1]
29
+ }).join('\n')
30
+ }
31
+ content += result.trim() + '\n'
32
+ callback()
33
+ }).catch((e) => {
34
+ callback(e)
35
+ })
36
+ // require style
37
+ }, (err) => {
38
+ if (err) return callback(err)
39
+ try {
40
+ const classMap = getClassMap({
41
+ content,
42
+ filename: loaderContext.resourcePath,
43
+ mode,
44
+ srcMode
45
+ })
46
+ if (ctorType === 'app') {
47
+ output += `global.__getAppClassMap = function() {
48
+ return ${shallowStringify(classMap)};
49
+ };\n`
50
+ } else {
51
+ output += `global.currentInject.injectMethods = {
52
+ __getClassMap: function() {
53
+ return ${shallowStringify(classMap)};
54
+ }
55
+ };\n`
56
+ }
57
+ } catch (e) {
58
+ return callback(e)
59
+ }
60
+ callback(null, {
61
+ output
62
+ })
63
+ })
64
+ } else {
65
+ callback(null, {
66
+ output: ''
67
+ })
68
+ }
69
+ }
@@ -0,0 +1,153 @@
1
+ const addQuery = require('../utils/add-query')
2
+ const parseRequest = require('../utils/parse-request')
3
+ const { matchCondition } = require('../utils/match-condition')
4
+ const loaderUtils = require('loader-utils')
5
+ const templateCompiler = require('../template-compiler/compiler')
6
+ const genNode = require('../template-compiler/gen-node-react')
7
+ const bindThis = require('../template-compiler/bind-this')
8
+
9
+ module.exports = function (template, {
10
+ loaderContext,
11
+ // hasScoped,
12
+ hasComment,
13
+ isNative,
14
+ srcMode,
15
+ moduleId,
16
+ ctorType,
17
+ usingComponents,
18
+ componentGenerics
19
+ }, callback) {
20
+ const mpx = loaderContext.getMpx()
21
+ const {
22
+ projectRoot,
23
+ mode,
24
+ env,
25
+ defs,
26
+ wxsContentMap,
27
+ decodeHTMLText,
28
+ externalClasses,
29
+ checkUsingComponents,
30
+ autoVirtualHostRules
31
+ } = mpx
32
+ const { resourcePath } = parseRequest(loaderContext.resource)
33
+ const builtInComponentsMap = {}
34
+
35
+ let genericsInfo
36
+ let output = '/* template */\n'
37
+
38
+ output += `global.currentInject = {
39
+ moduleId: ${JSON.stringify(moduleId)}
40
+ };\n`
41
+
42
+ if (template) {
43
+ // 由于远端src template资源引用的相对路径可能发生变化,暂时不支持。
44
+ if (template.src) {
45
+ return callback(new Error('[mpx loader][' + loaderContext.resource + ']: ' + 'template content must be inline in .mpx files!'))
46
+ }
47
+ if (template.lang) {
48
+ return callback(new Error('[mpx loader][' + loaderContext.resource + ']: ' + 'template lang is not supported in trans react native mode temporarily, we will support it in the future!'))
49
+ }
50
+
51
+ if (template.content) {
52
+ const templateSrcMode = template.mode || srcMode
53
+ const warn = (msg) => {
54
+ loaderContext.emitWarning(
55
+ new Error('[template compiler][' + loaderContext.resource + ']: ' + msg)
56
+ )
57
+ }
58
+ const error = (msg) => {
59
+ loaderContext.emitError(
60
+ new Error('[template compiler][' + loaderContext.resource + ']: ' + msg)
61
+ )
62
+ }
63
+ const { root, meta } = templateCompiler.parse(template.content, {
64
+ warn,
65
+ error,
66
+ usingComponents,
67
+ hasComment,
68
+ isNative,
69
+ ctorType,
70
+ mode,
71
+ env,
72
+ srcMode: templateSrcMode,
73
+ defs,
74
+ decodeHTMLText,
75
+ externalClasses,
76
+ // todo 后续输出web也采用mpx的scoped处理
77
+ hasScoped: false,
78
+ moduleId,
79
+ filePath: resourcePath,
80
+ i18n: null,
81
+ checkUsingComponents,
82
+ // web模式下全局组件不会被合入usingComponents中,故globalComponents可以传空
83
+ globalComponents: [],
84
+ // web模式下实现抽象组件
85
+ componentGenerics,
86
+ hasVirtualHost: matchCondition(resourcePath, autoVirtualHostRules)
87
+ })
88
+
89
+ if (meta.wxsContentMap) {
90
+ for (const module in meta.wxsContentMap) {
91
+ wxsContentMap[`${resourcePath}~${module}`] = meta.wxsContentMap[module]
92
+ }
93
+ }
94
+ if (meta.builtInComponentsMap) {
95
+ Object.keys(meta.builtInComponentsMap).forEach((name) => {
96
+ builtInComponentsMap[name] = {
97
+ resource: addQuery(meta.builtInComponentsMap[name], { isComponent: true })
98
+ }
99
+ })
100
+ }
101
+ if (meta.genericsInfo) {
102
+ genericsInfo = meta.genericsInfo
103
+ }
104
+
105
+ for (const module in meta.wxsModuleMap) {
106
+ const src = loaderUtils.urlToRequest(meta.wxsModuleMap[module], projectRoot)
107
+ output += `var ${module} = require(${loaderUtils.stringifyRequest(this, src)});\n`
108
+ }
109
+
110
+ const rawCode = genNode(root)
111
+ if (rawCode) {
112
+ try {
113
+ const ignoreMap = Object.assign({
114
+ createElement: true,
115
+ components: true,
116
+ getNativeComponent: true,
117
+ rootProps: true
118
+ }, meta.wxsModuleMap)
119
+ const bindResult = bindThis.transform(rawCode, {
120
+ ignoreMap
121
+ })
122
+ output += `global.currentInject.render = function (createElement, components, getNativeComponent, rootProps) {
123
+ return ${bindResult.code}
124
+ };\n`
125
+ } catch (e) {
126
+ error(`Invalid render function generated by the template, please check!
127
+ Error code:
128
+ ${rawCode}
129
+ Error Detail:
130
+ ${e.stack}`)
131
+ }
132
+ }
133
+
134
+ if (meta.computed) {
135
+ output += bindThis.transform(`global.currentInject.injectComputed = {${meta.computed.join(',')}};`).code + '\n'
136
+ }
137
+
138
+ if (meta.refs) {
139
+ output += `global.currentInject.getRefsData = function () {return ${JSON.stringify(meta.refs)};};\n`
140
+ }
141
+
142
+ if (meta.options) {
143
+ output += `global.currentInject.injectOptions = ${JSON.stringify(meta.options)};\n`
144
+ }
145
+ }
146
+ }
147
+
148
+ callback(null, {
149
+ output,
150
+ builtInComponentsMap,
151
+ genericsInfo
152
+ })
153
+ }