@mpxjs/webpack-plugin 2.6.114-alpha.8 → 2.6.115

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