@mpxjs/webpack-plugin 2.6.110 → 2.7.0-beta.10

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 (72) hide show
  1. package/lib/dependencies/AppEntryDependency.js +56 -0
  2. package/lib/dependencies/CommonJsVariableDependency.js +69 -0
  3. package/lib/dependencies/DynamicEntryDependency.js +131 -0
  4. package/lib/dependencies/FlagPluginDependency.js +23 -0
  5. package/lib/dependencies/InjectDependency.js +43 -0
  6. package/lib/dependencies/RecordGlobalComponentsDependency.js +50 -0
  7. package/lib/dependencies/RecordResourceMapDependency.js +52 -0
  8. package/lib/dependencies/RemoveEntryDependency.js +40 -0
  9. package/lib/{dependency → dependencies}/ReplaceDependency.js +19 -2
  10. package/lib/dependencies/ResolveDependency.js +84 -0
  11. package/lib/extractor.js +73 -178
  12. package/lib/file-loader.js +7 -19
  13. package/lib/helpers.js +42 -330
  14. package/lib/index.js +497 -376
  15. package/lib/json-compiler/helper.js +148 -0
  16. package/lib/json-compiler/index.js +195 -439
  17. package/lib/json-compiler/plugin.js +150 -0
  18. package/lib/json-compiler/{theme-loader.js → theme.js} +5 -3
  19. package/lib/loader.js +107 -226
  20. package/lib/native-loader.js +65 -132
  21. package/lib/parser.js +1 -2
  22. package/lib/record-loader.js +11 -0
  23. package/lib/{path-loader.js → resolve-loader.js} +0 -0
  24. package/lib/resolver/AddEnvPlugin.js +3 -2
  25. package/lib/resolver/AddModePlugin.js +3 -2
  26. package/lib/runtime/base.styl +5 -0
  27. package/lib/runtime/i18n.wxs +3 -3
  28. package/lib/runtime/optionProcessor.js +3 -3
  29. package/lib/selector.js +9 -11
  30. package/lib/style-compiler/index.js +12 -19
  31. package/lib/template-compiler/compiler.js +21 -162
  32. package/lib/template-compiler/index.js +47 -136
  33. package/lib/url-loader.js +11 -29
  34. package/lib/utils/add-query.js +1 -1
  35. package/lib/utils/const.js +9 -0
  36. package/lib/utils/emit-file.js +10 -0
  37. package/lib/utils/eval-json-js.js +31 -0
  38. package/lib/utils/get-entry-name.js +13 -0
  39. package/lib/utils/get-json-content.js +41 -0
  40. package/lib/utils/is-url-request.js +10 -1
  41. package/lib/utils/normalize.js +0 -13
  42. package/lib/utils/parse-request.js +3 -3
  43. package/lib/utils/resolve.js +13 -0
  44. package/lib/utils/set.js +47 -0
  45. package/lib/utils/stringify-loaders-resource.js +25 -0
  46. package/lib/utils/stringify-query.js +4 -0
  47. package/lib/web/processJSON.js +113 -142
  48. package/lib/web/processScript.js +32 -26
  49. package/lib/web/processTemplate.js +57 -39
  50. package/lib/wxml/{wxml-loader.js → loader.js} +24 -60
  51. package/lib/wxs/WxsModuleIdsPlugin.js +32 -0
  52. package/lib/wxs/WxsParserPlugin.js +2 -2
  53. package/lib/wxs/WxsPlugin.js +4 -8
  54. package/lib/wxs/WxsTemplatePlugin.js +46 -92
  55. package/lib/wxs/{wxs-i18n-loader.js → i18n-loader.js} +1 -3
  56. package/lib/wxs/{wxs-loader.js → loader.js} +41 -50
  57. package/lib/wxs/{wxs-pre-loader.js → pre-loader.js} +3 -4
  58. package/lib/wxss/loader.js +31 -43
  59. package/lib/wxss/localsLoader.js +1 -5
  60. package/package.json +5 -9
  61. package/lib/built-in-loader.js +0 -49
  62. package/lib/content-loader.js +0 -13
  63. package/lib/dependency/ChildCompileDependency.js +0 -24
  64. package/lib/dependency/InjectDependency.js +0 -26
  65. package/lib/dependency/RemovedModuleDependency.js +0 -23
  66. package/lib/dependency/ResolveDependency.js +0 -49
  67. package/lib/plugin-loader.js +0 -287
  68. package/lib/staticConfig.js +0 -4
  69. package/lib/utils/get-main-compilation.js +0 -6
  70. package/lib/utils/read-json-for-src.js +0 -34
  71. package/lib/utils/try-require.js +0 -16
  72. package/lib/wxss/getImportPrefix.js +0 -30
@@ -0,0 +1,150 @@
1
+ const async = require('async')
2
+ const JSON5 = require('json5')
3
+ const getEntryName = require('../utils/get-entry-name')
4
+ const FlagPluginDependency = require('../dependencies/FlagPluginDependency')
5
+ const RemoveEntryDependency = require('../dependencies/RemoveEntryDependency')
6
+ const createJSONHelper = require('./helper')
7
+ const { MPX_DISABLE_EXTRACTOR_CACHE, RESOLVE_IGNORED_ERR } = require('../utils/const')
8
+
9
+ module.exports = function (source) {
10
+ // 该loader中会在每次编译中动态添加entry,不能缓存,否则watch不好使
11
+ const nativeCallback = this.async()
12
+
13
+ const mpx = this.getMpx()
14
+
15
+ if (!mpx) {
16
+ return nativeCallback(null, source)
17
+ }
18
+
19
+ // json模块必须每次都创建(但并不是每次都需要build),用于动态添加编译入口,传递信息以禁用父级extractor的缓存
20
+ this.emitFile(MPX_DISABLE_EXTRACTOR_CACHE, '', undefined, { skipEmit: true })
21
+
22
+ this._module.addPresentationalDependency(new FlagPluginDependency())
23
+
24
+ const emitWarning = (msg) => {
25
+ this.emitWarning(
26
+ new Error('[plugin loader][' + this.resource + ']: ' + msg)
27
+ )
28
+ }
29
+
30
+ const emitError = (msg) => {
31
+ this.emitError(
32
+ new Error('[plugin loader][' + this.resource + ']: ' + msg)
33
+ )
34
+ }
35
+
36
+ const {
37
+ processPage,
38
+ processDynamicEntry,
39
+ processComponent,
40
+ processJsExport
41
+ } = createJSONHelper({
42
+ loaderContext: this,
43
+ emitWarning,
44
+ emitError
45
+ })
46
+
47
+ const context = this.context
48
+ const relativePath = this._compilation.outputOptions.publicPath || ''
49
+ const mode = mpx.mode
50
+ const srcMode = mpx.srcMode
51
+ const entryName = getEntryName(this)
52
+ // 最终输出中不需要为plugin.json产生chunk,而是使用extractor输出,删除plugin.json对应的entrypoint
53
+ if (entryName) this._module.addPresentationalDependency(new RemoveEntryDependency(entryName))
54
+
55
+ // 新模式下plugin.json输出依赖于extractor
56
+ const callback = (err, processOutput) => {
57
+ if (err) return nativeCallback(err)
58
+ let output = `var pluginEntry = ${JSON.stringify(pluginEntry, null, 2)};\n`
59
+ if (processOutput) output = processOutput(output)
60
+ output += `module.exports = JSON.stringify(pluginEntry, null, 2);\n`
61
+ nativeCallback(null, output)
62
+ }
63
+
64
+ let pluginEntry
65
+ try {
66
+ pluginEntry = JSON5.parse(source)
67
+ } catch (err) {
68
+ return callback(err)
69
+ }
70
+
71
+ const processMain = (main, callback) => {
72
+ if (!main) return callback()
73
+ processJsExport(main, context, '', (err, entry) => {
74
+ if (err === RESOLVE_IGNORED_ERR) {
75
+ delete pluginEntry.main
76
+ return callback()
77
+ }
78
+ if (err) return callback(err)
79
+ pluginEntry.main = entry
80
+ callback()
81
+ })
82
+ }
83
+
84
+ const processComponents = (components, callback) => {
85
+ if (!components) return callback()
86
+ async.eachOf(components, (component, name, callback) => {
87
+ processComponent(component, context, { relativePath }, (err, entry) => {
88
+ if (err === RESOLVE_IGNORED_ERR) {
89
+ delete components[name]
90
+ return callback()
91
+ }
92
+ if (err) return callback(err)
93
+ components[name] = entry
94
+ callback()
95
+ })
96
+ }, callback)
97
+ }
98
+
99
+ const processPages = (pages, callback) => {
100
+ if (!pages) return callback()
101
+ if (srcMode === 'ali') {
102
+ const reversedMap = {}
103
+ const publicPages = pluginEntry.publicPages || {}
104
+ Object.keys(publicPages).forEach((key) => {
105
+ const item = publicPages[key]
106
+ reversedMap[item] = key
107
+ })
108
+ pages = pages.reduce((page, target, index) => {
109
+ const key = reversedMap[page] || `__private_page_${index}__`
110
+ target[key] = page
111
+ }, {})
112
+ }
113
+
114
+ if (mode === 'ali') {
115
+ pluginEntry.publicPages = {}
116
+ pluginEntry.pages = []
117
+ }
118
+
119
+ async.eachOf(pages, (page, key) => {
120
+ processPage(page, context, '', (err, entry) => {
121
+ if (err === RESOLVE_IGNORED_ERR) {
122
+ delete pages[key]
123
+ return callback()
124
+ }
125
+ if (err) return callback(err)
126
+ if (mode === 'ali') {
127
+ pluginEntry.pages.push(entry)
128
+ if (!/^__private_page_\d+__$/.test(key)) {
129
+ pluginEntry.publicPages[key] = entry
130
+ }
131
+ } else {
132
+ pages[key] = entry
133
+ }
134
+ callback()
135
+ })
136
+ })
137
+ }
138
+
139
+ async.parallel([
140
+ (callback) => {
141
+ return processMain(pluginEntry.main, callback)
142
+ }, (callback) => {
143
+ return processComponents(pluginEntry.publicComponents, callback)
144
+ }, (callback) => {
145
+ return processPages(pluginEntry.pages, callback)
146
+ }
147
+ ], (err) => {
148
+ return callback(err, processDynamicEntry)
149
+ })
150
+ }
@@ -8,9 +8,11 @@ function isFile (request) {
8
8
  }
9
9
 
10
10
  module.exports = function (raw) {
11
- const options = loaderUtils.getOptions(this) || {}
12
- const isUrlRequest = r => isUrlRequestRaw(r, options.root)
13
- const urlToRequest = r => loaderUtils.urlToRequest(r, options.root)
11
+ const mpx = this.getMpx()
12
+ const root = mpx.projectRoot
13
+ const externals = mpx.externals
14
+ const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
15
+ const urlToRequest = r => loaderUtils.urlToRequest(r, root)
14
16
 
15
17
  const json = JSON5.parse(raw)
16
18
  let output = `var json = ${JSON.stringify(json, null, 2)};\n`
package/lib/loader.js CHANGED
@@ -2,7 +2,6 @@ const JSON5 = require('json5')
2
2
  const parseComponent = require('./parser')
3
3
  const createHelpers = require('./helpers')
4
4
  const loaderUtils = require('loader-utils')
5
- const InjectDependency = require('./dependency/InjectDependency')
6
5
  const parseRequest = require('./utils/parse-request')
7
6
  const matchCondition = require('./utils/match-condition')
8
7
  const fixUsingComponent = require('./utils/fix-using-component')
@@ -12,15 +11,16 @@ const processJSON = require('./web/processJSON')
12
11
  const processScript = require('./web/processScript')
13
12
  const processStyles = require('./web/processStyles')
14
13
  const processTemplate = require('./web/processTemplate')
15
- const readJsonForSrc = require('./utils/read-json-for-src')
14
+ const getJSONContent = require('./utils/get-json-content')
16
15
  const normalize = require('./utils/normalize')
17
- const getMainCompilation = require('./utils/get-main-compilation')
18
- const { MPX_APP_MODULE_ID } = require('./staticConfig')
16
+ const getEntryName = require('./utils/get-entry-name')
17
+ const AppEntryDependency = require('./dependencies/AppEntryDependency')
18
+ const { MPX_APP_MODULE_ID } = require('./utils/const')
19
+
19
20
  module.exports = function (content) {
20
21
  this.cacheable()
21
22
 
22
- const mainCompilation = getMainCompilation(this._compilation)
23
- const mpx = mainCompilation.__mpx__
23
+ const mpx = this.getMpx()
24
24
  if (!mpx) {
25
25
  return content
26
26
  }
@@ -28,11 +28,8 @@ module.exports = function (content) {
28
28
  const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
29
29
  const pagesMap = mpx.pagesMap
30
30
  const componentsMap = mpx.componentsMap[packageName]
31
- const resolveMode = mpx.resolveMode
32
- const projectRoot = mpx.projectRoot
33
31
  const mode = mpx.mode
34
32
  const env = mpx.env
35
- const defs = mpx.defs
36
33
  const i18n = mpx.i18n
37
34
  const globalSrcMode = mpx.srcMode
38
35
  const localSrcMode = queryObj.mode
@@ -40,21 +37,13 @@ module.exports = function (content) {
40
37
  const vueContentCache = mpx.vueContentCache
41
38
  const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
42
39
 
43
- // 支持资源query传入pagecomponent支持页面/组件单独编译
44
- if ((queryObj.component && !componentsMap[resourcePath]) || (queryObj.page && !pagesMap[resourcePath])) {
45
- let entryChunkName
46
- const rawRequest = this._module.rawRequest
47
- const _preparedEntrypoints = this._compilation._preparedEntrypoints
48
- for (let i = 0; i < _preparedEntrypoints.length; i++) {
49
- if (rawRequest === _preparedEntrypoints[i].request) {
50
- entryChunkName = _preparedEntrypoints[i].name
51
- break
52
- }
53
- }
54
- if (queryObj.component) {
55
- componentsMap[resourcePath] = entryChunkName || 'noEntryComponent'
40
+ // 支持资源query传入isPageisComponent支持页面/组件单独编译
41
+ if ((queryObj.isComponent && !componentsMap[resourcePath]) || (queryObj.isPage && !pagesMap[resourcePath])) {
42
+ const entryName = getEntryName(this)
43
+ if (queryObj.isComponent) {
44
+ componentsMap[resourcePath] = entryName || 'noEntryComponent'
56
45
  } else {
57
- pagesMap[resourcePath] = entryChunkName || 'noEntryPage'
46
+ pagesMap[resourcePath] = entryName || 'noEntryPage'
58
47
  }
59
48
  }
60
49
 
@@ -66,37 +55,17 @@ module.exports = function (content) {
66
55
  // component
67
56
  ctorType = 'component'
68
57
  }
58
+
69
59
  const loaderContext = this
70
60
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
71
61
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
72
- const options = loaderUtils.getOptions(this) || {}
73
- const processSrcQuery = (src, type) => {
74
- const localQuery = Object.assign({}, queryObj)
75
- // style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerResource
76
- if (type === 'styles') {
77
- localQuery.isStatic = true
78
- localQuery.issuerResource = this.resource
79
- } else {
80
- localQuery.resourcePath = resourcePath
81
- }
82
- if (type === 'json') {
83
- localQuery.__component = true
84
- }
85
- return addQuery(src, localQuery)
86
- }
87
-
88
62
  const filePath = resourcePath
89
-
90
- let moduleId = 'm' + mpx.pathHash(filePath)
91
- if (ctorType === 'app') {
92
- moduleId = MPX_APP_MODULE_ID
93
- }
63
+ const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
94
64
 
95
65
  const parts = parseComponent(content, {
96
66
  filePath,
97
67
  needMap: this.sourceMap,
98
68
  mode,
99
- defs,
100
69
  env
101
70
  })
102
71
 
@@ -105,24 +74,18 @@ module.exports = function (content) {
105
74
 
106
75
  async.waterfall([
107
76
  (callback) => {
108
- const json = parts.json || {}
109
- if (json.src) {
110
- readJsonForSrc(json.src, loaderContext, (err, result) => {
111
- if (err) return callback(err)
112
- json.content = result
113
- callback()
114
- })
115
- } else {
77
+ getJSONContent(parts.json || {}, loaderContext, (err, content) => {
78
+ if (err) return callback(err)
79
+ if (parts.json) parts.json.content = content
116
80
  callback()
117
- }
81
+ })
118
82
  },
119
83
  (callback) => {
120
84
  // web输出模式下没有任何inject,可以通过cache直接返回,由于读取src json可能会新增模块依赖,需要在之后返回缓存内容
121
85
  if (vueContentCache.has(filePath)) {
122
86
  return callback(null, vueContentCache.get(filePath))
123
87
  }
124
- // 只有ali才可能需要scoped
125
- const hasScoped = (parts.styles.some(({ scoped }) => scoped) || autoScope) && mode === 'ali'
88
+ const hasScoped = parts.styles.some(({ scoped }) => scoped) || autoScope
126
89
  const templateAttrs = parts.template && parts.template.attrs
127
90
  const hasComment = templateAttrs && templateAttrs.comments
128
91
  const isNative = false
@@ -146,27 +109,10 @@ module.exports = function (content) {
146
109
  }
147
110
  }
148
111
 
149
- const {
150
- getRequire,
151
- getRequireForSrc,
152
- getRequestString,
153
- getSrcRequestString
154
- } = createHelpers({
155
- loaderContext,
156
- options,
157
- moduleId,
158
- hasScoped,
159
- hasComment,
160
- usingComponents,
161
- srcMode,
162
- isNative,
163
- projectRoot
164
- })
165
-
166
112
  // 处理mode为web时输出vue格式文件
167
113
  if (mode === 'web') {
168
- if (ctorType === 'app' && !queryObj.app) {
169
- const request = addQuery(this.resource, { app: true })
114
+ if (ctorType === 'app' && !queryObj.isApp) {
115
+ const request = addQuery(this.resource, { isApp: true })
170
116
  output += `
171
117
  import App from ${stringifyRequest(request)}
172
118
  import Vue from 'vue'
@@ -187,19 +133,15 @@ module.exports = function (content) {
187
133
  async.parallel([
188
134
  (callback) => {
189
135
  processTemplate(parts.template, {
136
+ loaderContext,
137
+ hasScoped,
190
138
  hasComment,
191
139
  isNative,
192
- mode,
193
140
  srcMode,
194
- defs,
195
- loaderContext,
196
141
  moduleId,
197
142
  ctorType,
198
143
  usingComponents,
199
- componentGenerics,
200
- decodeHTMLText: mpx.decodeHTMLText,
201
- externalClasses: mpx.externalClasses,
202
- checkUsingComponents: mpx.checkUsingComponents
144
+ componentGenerics
203
145
  }, callback)
204
146
  },
205
147
  (callback) => {
@@ -211,16 +153,9 @@ module.exports = function (content) {
211
153
  },
212
154
  (callback) => {
213
155
  processJSON(parts.json, {
214
- mode,
215
- env,
216
- defs,
217
- resolveMode,
218
156
  loaderContext,
219
157
  pagesMap,
220
- pagesEntryMap: mpx.pagesEntryMap,
221
- pathHash: mpx.pathHash,
222
- componentsMap,
223
- projectRoot
158
+ componentsMap
224
159
  }, callback)
225
160
  }
226
161
  ], (err, res) => {
@@ -236,24 +171,20 @@ module.exports = function (content) {
236
171
  }
237
172
 
238
173
  processScript(parts.script, {
174
+ loaderContext,
239
175
  ctorType,
240
176
  srcMode,
241
- loaderContext,
242
177
  isProduction,
243
- getRequireForSrc,
244
- i18n,
245
178
  componentGenerics,
246
- projectRoot,
247
179
  jsonConfig: jsonRes.jsonObj,
248
- componentId: queryObj.componentId || '',
180
+ outputPath: queryObj.outputPath || '',
249
181
  tabBarMap: jsonRes.tabBarMap,
250
182
  tabBarStr: jsonRes.tabBarStr,
251
183
  builtInComponentsMap: templateRes.builtInComponentsMap,
252
184
  genericsInfo: templateRes.genericsInfo,
253
185
  wxsModuleMap: templateRes.wxsModuleMap,
254
186
  localComponentsMap: jsonRes.localComponentsMap,
255
- localPagesMap: jsonRes.localPagesMap,
256
- forceDisableBuiltInLoader: mpx.forceDisableBuiltInLoader
187
+ localPagesMap: jsonRes.localPagesMap
257
188
  }, callback)
258
189
  }
259
190
  ], (err, scriptRes) => {
@@ -264,37 +195,37 @@ module.exports = function (content) {
264
195
  })
265
196
  }
266
197
 
267
- // 触发webpack global var 注入
268
- output += 'global.currentModuleId\n'
198
+ const moduleGraph = this._compilation.moduleGraph
199
+
200
+ const issuer = moduleGraph.getIssuer(this._module)
201
+
202
+ if (issuer) {
203
+ return callback(new Error(`Current ${ctorType} [${this.resourcePath}] is issued by [${issuer.resource}], which is not allowed!`))
204
+ }
205
+
206
+ if (ctorType === 'app') {
207
+ const appName = getEntryName(this)
208
+ this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
209
+ }
210
+
211
+ const {
212
+ getRequire
213
+ } = createHelpers(loaderContext)
269
214
 
270
- // todo loader中inject dep比较危险,watch模式下不一定靠谱,可考虑将import改为require然后通过修改loader内容注入
271
215
  // 注入模块id及资源路径
272
- let globalInjectCode = `global.currentModuleId = ${JSON.stringify(moduleId)}\n`
216
+ output += `global.currentModuleId = ${JSON.stringify(moduleId)}\n`
273
217
  if (!isProduction) {
274
- globalInjectCode += `global.currentResource = ${JSON.stringify(filePath)}\n`
218
+ output += `global.currentResource = ${JSON.stringify(filePath)}\n`
275
219
  }
276
-
277
- if (i18n && (ctorType === 'app' || (ctorType === 'page' && queryObj.isIndependent)) && !mpx.forceDisableInject) {
278
- const i18nMethodsVar = 'i18nMethods'
220
+ // 为app或独立分包页面注入i18n
221
+ if (i18n && (ctorType === 'app' || (ctorType === 'page' && queryObj.isIndependent))) {
279
222
  const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
280
- const i18nWxsLoaderPath = normalize.lib('wxs/wxs-i18n-loader.js')
223
+ const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
281
224
  const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
282
- const expression = `require(${loaderUtils.stringifyRequest(loaderContext, i18nWxsRequest)})`
283
- const deps = []
284
- this._module.parser.parse(expression, {
285
- current: {
286
- addDependency: dep => {
287
- dep.userRequest = i18nMethodsVar
288
- deps.push(dep)
289
- }
290
- },
291
- module: this._module
292
- })
293
- this._module.addVariable(i18nMethodsVar, expression, deps)
294
225
 
295
- globalInjectCode += `if (!global.i18n) {
226
+ output += `if (!global.i18n) {
296
227
  global.i18n = ${JSON.stringify({ locale: i18n.locale, version: 0 })}
297
- global.i18nMethods = ${i18nMethodsVar}
228
+ global.i18nMethods = require(${loaderUtils.stringifyRequest(loaderContext, i18nWxsRequest)})
298
229
  }\n`
299
230
  }
300
231
  // 注入构造函数
@@ -309,101 +240,50 @@ module.exports = function (content) {
309
240
  } else if (ctorType === 'component') {
310
241
  ctor = 'Component'
311
242
  }
312
- globalInjectCode += `global.currentCtor = ${ctor}\n`
313
- globalInjectCode += `global.currentResourceType = '${ctorType}'\n`
314
- globalInjectCode += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
243
+ output += `global.currentCtor = ${ctor}\n`
244
+ output += `global.currentCtorType = ${JSON.stringify(ctor.replace(/^./, (match) => {
315
245
  return match.toLowerCase()
316
246
  }))}\n`
247
+ output += `global.currentResourceType = '${ctorType}'\n`
317
248
 
318
- // <script>
319
- output += '/* script */\n'
320
- let scriptSrcMode = srcMode
321
- const script = parts.script
322
- if (script) {
323
- scriptSrcMode = script.mode || scriptSrcMode
324
- let scriptRequestString
325
- if (script.src) {
326
- // 传入resourcePath以确保后续处理中能够识别src引入的资源为组件主资源
327
- script.src = processSrcQuery(script.src, 'script')
328
- scriptRequestString = getSrcRequestString('script', script)
329
- } else {
330
- scriptRequestString = getRequestString('script', script)
331
- }
332
- if (scriptRequestString) {
333
- output += 'export * from ' + scriptRequestString + '\n\n'
334
- if (ctorType === 'app') {
335
- mpx.appScriptRawRequest = JSON.parse(scriptRequestString)
336
- mpx.appScriptPromise = new Promise((resolve) => {
337
- mpx.appScriptPromiseResolve = resolve
338
- })
339
- }
340
- }
341
- } else {
342
- switch (ctorType) {
343
- case 'app':
344
- output += 'import {createApp} from "@mpxjs/core"\n' +
345
- 'createApp({})\n'
346
- break
347
- case 'page':
348
- output += 'import {createPage} from "@mpxjs/core"\n' +
349
- 'createPage({})\n'
350
- break
351
- case 'component':
352
- output += 'import {createComponent} from "@mpxjs/core"\n' +
353
- 'createComponent({})\n'
354
- }
355
- output += '\n'
356
- }
249
+ // template
250
+ output += '/* template */\n'
251
+ const template = parts.template
357
252
 
358
- if (scriptSrcMode) {
359
- globalInjectCode += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
253
+ if (template) {
254
+ const extraOptions = {
255
+ hasScoped,
256
+ hasComment,
257
+ isNative,
258
+ moduleId,
259
+ usingComponents
260
+ // 添加babel处理渲染函数中可能包含的...展开运算符
261
+ // 由于...运算符应用范围极小以及babel成本极高,先关闭此特性后续看情况打开
262
+ // needBabel: true
263
+ }
264
+ if (template.src) extraOptions.resourcePath = resourcePath
265
+ // 基于global.currentInject来注入模板渲染函数和refs等信息
266
+ output += getRequire('template', template, extraOptions) + '\n'
360
267
  }
361
268
 
362
269
  // styles
363
270
  output += '/* styles */\n'
364
- let cssModules
365
271
  if (parts.styles.length) {
366
- let styleInjectionCode = ''
367
272
  parts.styles.forEach((style, i) => {
368
- let scoped = hasScoped ? (style.scoped || autoScope) : false
369
- let requireString
273
+ const scoped = style.scoped || autoScope
274
+ const extraOptions = {
275
+ moduleId,
276
+ scoped
277
+ }
370
278
  // require style
371
279
  if (style.src) {
372
- style.src = processSrcQuery(style.src, 'styles')
373
- requireString = getRequireForSrc('styles', style, -1, scoped)
374
- } else {
375
- requireString = getRequire('styles', style, i, scoped)
376
- }
377
- const hasStyleLoader = requireString.indexOf('style-loader') > -1
378
- const invokeStyle = code => `${code}\n`
379
-
380
- const moduleName = style.module === true ? '$style' : style.module
381
- // setCssModule
382
- if (moduleName) {
383
- if (!cssModules) {
384
- cssModules = {}
385
- }
386
- if (moduleName in cssModules) {
387
- loaderContext.emitError(
388
- 'CSS module name "' + moduleName + '" is not unique!'
389
- )
390
- styleInjectionCode += invokeStyle(requireString)
391
- } else {
392
- cssModules[moduleName] = true
393
-
394
- if (!hasStyleLoader) {
395
- requireString += '.locals'
396
- }
397
-
398
- styleInjectionCode += invokeStyle(
399
- 'this["' + moduleName + '"] = ' + requireString
400
- )
401
- }
402
- } else {
403
- styleInjectionCode += invokeStyle(requireString)
280
+ // style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerFile
281
+ extraOptions.isStatic = true
282
+ const issuerResource = addQuery(this.resource, { type: 'styles' }, true)
283
+ extraOptions.issuerFile = mpx.getExtractedFile(issuerResource)
404
284
  }
285
+ output += getRequire('styles', style, extraOptions, i) + '\n'
405
286
  })
406
- output += styleInjectionCode + '\n'
407
287
  } else if (ctorType === 'app' && mode === 'ali') {
408
288
  output += getRequire('styles', {}) + '\n'
409
289
  }
@@ -412,34 +292,35 @@ module.exports = function (content) {
412
292
  output += '/* json */\n'
413
293
  // 给予json默认值, 确保生成json request以自动补全json
414
294
  const json = parts.json || {}
415
- if (json.src) {
416
- json.src = processSrcQuery(json.src, 'json')
417
- output += getRequireForSrc('json', json) + '\n\n'
418
- } else {
419
- output += getRequire('json', json) + '\n\n'
420
- }
421
-
422
- // template
423
- output += '/* template */\n'
424
- const template = parts.template
295
+ output += getRequire('json', json, json.src && { resourcePath }) + '\n'
425
296
 
426
- if (template) {
427
- if (template.src) {
428
- template.src = processSrcQuery(template.src, 'template')
429
- output += getRequireForSrc('template', template) + '\n\n'
430
- } else {
431
- output += getRequire('template', template) + '\n\n'
297
+ // script
298
+ output += '/* script */\n'
299
+ let scriptSrcMode = srcMode
300
+ const script = parts.script
301
+ if (script) {
302
+ scriptSrcMode = script.mode || scriptSrcMode
303
+ if (scriptSrcMode) output += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
304
+ const extraOptions = {}
305
+ if (script.src) extraOptions.resourcePath = resourcePath
306
+ output += getRequire('script', script, extraOptions) + '\n'
307
+ } else {
308
+ // todo 依然创建request在selector中进行补全或者将i18n通过CommonJsVariableDependency改造为initFragments的方式进行注入,否则在app.mpx中没有script区块的情况下无法保证i18n注入代码在@mpxjs/core之前执行
309
+ switch (ctorType) {
310
+ case 'app':
311
+ output += 'import {createApp} from "@mpxjs/core"\n' +
312
+ 'createApp({})\n'
313
+ break
314
+ case 'page':
315
+ output += 'import {createPage} from "@mpxjs/core"\n' +
316
+ 'createPage({})\n'
317
+ break
318
+ case 'component':
319
+ output += 'import {createComponent} from "@mpxjs/core"\n' +
320
+ 'createComponent({})\n'
432
321
  }
322
+ output += '\n'
433
323
  }
434
-
435
- if (!mpx.forceDisableInject) {
436
- const dep = new InjectDependency({
437
- content: globalInjectCode,
438
- index: -3
439
- })
440
- this._module.addDependency(dep)
441
- }
442
-
443
324
  callback(null, output)
444
325
  }
445
326
  ], callback)