@mpxjs/webpack-plugin 2.8.23 → 2.8.25-alpha.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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/lib/config.js +14 -0
  3. package/lib/dependencies/AddEntryDependency.js +24 -0
  4. package/lib/dependencies/ResolveDependency.js +4 -0
  5. package/lib/index.js +35 -5
  6. package/lib/json-compiler/index.js +1 -8
  7. package/lib/loader.js +40 -0
  8. package/lib/platform/template/wx/component-config/button.js +14 -2
  9. package/lib/platform/template/wx/component-config/image.js +4 -0
  10. package/lib/platform/template/wx/component-config/input.js +4 -0
  11. package/lib/platform/template/wx/component-config/rich-text.js +4 -0
  12. package/lib/platform/template/wx/component-config/scroll-view.js +4 -0
  13. package/lib/platform/template/wx/component-config/switch.js +4 -0
  14. package/lib/platform/template/wx/component-config/text.js +4 -0
  15. package/lib/platform/template/wx/component-config/textarea.js +5 -0
  16. package/lib/platform/template/wx/component-config/view.js +4 -0
  17. package/lib/platform/template/wx/index.js +121 -1
  18. package/lib/resolve-loader.js +4 -1
  19. package/lib/runtime/components/tenon/getInnerListeners.js +314 -0
  20. package/lib/runtime/components/tenon/tenon-button.vue +305 -0
  21. package/lib/runtime/components/tenon/tenon-image.vue +61 -0
  22. package/lib/runtime/components/tenon/tenon-input.vue +104 -0
  23. package/lib/runtime/components/tenon/tenon-rich-text.vue +21 -0
  24. package/lib/runtime/components/tenon/tenon-scroll-view.vue +124 -0
  25. package/lib/runtime/components/tenon/tenon-switch.vue +91 -0
  26. package/lib/runtime/components/tenon/tenon-text-area.vue +77 -0
  27. package/lib/runtime/components/tenon/tenon-text.vue +64 -0
  28. package/lib/runtime/components/tenon/tenon-view.vue +93 -0
  29. package/lib/runtime/optionProcessor.tenon.js +388 -0
  30. package/lib/style-compiler/index.js +1 -1
  31. package/lib/style-compiler/plugins/hm.js +20 -0
  32. package/lib/template-compiler/compiler.js +11 -2
  33. package/lib/tenon/index.js +104 -0
  34. package/lib/tenon/processJSON.js +356 -0
  35. package/lib/tenon/processScript.js +270 -0
  36. package/lib/tenon/processStyles.js +21 -0
  37. package/lib/tenon/processTemplate.js +133 -0
  38. package/lib/utils/get-relative-path.js +25 -0
  39. package/lib/wxss/loader.js +3 -3
  40. package/package.json +5 -2
@@ -0,0 +1,356 @@
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 isUrlRequest = require('../utils/is-url-request')
11
+
12
+ module.exports = function (json, options, rawCallback) {
13
+ const mode = options.mode
14
+ const env = options.env
15
+ const defs = options.defs
16
+ const loaderContext = options.loaderContext
17
+ const resolveMode = options.resolveMode
18
+ // const pagesMap = options.pagesMap
19
+ const componentsMap = options.componentsMap
20
+ const projectRoot = options.projectRoot
21
+ const pathHash = options.pathHash
22
+ const localPagesMap = {}
23
+ const localComponentsMap = {}
24
+ const buildInfo = loaderContext._module.buildInfo
25
+
26
+ const output = '/* json */\n'
27
+ let jsonObj = {}
28
+ let tabBarMap
29
+ let tabBarStr
30
+ const context = loaderContext.context
31
+
32
+ // const emitWarning = (msg) => {
33
+ // loaderContext.emitWarning(
34
+ // new Error('[json processor][' + loaderContext.resource + ']: ' + msg)
35
+ // )
36
+ // }
37
+
38
+ // const emitError = (msg) => {
39
+ // this.emitError(
40
+ // new Error('[json compiler][' + this.resource + ']: ' + msg)
41
+ // )
42
+ // }
43
+
44
+ // const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
45
+
46
+ const callback = (err) => {
47
+ return rawCallback(err, {
48
+ output,
49
+ jsonObj,
50
+ localPagesMap,
51
+ localComponentsMap,
52
+ tabBarMap,
53
+ tabBarStr
54
+ })
55
+ }
56
+
57
+ if (!json) {
58
+ return callback()
59
+ }
60
+ // 由于json需要提前读取在template处理中使用,src的场景已经在loader中处理了,此处无需考虑json.src的场景
61
+ try {
62
+ jsonObj = JSON5.parse(json.content)
63
+ } catch (e) {
64
+ return callback(e)
65
+ }
66
+
67
+ const fs = loaderContext._compiler.inputFileSystem
68
+
69
+ const resolve = (context, request, callback) => {
70
+ // const { queryObj } = parseRequest(request)
71
+ // todo delete. parseRequest 不会返回 context 属性
72
+ // context = queryObj.context || context
73
+ return loaderContext.resolve(context, request, callback)
74
+ }
75
+
76
+ // const defaultTabbar = {
77
+ // borderStyle: 'black',
78
+ // position: 'bottom',
79
+ // custom: false,
80
+ // isShow: true
81
+ // }
82
+
83
+ // const processTabBar = (tabBar, callback) => {
84
+ // if (tabBar) {
85
+ // tabBar = Object.assign({}, defaultTabbar, tabBar)
86
+ // tabBarMap = {}
87
+ // jsonObj.tabBar.list.forEach(({ pagePath }) => {
88
+ // tabBarMap[pagePath] = true
89
+ // })
90
+ // tabBarStr = JSON.stringify(tabBar)
91
+ // tabBarStr = tabBarStr.replace(/"(iconPath|selectedIconPath)":"([^"]+)"/g, function (matched, $1, $2) {
92
+ // if (isUrlRequest($2, projectRoot)) {
93
+ // return `"${$1}":require(${stringifyRequest(loaderUtils.urlToRequest($2, projectRoot))})`
94
+ // }
95
+ // return matched
96
+ // })
97
+ // }
98
+ // callback()
99
+ // }
100
+
101
+ const processPackages = (packages, context, callback) => {
102
+ if (packages) {
103
+ async.forEach(packages, (packagePath, callback) => {
104
+ const parsed = parseRequest(packagePath)
105
+ const queryObj = parsed.queryObj
106
+ // readFile无法处理query
107
+ packagePath = parsed.resourcePath
108
+ async.waterfall([
109
+ (callback) => {
110
+ resolve(context, packagePath, (err, result) => {
111
+ callback(err, result)
112
+ })
113
+ },
114
+ (result, callback) => {
115
+ loaderContext.addDependency(result)
116
+ fs.readFile(result, (err, content) => {
117
+ if (err) return callback(err)
118
+ callback(err, result, content.toString('utf-8'))
119
+ })
120
+ },
121
+ (result, content, callback) => {
122
+ const filePath = result
123
+ const extName = path.extname(filePath)
124
+ if (extName === '.mpx' || extName === '.vue') {
125
+ const parts = parseComponent(content, {
126
+ filePath,
127
+ needMap: loaderContext.sourceMap,
128
+ mode,
129
+ defs,
130
+ env
131
+ })
132
+ const json = parts.json || {}
133
+ if (json.content) {
134
+ content = json.content
135
+ } else if (json.src) {
136
+ return getJSONContent(json || {}, loaderContext, (err, content) => {
137
+ callback(err, result, content)
138
+ })
139
+ }
140
+ }
141
+ callback(null, result, content)
142
+ },
143
+ (result, content, callback) => {
144
+ try {
145
+ content = JSON5.parse(content)
146
+ } catch (err) {
147
+ return callback(err)
148
+ }
149
+
150
+ const processSelfQueue = []
151
+ const context = path.dirname(result)
152
+
153
+ if (content.pages) {
154
+ const tarRoot = queryObj.root
155
+ if (tarRoot) {
156
+ delete queryObj.root
157
+ const subPackage = {
158
+ tarRoot,
159
+ pages: content.pages,
160
+ ...queryObj
161
+ }
162
+ processSelfQueue.push((callback) => {
163
+ processSubPackage(subPackage, context, callback)
164
+ })
165
+ } else {
166
+ processSelfQueue.push((callback) => {
167
+ processPages(content.pages, '', '', context, callback)
168
+ })
169
+ }
170
+ }
171
+ if (content.packages) {
172
+ processSelfQueue.push((callback) => {
173
+ processPackages(content.packages, context, callback)
174
+ })
175
+ }
176
+ if (processSelfQueue.length) {
177
+ async.parallel(processSelfQueue, callback)
178
+ } else {
179
+ callback()
180
+ }
181
+ }
182
+ ], callback)
183
+ }, callback)
184
+ } else {
185
+ callback()
186
+ }
187
+ }
188
+
189
+ // const getPageName = (resourcePath, ext) => {
190
+ // const baseName = path.basename(resourcePath, ext)
191
+ // return path.join('pages', baseName + pathHash(resourcePath), baseName)
192
+ // }
193
+
194
+ const processPages = (pages, srcRoot = '', tarRoot = '', context, callback) => {
195
+ if (pages) {
196
+ context = path.join(context, srcRoot)
197
+ async.forEach(pages, (page, callback) => {
198
+ let pagePath = page
199
+ if (typeof page !== 'string') {
200
+ pagePath = page.src
201
+ }
202
+ // if (!isUrlRequest(page, projectRoot)) return callback()
203
+ // if (resolveMode === 'native') {
204
+ // page = loaderUtils.urlToRequest(page, projectRoot)
205
+ // }
206
+ // resolve(context, page, (err, resource) => {
207
+ // if (err) return callback(err)
208
+ // const { resourcePath, queryObj } = parseRequest(resource)
209
+ // const ext = path.extname(resourcePath)
210
+ // // 获取pageName
211
+ // let pageName
212
+ // if (aliasPath) {
213
+ // pageName = toPosix(path.join(tarRoot, aliasPath))
214
+ // // 判断 key 存在重复情况直接报错
215
+ // for (let key in pagesMap) {
216
+ // if (pagesMap[key] === pageName && key !== resourcePath) {
217
+ // emitError(`Current page [${resourcePath}] registers a conflict page path [${pageName}] with existed page [${key}], which is not allowed, please rename it!`)
218
+ // return callback()
219
+ // }
220
+ // }
221
+ // } else {
222
+ // const relative = path.relative(context, resourcePath)
223
+ // if (/^\./.test(relative)) {
224
+ // // 如果当前page不存在于context中,对其进行重命名
225
+ // pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
226
+ // emitWarning(`Current page [${resourcePath}] is not in current pages directory [${context}], the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
227
+ // } else {
228
+ // pageName = toPosix(path.join(tarRoot, /^(.*?)(\.[^.]*)?$/.exec(relative)[1]))
229
+ // // 如果当前page与已有page存在命名冲突,也进行重命名
230
+ // for (let key in pagesMap) {
231
+ // // 此处引入pagesMap确保相同entry下路由路径重复注册才报错,不同entry下的路由路径重复则无影响
232
+ // if (pagesMap[key] === pageName && key !== resourcePath && pagesMap[key] === loaderContext.resourcePath) {
233
+ // const pageNameRaw = pageName
234
+ // pageName = toPosix(path.join(tarRoot, getPageName(resourcePath, ext)))
235
+ // emitWarning(`Current page [${resourcePath}] is registered with a conflict page path [${pageNameRaw}] which is already existed in system, the page path will be replaced with [${pageName}], use ?resolve to get the page path and navigate to it!`)
236
+ // break
237
+ // }
238
+ // }
239
+ // }
240
+ // }
241
+ // if (pagesMap[resourcePath]) {
242
+ // emitWarning(`Current page [${resourcePath}] which is imported from [${loaderContext.resourcePath}] has been registered in pagesMap already, it will be ignored, please check it and remove the redundant page declaration!`)
243
+ // return callback()
244
+ // }
245
+ // buildInfo.pagesMap = buildInfo.pagesMap || {}
246
+ // buildInfo.pagesMap[resourcePath] = pagesMap[resourcePath] = pageName
247
+ // pagesMap[resourcePath] = loaderContext.resourcePath
248
+ localPagesMap[pagePath] = page
249
+ // callback()
250
+ // })
251
+ callback()
252
+ }, callback)
253
+ } else {
254
+ callback()
255
+ }
256
+ }
257
+
258
+ const processSubPackage = (subPackage, context, callback) => {
259
+ if (subPackage) {
260
+ const tarRoot = subPackage.tarRoot || subPackage.root || ''
261
+ const srcRoot = subPackage.srcRoot || subPackage.root || ''
262
+ if (!tarRoot) return callback()
263
+ processPages(subPackage.pages, srcRoot, tarRoot, context, callback)
264
+ } else {
265
+ callback()
266
+ }
267
+ }
268
+
269
+ const processSubPackages = (subPackages, context, callback) => {
270
+ if (subPackages) {
271
+ async.forEach(subPackages, (subPackage, callback) => {
272
+ processSubPackage(subPackage, context, callback)
273
+ }, callback)
274
+ } else {
275
+ callback()
276
+ }
277
+ }
278
+
279
+ const processComponents = (components, context, callback) => {
280
+ if (components) {
281
+ async.forEachOf(components, (component, name, callback) => {
282
+ processComponent(component, name, context, callback)
283
+ }, callback)
284
+ } else {
285
+ callback()
286
+ }
287
+ }
288
+
289
+ const processComponent = (component, name, context, callback) => {
290
+ if (!isUrlRequest(component, projectRoot)) return callback()
291
+
292
+ if (resolveMode === 'native') {
293
+ component = loaderUtils.urlToRequest(component, projectRoot)
294
+ }
295
+
296
+ resolve(context, component, (err, resource) => {
297
+ if (err) return callback(err)
298
+ const { resourcePath, queryObj } = parseRequest(resource)
299
+ const parsed = path.parse(resourcePath)
300
+ const componentId = parsed.name + pathHash(resourcePath)
301
+
302
+ buildInfo.packageName = 'main'
303
+ buildInfo.componentsMap = buildInfo.componentsMap || {}
304
+ buildInfo.componentsMap[resourcePath] = componentsMap[resourcePath] = componentId
305
+
306
+ localComponentsMap[name] = {
307
+ resource: addQuery(resource, { isComponent: true, componentId }),
308
+ async: queryObj.async
309
+ }
310
+ callback()
311
+ })
312
+ }
313
+
314
+ // const processGenerics = (generics, context, callback) => {
315
+ // if (generics) {
316
+ // async.forEachOf(generics, (generic, name, callback) => {
317
+ // if (generic.default) {
318
+ // processComponent(generic.default, `${name}default`, context, callback)
319
+ // } else {
320
+ // callback()
321
+ // }
322
+ // }, callback)
323
+ // } else {
324
+ // callback()
325
+ // }
326
+ // }
327
+
328
+ async.parallel([
329
+ (callback) => {
330
+ if (jsonObj.pages && jsonObj.pages[0]) {
331
+ // 标记首页
332
+ if (typeof jsonObj.pages[0] !== 'string') {
333
+ jsonObj.pages[0].src = addQuery(jsonObj.pages[0].src, { isFirst: true })
334
+ } else {
335
+ jsonObj.pages[0] = addQuery(jsonObj.pages[0], { isFirst: true })
336
+ }
337
+ }
338
+ processPages(jsonObj.pages, '', '', context, callback)
339
+ },
340
+ (callback) => {
341
+ processComponents(jsonObj.usingComponents, context, callback)
342
+ },
343
+ (callback) => {
344
+ processPackages(jsonObj.packages, context, callback)
345
+ },
346
+ (callback) => {
347
+ processSubPackages(jsonObj.subPackages || jsonObj.subpackages, context, callback)
348
+ }
349
+ // (callback) => {
350
+ // processGenerics(jsonObj.componentGenerics, context, callback)
351
+ // },
352
+ // (callback) => {
353
+ // processTabBar(jsonObj.tabBar, callback)
354
+ // }
355
+ ], callback)
356
+ }
@@ -0,0 +1,270 @@
1
+ const genComponentTag = require('../utils/gen-component-tag')
2
+ const loaderUtils = require('loader-utils')
3
+ const addQuery = require('../utils/add-query')
4
+ const normalize = require('../utils/normalize')
5
+ const builtInLoaderPath = normalize.lib('built-in-loader')
6
+ const optionProcessorPath = normalize.lib('runtime/optionProcessor')
7
+ const createJSONHelper = require('../json-compiler/helper')
8
+ const createHelpers = require('../helpers')
9
+ const async = require('async')
10
+ const hasOwn = require('../utils/has-own')
11
+
12
+ function shallowStringify (obj) {
13
+ const arr = []
14
+ for (const key in obj) {
15
+ if (hasOwn(obj, key)) {
16
+ let value = obj[key]
17
+ if (Array.isArray(value)) {
18
+ value = `[${value.join(',')}]`
19
+ }
20
+ arr.push(`'${key}':${value}`)
21
+ }
22
+ }
23
+ return `{${arr.join(',')}}`
24
+ }
25
+
26
+ module.exports = function (script, options, callback) {
27
+ const ctorType = options.ctorType
28
+ const builtInComponentsMap = options.builtInComponentsMap
29
+ const localComponentsMap = options.localComponentsMap
30
+ const localPagesMap = options.localPagesMap
31
+ const srcMode = options.srcMode
32
+ const loaderContext = options.loaderContext
33
+ const moduleId = options.moduleId
34
+ const isProduction = options.isProduction
35
+ const componentId = options.componentId
36
+ // const i18n = options.i18n
37
+ const jsonConfig = options.jsonConfig
38
+ // const tabBar = jsonConfig.tabBar
39
+ const tabBarMap = options.tabBarMap
40
+ // const tabBarStr = options.tabBarStr
41
+ const genericsInfo = options.genericsInfo
42
+ const componentGenerics = options.componentGenerics
43
+ const forceDisableBuiltInLoader = options.forceDisableBuiltInLoader
44
+
45
+ // add entry
46
+ // const checkEntryDeps = (callback) => {
47
+ // callback = callback || cacheCallback
48
+ // if (callback && entryDeps.size === 0) {
49
+ // callback()
50
+ // } else {
51
+ // cacheCallback = callback
52
+ // }
53
+ // }
54
+
55
+ // const addEntryDep = (context, resource, name) => {
56
+ // // 如果loader已经回调,就不再添加entry
57
+ // if (callbacked) return
58
+ // const dep = SingleEntryPlugin.createDependency(resource, name)
59
+ // entryDeps.add(dep)
60
+ // const virtualModule = new AddEntryDependency({
61
+ // context: context._compiler.context,
62
+ // dep,
63
+ // name
64
+ // })
65
+ // /* eslint-disable camelcase */
66
+ // context._module.__has_tenon_entry = true
67
+ // context._module.addDependency(virtualModule)
68
+ // entryDeps.delete(dep)
69
+ // checkEntryDeps()
70
+ // }
71
+
72
+ const emitWarning = (msg) => {
73
+ loaderContext.emitWarning(
74
+ new Error('[tenon script processor][' + loaderContext.resource + ']: ' + msg)
75
+ )
76
+ }
77
+
78
+ const emitError = (msg) => {
79
+ loaderContext.emitError(
80
+ new Error('[tenon script processor][' + loaderContext.resource + ']: ' + msg)
81
+ )
82
+ }
83
+
84
+ const {
85
+ processPage,
86
+ processDynamicEntry
87
+ } = createJSONHelper({
88
+ loaderContext,
89
+ emitWarning,
90
+ emitError
91
+ })
92
+
93
+ const { getRequire } = createHelpers(loaderContext)
94
+
95
+ const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
96
+ // let tabBarPagesMap = {}
97
+ // if (tabBar && tabBarMap) {
98
+ // // 挂载tabBar组件
99
+ // const tabBarRequest = stringifyRequest(addQuery(tabBar.custom ? './custom-tab-bar/index' : tabBarPath, { component: true }))
100
+ // tabBarPagesMap['mpx-tab-bar'] = `getComponent(require(${tabBarRequest}))`
101
+ // // 挂载tabBar页面
102
+ // Object.keys(tabBarMap).forEach((pagePath) => {
103
+ // const pageCfg = localPagesMap[pagePath]
104
+ // if (pageCfg) {
105
+ // const pageRequest = stringifyRequest(pageCfg.resource)
106
+ // if (pageCfg.async) {
107
+ // tabBarPagesMap[pagePath] = `()=>import(${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
108
+ // } else {
109
+ // tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
110
+ // }
111
+ // } else {
112
+ // emitWarning(`TabBar page path ${pagePath} is not exist in local page map, please check!`)
113
+ // }
114
+ // })
115
+ // }
116
+
117
+ let output = '/* script */\n'
118
+
119
+ let scriptSrcMode = srcMode
120
+ if (script) {
121
+ scriptSrcMode = script.mode || scriptSrcMode
122
+ } else {
123
+ script = {
124
+ tag: 'script',
125
+ content: ''
126
+ }
127
+ switch (ctorType) {
128
+ case 'app':
129
+ script.content = 'import {createApp} from "@mpxjs/core"\n' +
130
+ 'createApp({})\n'
131
+ break
132
+ case 'page':
133
+ script.content = 'import {createPage} from "@mpxjs/core"\n' +
134
+ 'createPage({})\n'
135
+ break
136
+ case 'component':
137
+ script.content = 'import {createComponent} from "@mpxjs/core"\n' +
138
+ 'createComponent({})\n'
139
+ }
140
+ }
141
+ output += genComponentTag(script, {
142
+ attrs (script) {
143
+ const attrs = Object.assign({}, script.attrs)
144
+ // src改为内联require,删除
145
+ delete attrs.src
146
+ return attrs
147
+ },
148
+ content (script) {
149
+ let content = `\n import processOption, { getComponent, getWxsMixin } from ${stringifyRequest(optionProcessorPath)}\n`
150
+ // add import
151
+ if (ctorType === 'app') {
152
+ content += ` import '@mpxjs/webpack-plugin/lib/runtime/base.styl'
153
+ import Vue from 'vue'
154
+ const VueRouter = {}
155
+ global.getApp = function(){}
156
+ global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
157
+ global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
158
+ global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}\n
159
+ global.currentPagePath = ""\n`
160
+ }
161
+ // 注入wxs模块
162
+ // content += ' const wxsModules = {}\n'
163
+ // if (options.wxsModuleMap) {
164
+ // Object.keys(options.wxsModuleMap).forEach((module) => {
165
+ // const src = loaderUtils.urlToRequest(options.wxsModuleMap[module], options.projectRoot)
166
+ // const expression = `require(${stringifyRequest(src)})`
167
+ // content += ` wxsModules.${module} = ${expression}\n`
168
+ // })
169
+ // }
170
+ const firstPage = ''
171
+ const pagesMap = {}
172
+ const componentsMap = {}
173
+
174
+ Object.keys(localComponentsMap).forEach((componentName) => {
175
+ const componentCfg = localComponentsMap[componentName]
176
+ const componentRequest = stringifyRequest(componentCfg.resource)
177
+ if (componentCfg.async) {
178
+ componentsMap[componentName] = `()=>import(${componentRequest}).then(res => getComponent(res))`
179
+ } else {
180
+ componentsMap[componentName] = `getComponent(require(${componentRequest}))`
181
+ }
182
+ })
183
+
184
+ Object.keys(builtInComponentsMap).forEach((componentName) => {
185
+ const componentCfg = builtInComponentsMap[componentName]
186
+ const componentRequest = forceDisableBuiltInLoader ? stringifyRequest(componentCfg.resource) : stringifyRequest('builtInComponent.vue!=!' + builtInLoaderPath + '!' + componentCfg.resource)
187
+ componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
188
+ })
189
+ content += ` global.currentModuleId = ${JSON.stringify(moduleId)}\n`
190
+ content += ` global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
191
+ if (!isProduction) {
192
+ content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
193
+ }
194
+ // 传递ctorType以补全js内容
195
+ const extraOptions = {
196
+ ctorType,
197
+ lang: script.lang || 'js'
198
+ }
199
+ // 使用 require 引入 script
200
+ content += ` ${getRequire('script', script, extraOptions)}\n`
201
+
202
+ // createApp/Page/Component执行完成后立刻获取当前的option并暂存
203
+ content += ` const currentOption = global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
204
+ // 获取pageConfig
205
+ const pageConfig = {}
206
+ if (ctorType === 'page') {
207
+ // 存储当前page路径
208
+ content += ` global.currentPagePath = ${JSON.stringify(loaderContext._compilation.__mpx__.pagesMap[loaderContext.resourcePath])}\n`
209
+ const uselessOptions = new Set([
210
+ 'usingComponents',
211
+ 'style',
212
+ 'singlePage'
213
+ ])
214
+ Object.keys(jsonConfig)
215
+ .filter(key => !uselessOptions.has(key))
216
+ .forEach(key => {
217
+ pageConfig[key] = jsonConfig[key]
218
+ })
219
+ }
220
+
221
+ // 配置平台转换通过createFactory在core中convertor中定义和进行
222
+ // 通过processOption进行组件注册和路由注入
223
+ content += ` export default processOption(
224
+ currentOption,
225
+ ${JSON.stringify(ctorType)},
226
+ ${JSON.stringify(firstPage)},
227
+ ${JSON.stringify(componentId)},
228
+ ${JSON.stringify(pageConfig)},
229
+ // @ts-ignore
230
+ ${shallowStringify(pagesMap)},
231
+ // @ts-ignore
232
+ ${shallowStringify(componentsMap)},
233
+ ${JSON.stringify(tabBarMap)},
234
+ ${JSON.stringify(componentGenerics)},
235
+ ${JSON.stringify(genericsInfo)},
236
+ undefined`
237
+
238
+ // if (ctorType === 'app') {
239
+ // content += `,
240
+ // Vue,
241
+ // VueRouter`
242
+ // if (i18n) {
243
+ // content += `,
244
+ // i18n`
245
+ // }
246
+ // }
247
+ content += '\n )\n__dynamic_page_slot__\n'
248
+ return content
249
+ }
250
+ })
251
+ output += '\n'
252
+ // 处理pages
253
+ const pageSet = new Set()
254
+ let dynamicPageStr = ''
255
+ async.each(localPagesMap, (pageCfg, callback) => {
256
+ if (typeof pageCfg !== 'string') pageCfg.src = addQuery(pageCfg.src, { tenon: true })
257
+ processPage(pageCfg, loaderContext.context, '', (err, entry, { key }) => {
258
+ if (err) return callback()
259
+ if (pageSet.has(key)) return callback()
260
+ pageSet.add(key)
261
+ dynamicPageStr += `\n"${entry}"`
262
+ callback()
263
+ })
264
+ }, () => {
265
+ output = output.replace('__dynamic_page_slot__', processDynamicEntry(dynamicPageStr) || '')
266
+ callback(null, {
267
+ output
268
+ })
269
+ })
270
+ }
@@ -0,0 +1,21 @@
1
+ const genComponentTag = require('../utils/gen-component-tag')
2
+
3
+ module.exports = function (styles, options, callback) {
4
+ let output = '/* styles */\n'
5
+ if (styles.length) {
6
+ styles.forEach((style) => {
7
+ output += genComponentTag(style, {
8
+ attrs (style) {
9
+ const attrs = Object.assign({}, style.attrs)
10
+ if (options.autoScope) attrs.scoped = true
11
+ return attrs
12
+ }
13
+ })
14
+ output += '\n'
15
+ })
16
+ output += '\n'
17
+ }
18
+ callback(null, {
19
+ output
20
+ })
21
+ }