@mpxjs/webpack-plugin 2.6.113 → 2.6.114-alpha.2

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