@mpxjs/webpack-plugin 2.8.21 → 2.8.23-alpha

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 (39) 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/DynamicEntryDependency.js +14 -1
  5. package/lib/dependencies/ResolveDependency.js +4 -0
  6. package/lib/index.js +52 -7
  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 +262 -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/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,262 @@
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 async = require('async')
9
+ const hasOwn = require('../utils/has-own')
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
+ module.exports = function (script, options, callback) {
26
+ const ctorType = options.ctorType
27
+ const builtInComponentsMap = options.builtInComponentsMap
28
+ const localComponentsMap = options.localComponentsMap
29
+ const localPagesMap = options.localPagesMap
30
+ const srcMode = options.srcMode
31
+ const loaderContext = options.loaderContext
32
+ const isProduction = options.isProduction
33
+ const componentId = options.componentId
34
+ // const i18n = options.i18n
35
+ const jsonConfig = options.jsonConfig
36
+ // const tabBar = jsonConfig.tabBar
37
+ const tabBarMap = options.tabBarMap
38
+ // const tabBarStr = options.tabBarStr
39
+ const genericsInfo = options.genericsInfo
40
+ const componentGenerics = options.componentGenerics
41
+ const forceDisableBuiltInLoader = options.forceDisableBuiltInLoader
42
+
43
+ // add entry
44
+ // const checkEntryDeps = (callback) => {
45
+ // callback = callback || cacheCallback
46
+ // if (callback && entryDeps.size === 0) {
47
+ // callback()
48
+ // } else {
49
+ // cacheCallback = callback
50
+ // }
51
+ // }
52
+
53
+ // const addEntryDep = (context, resource, name) => {
54
+ // // 如果loader已经回调,就不再添加entry
55
+ // if (callbacked) return
56
+ // const dep = SingleEntryPlugin.createDependency(resource, name)
57
+ // entryDeps.add(dep)
58
+ // const virtualModule = new AddEntryDependency({
59
+ // context: context._compiler.context,
60
+ // dep,
61
+ // name
62
+ // })
63
+ // /* eslint-disable camelcase */
64
+ // context._module.__has_tenon_entry = true
65
+ // context._module.addDependency(virtualModule)
66
+ // entryDeps.delete(dep)
67
+ // checkEntryDeps()
68
+ // }
69
+
70
+ const emitWarning = (msg) => {
71
+ loaderContext.emitWarning(
72
+ new Error('[tenon script processor][' + loaderContext.resource + ']: ' + msg)
73
+ )
74
+ }
75
+
76
+ const emitError = (msg) => {
77
+ loaderContext.emitError(
78
+ new Error('[tenon script processor][' + loaderContext.resource + ']: ' + msg)
79
+ )
80
+ }
81
+
82
+ const {
83
+ processPage,
84
+ processDynamicEntry
85
+ } = createJSONHelper({
86
+ loaderContext,
87
+ emitWarning,
88
+ emitError
89
+ })
90
+
91
+ const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
92
+ // let tabBarPagesMap = {}
93
+ // if (tabBar && tabBarMap) {
94
+ // // 挂载tabBar组件
95
+ // const tabBarRequest = stringifyRequest(addQuery(tabBar.custom ? './custom-tab-bar/index' : tabBarPath, { component: true }))
96
+ // tabBarPagesMap['mpx-tab-bar'] = `getComponent(require(${tabBarRequest}))`
97
+ // // 挂载tabBar页面
98
+ // Object.keys(tabBarMap).forEach((pagePath) => {
99
+ // const pageCfg = localPagesMap[pagePath]
100
+ // if (pageCfg) {
101
+ // const pageRequest = stringifyRequest(pageCfg.resource)
102
+ // if (pageCfg.async) {
103
+ // tabBarPagesMap[pagePath] = `()=>import(${pageRequest}).then(res => getComponent(res, { __mpxPageRoute: ${JSON.stringify(pagePath)} }))`
104
+ // } else {
105
+ // tabBarPagesMap[pagePath] = `getComponent(require(${pageRequest}), { __mpxPageRoute: ${JSON.stringify(pagePath)} })`
106
+ // }
107
+ // } else {
108
+ // emitWarning(`TabBar page path ${pagePath} is not exist in local page map, please check!`)
109
+ // }
110
+ // })
111
+ // }
112
+
113
+ let output = '/* script */\n'
114
+
115
+ let scriptSrcMode = srcMode
116
+ if (script) {
117
+ scriptSrcMode = script.mode || scriptSrcMode
118
+ } else {
119
+ script = {
120
+ tag: 'script',
121
+ content: ''
122
+ }
123
+ switch (ctorType) {
124
+ case 'app':
125
+ script.content = 'import {createApp} from "@mpxjs/core"\n' +
126
+ 'createApp({})\n'
127
+ break
128
+ case 'page':
129
+ script.content = 'import {createPage} from "@mpxjs/core"\n' +
130
+ 'createPage({})\n'
131
+ break
132
+ case 'component':
133
+ script.content = 'import {createComponent} from "@mpxjs/core"\n' +
134
+ 'createComponent({})\n'
135
+ }
136
+ }
137
+ output += genComponentTag(script, {
138
+ attrs (script) {
139
+ const attrs = Object.assign({}, script.attrs)
140
+ // src改为内联require,删除
141
+ delete attrs.src
142
+ return attrs
143
+ },
144
+ content (script) {
145
+ let content = `\n import processOption, { getComponent, getWxsMixin } from ${stringifyRequest(optionProcessorPath)}\n`
146
+ // add import
147
+ if (ctorType === 'app') {
148
+ content += ` import '@mpxjs/webpack-plugin/lib/runtime/base.styl'
149
+ import Vue from 'vue'
150
+ const VueRouter = {}
151
+ global.getApp = function(){}
152
+ global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
153
+ global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
154
+ global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}\n
155
+ global.currentPagePath = ""\n`
156
+ }
157
+ // 注入wxs模块
158
+ // content += ' const wxsModules = {}\n'
159
+ // if (options.wxsModuleMap) {
160
+ // Object.keys(options.wxsModuleMap).forEach((module) => {
161
+ // const src = loaderUtils.urlToRequest(options.wxsModuleMap[module], options.projectRoot)
162
+ // const expression = `require(${stringifyRequest(src)})`
163
+ // content += ` wxsModules.${module} = ${expression}\n`
164
+ // })
165
+ // }
166
+ const firstPage = ''
167
+ const pagesMap = {}
168
+ const componentsMap = {}
169
+
170
+ Object.keys(localComponentsMap).forEach((componentName) => {
171
+ const componentCfg = localComponentsMap[componentName]
172
+ const componentRequest = stringifyRequest(componentCfg.resource)
173
+ if (componentCfg.async) {
174
+ componentsMap[componentName] = `()=>import(${componentRequest}).then(res => getComponent(res))`
175
+ } else {
176
+ componentsMap[componentName] = `getComponent(require(${componentRequest}))`
177
+ }
178
+ })
179
+
180
+ Object.keys(builtInComponentsMap).forEach((componentName) => {
181
+ const componentCfg = builtInComponentsMap[componentName]
182
+ const componentRequest = forceDisableBuiltInLoader ? stringifyRequest(componentCfg.resource) : stringifyRequest('builtInComponent.vue!=!' + builtInLoaderPath + '!' + componentCfg.resource)
183
+ componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
184
+ })
185
+
186
+ content += ` global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
187
+ if (!isProduction) {
188
+ content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
189
+ }
190
+ // 为了正确获取currentSrcMode便于运行时进行转换,对于src引入的组件script采用require方式引入(由于webpack会将import的执行顺序上升至最顶),这意味着对于src引入脚本中的named export将不会生效,不过鉴于mpx和小程序中本身也没有在组件script中声明export的用法,所以应该没有影响
191
+ content += script.src
192
+ ? `require(${stringifyRequest(script.src)})\n`
193
+ : (script.content + '\n') + '\n'
194
+ // createApp/Page/Component执行完成后立刻获取当前的option并暂存
195
+ content += ' const currentOption = global.currentOption\n'
196
+ // 获取pageConfig
197
+ const pageConfig = {}
198
+ if (ctorType === 'page') {
199
+ // 存储当前page路径
200
+ content += ` global.currentPagePath = ${JSON.stringify(loaderContext._compilation.__mpx__.pagesMap[loaderContext.resourcePath])}\n`
201
+ const uselessOptions = new Set([
202
+ 'usingComponents',
203
+ 'style',
204
+ 'singlePage'
205
+ ])
206
+ Object.keys(jsonConfig)
207
+ .filter(key => !uselessOptions.has(key))
208
+ .forEach(key => {
209
+ pageConfig[key] = jsonConfig[key]
210
+ })
211
+ }
212
+
213
+ // 配置平台转换通过createFactory在core中convertor中定义和进行
214
+ // 通过processOption进行组件注册和路由注入
215
+ content += ` export default processOption(
216
+ currentOption,
217
+ ${JSON.stringify(ctorType)},
218
+ ${JSON.stringify(firstPage)},
219
+ ${JSON.stringify(componentId)},
220
+ ${JSON.stringify(pageConfig)},
221
+ // @ts-ignore
222
+ ${shallowStringify(pagesMap)},
223
+ // @ts-ignore
224
+ ${shallowStringify(componentsMap)},
225
+ ${JSON.stringify(tabBarMap)},
226
+ ${JSON.stringify(componentGenerics)},
227
+ ${JSON.stringify(genericsInfo)},
228
+ undefined`
229
+
230
+ // if (ctorType === 'app') {
231
+ // content += `,
232
+ // Vue,
233
+ // VueRouter`
234
+ // if (i18n) {
235
+ // content += `,
236
+ // i18n`
237
+ // }
238
+ // }
239
+ content += '\n )\n__dynamic_page_slot__\n'
240
+ return content
241
+ }
242
+ })
243
+ output += '\n'
244
+ // 处理pages
245
+ const pageSet = new Set()
246
+ let dynamicPageStr = ''
247
+ async.each(localPagesMap, (pageCfg, callback) => {
248
+ if (typeof pageCfg !== 'string') pageCfg.src = addQuery(pageCfg.src, { tenon: true })
249
+ processPage(pageCfg, loaderContext.context, '', (err, entry, { key }) => {
250
+ if (err) return callback()
251
+ if (pageSet.has(key)) return callback()
252
+ pageSet.add(key)
253
+ dynamicPageStr += `\n"${entry}"`
254
+ callback()
255
+ })
256
+ }, () => {
257
+ output = output.replace('__dynamic_page_slot__', processDynamicEntry(dynamicPageStr) || '')
258
+ callback(null, {
259
+ output
260
+ })
261
+ })
262
+ }
@@ -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
+ }