@mpxjs/webpack-plugin 2.7.50-alpha.3 → 2.7.52

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.
@@ -68,24 +68,35 @@ class DynamicEntryDependency extends NullDependency {
68
68
  // export类型的resultPath需要添加.js后缀
69
69
  if (entryType === 'export') resultPath += '.js'
70
70
 
71
- if (alreadyOutputted) return callback(null, { resultPath })
72
-
73
71
  // 对于常规js模块不应添加packageRoot避免冗余
74
72
  if (packageRoot && entryType !== 'export') {
75
73
  resource = addQuery(resource, { packageRoot }, true)
76
74
  }
77
75
 
78
- mpx.addEntry(resource, filename, (err, entryModule) => {
79
- if (err) return callback(err)
80
- if (entryType === 'export') {
81
- mpx.exportModules.add(entryModule)
82
- }
83
- originEntryNode.addChild(mpx.getEntryNode(entryModule, entryType))
84
- return callback(null, {
85
- resultPath,
86
- entryModule
76
+ const key = resource + filename
77
+ let addEntryPromise
78
+
79
+ if (alreadyOutputted) {
80
+ addEntryPromise = mpx.addEntryPromiseMap.get(key) || Promise.resolve()
81
+ } else {
82
+ addEntryPromise = new Promise((resolve, reject) => {
83
+ mpx.addEntry(resource, filename, (err, entryModule) => {
84
+ if (err) return reject(err)
85
+ if (entryType === 'export') {
86
+ mpx.exportModules.add(entryModule)
87
+ }
88
+ resolve(entryModule)
89
+ })
87
90
  })
88
- })
91
+ mpx.addEntryPromiseMap.set(key, addEntryPromise)
92
+ }
93
+
94
+ addEntryPromise
95
+ .then(entryModule => {
96
+ if (entryModule) originEntryNode.addChild(mpx.getEntryNode(entryModule, entryType))
97
+ callback(null, { resultPath })
98
+ })
99
+ .catch(err => callback(err))
89
100
  }
90
101
  ], callback)
91
102
  }
@@ -0,0 +1,43 @@
1
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
+ const makeSerializable = require('webpack/lib/util/makeSerializable')
3
+
4
+ class RecordVueContentDependency extends NullDependency {
5
+ constructor (resourcePath, content) {
6
+ super()
7
+ this.resourcePath = resourcePath
8
+ this.content = content
9
+ }
10
+
11
+ get type () {
12
+ return 'mpx record vue content'
13
+ }
14
+
15
+ mpxAction (module, compilation, callback) {
16
+ const mpx = compilation.__mpx__
17
+ mpx.vueContentCache.set(this.resourcePath, this.content)
18
+ return callback()
19
+ }
20
+
21
+ serialize (context) {
22
+ const { write } = context
23
+ write(this.resourcePath)
24
+ write(this.content)
25
+ super.serialize(context)
26
+ }
27
+
28
+ deserialize (context) {
29
+ const { read } = context
30
+ this.resourcePath = read()
31
+ this.content = read()
32
+ super.deserialize(context)
33
+ }
34
+ }
35
+
36
+ RecordVueContentDependency.Template = class RecordVueContentDependencyTemplate {
37
+ apply () {
38
+ }
39
+ }
40
+
41
+ makeSerializable(RecordVueContentDependency, '@mpxjs/webpack-plugin/lib/dependencies/RecordVueContentDependency')
42
+
43
+ module.exports = RecordVueContentDependency
package/lib/index.js CHANGED
@@ -35,6 +35,7 @@ const RecordIndependentDependency = require('./dependencies/RecordIndependentDep
35
35
  const DynamicEntryDependency = require('./dependencies/DynamicEntryDependency')
36
36
  const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
37
37
  const RemoveEntryDependency = require('./dependencies/RemoveEntryDependency')
38
+ const RecordVueContentDependency = require('./dependencies/RecordVueContentDependency')
38
39
  const SplitChunksPlugin = require('webpack/lib/optimize/SplitChunksPlugin')
39
40
  const PartialCompilePlugin = require('./partial-compile/index')
40
41
  const fixRelative = require('./utils/fix-relative')
@@ -498,6 +499,9 @@ class MpxWebpackPlugin {
498
499
 
499
500
  compilation.dependencyFactories.set(CommonJsAsyncDependency, normalModuleFactory)
500
501
  compilation.dependencyTemplates.set(CommonJsAsyncDependency, new CommonJsAsyncDependency.Template())
502
+
503
+ compilation.dependencyFactories.set(RecordVueContentDependency, new NullFactory())
504
+ compilation.dependencyTemplates.set(RecordVueContentDependency, new RecordVueContentDependency.Template())
501
505
  })
502
506
 
503
507
  compiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation, { normalModuleFactory }) => {
@@ -539,6 +543,7 @@ class MpxWebpackPlugin {
539
543
  usingComponents: {},
540
544
  // todo es6 map读写性能高于object,之后会逐步替换
541
545
  wxsAssetsCache: new Map(),
546
+ addEntryPromiseMap: new Map(),
542
547
  currentPackageRoot: '',
543
548
  wxsContentMap: {},
544
549
  forceUsePageCtor: this.options.forceUsePageCtor,
@@ -557,6 +562,7 @@ class MpxWebpackPlugin {
557
562
  nativeConfig: this.options.nativeConfig,
558
563
  // 输出web专用配置
559
564
  webConfig: this.options.webConfig,
565
+ vueContentCache: new Map(),
560
566
  tabBarMap: {},
561
567
  defs: preProcessDefs(this.options.defs),
562
568
  i18n: this.options.i18n,
@@ -1414,11 +1420,11 @@ try {
1414
1420
  let mpxStyleLoaderIndex = -1
1415
1421
  loaders.forEach((loader, index) => {
1416
1422
  const currentLoader = toPosix(loader.loader)
1417
- if (currentLoader.includes('css-loader')) {
1423
+ if (currentLoader.includes('css-loader') && cssLoaderIndex === -1) {
1418
1424
  cssLoaderIndex = index
1419
- } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader')) {
1425
+ } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader') && vueStyleLoaderIndex === -1) {
1420
1426
  vueStyleLoaderIndex = index
1421
- } else if (currentLoader.includes(styleCompilerPath)) {
1427
+ } else if (currentLoader.includes(styleCompilerPath) && mpxStyleLoaderIndex === -1) {
1422
1428
  mpxStyleLoaderIndex = index
1423
1429
  }
1424
1430
  })
package/lib/loader.js CHANGED
@@ -16,6 +16,7 @@ const normalize = require('./utils/normalize')
16
16
  const getEntryName = require('./utils/get-entry-name')
17
17
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
18
18
  const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
19
+ const RecordVueContentDependency = require('./dependencies/RecordVueContentDependency')
19
20
  const CommonJsVariableDependency = require('./dependencies/CommonJsVariableDependency')
20
21
  const { MPX_APP_MODULE_ID } = require('./utils/const')
21
22
  const path = require('path')
@@ -137,6 +138,10 @@ module.exports = function (content) {
137
138
  return callback(null, output)
138
139
  }
139
140
 
141
+ // 通过RecordVueContentDependency和vueContentCache确保子request不再重复生成vueContent
142
+ const cacheContent = mpx.vueContentCache.get(filePath)
143
+ if (cacheContent) return callback(null, cacheContent)
144
+
140
145
  return async.waterfall([
141
146
  (callback) => {
142
147
  async.parallel([
@@ -183,6 +188,7 @@ module.exports = function (content) {
183
188
  loaderContext,
184
189
  ctorType,
185
190
  srcMode,
191
+ moduleId,
186
192
  isProduction,
187
193
  componentGenerics,
188
194
  jsonConfig: jsonRes.jsonObj,
@@ -199,6 +205,7 @@ module.exports = function (content) {
199
205
  ], (err, scriptRes) => {
200
206
  if (err) return callback(err)
201
207
  output += scriptRes.output
208
+ this._module.addPresentationalDependency(new RecordVueContentDependency(filePath, output))
202
209
  callback(null, output)
203
210
  })
204
211
  }
@@ -265,10 +272,9 @@ module.exports = function (content) {
265
272
 
266
273
  if (template) {
267
274
  const extraOptions = {
268
- ...template.src ? {
269
- ...queryObj,
270
- resourcePath
271
- } : null,
275
+ ...template.src
276
+ ? { ...queryObj, resourcePath }
277
+ : null,
272
278
  hasScoped,
273
279
  hasComment,
274
280
  isNative,
@@ -290,11 +296,9 @@ module.exports = function (content) {
290
296
  const scoped = style.scoped || autoScope
291
297
  const extraOptions = {
292
298
  // style src会被特殊处理为全局复用样式,不添加resourcePath,添加isStatic及issuerFile
293
- ...style.src ? {
294
- ...queryObj,
295
- isStatic: true,
296
- issuerResource: addQuery(this.resource, { type: 'styles' }, true)
297
- } : null,
299
+ ...style.src
300
+ ? { ...queryObj, isStatic: true, issuerResource: addQuery(this.resource, { type: 'styles' }, true) }
301
+ : null,
298
302
  moduleId,
299
303
  scoped
300
304
  }
@@ -311,10 +315,7 @@ module.exports = function (content) {
311
315
  output += '/* json */\n'
312
316
  // 给予json默认值, 确保生成json request以自动补全json
313
317
  const json = parts.json || {}
314
- output += getRequire('json', json, json.src && {
315
- ...queryObj,
316
- resourcePath
317
- }) + '\n'
318
+ output += getRequire('json', json, json.src && { ...queryObj, resourcePath }) + '\n'
318
319
 
319
320
  // script
320
321
  output += '/* script */\n'
@@ -326,10 +327,9 @@ module.exports = function (content) {
326
327
  if (scriptSrcMode) output += `global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
327
328
  // 传递ctorType以补全js内容
328
329
  const extraOptions = {
329
- ...script.src ? {
330
- ...queryObj,
331
- resourcePath
332
- } : null,
330
+ ...script.src
331
+ ? { ...queryObj, resourcePath }
332
+ : null,
333
333
  ctorType
334
334
  }
335
335
  output += getRequire('script', script, extraOptions) + '\n'
@@ -2,7 +2,7 @@ const genComponentTag = require('../utils/gen-component-tag')
2
2
  const loaderUtils = require('loader-utils')
3
3
  const addQuery = require('../utils/add-query')
4
4
  const normalize = require('../utils/normalize')
5
- const parseRequest = require('../utils/parse-request')
5
+ const createHelpers = require('../helpers')
6
6
  const optionProcessorPath = normalize.lib('runtime/optionProcessor')
7
7
  const tabBarContainerPath = normalize.lib('runtime/components/web/mpx-tab-bar-container.vue')
8
8
  const tabBarPath = normalize.lib('runtime/components/web/mpx-tab-bar.vue')
@@ -32,6 +32,7 @@ module.exports = function (script, {
32
32
  loaderContext,
33
33
  ctorType,
34
34
  srcMode,
35
+ moduleId,
35
36
  isProduction,
36
37
  componentGenerics,
37
38
  jsonConfig,
@@ -44,13 +45,13 @@ module.exports = function (script, {
44
45
  localComponentsMap,
45
46
  localPagesMap
46
47
  }, callback) {
47
- const mpx = loaderContext.getMpx()
48
48
  const {
49
49
  i18n,
50
- projectRoot
51
- } = mpx
50
+ projectRoot,
51
+ webConfig
52
+ } = loaderContext.getMpx()
52
53
 
53
- const { queryObj } = parseRequest(loaderContext.resource)
54
+ const { getRequire } = createHelpers(loaderContext)
54
55
  const tabBar = jsonConfig.tabBar
55
56
 
56
57
  const emitWarning = (msg) => {
@@ -87,23 +88,7 @@ module.exports = function (script, {
87
88
  if (script) {
88
89
  scriptSrcMode = script.mode || scriptSrcMode
89
90
  } else {
90
- script = {
91
- tag: 'script',
92
- content: ''
93
- }
94
- switch (ctorType) {
95
- case 'app':
96
- script.content = 'import {createApp} from "@mpxjs/core"\n' +
97
- 'createApp({})\n'
98
- break
99
- case 'page':
100
- script.content = 'import {createPage} from "@mpxjs/core"\n' +
101
- 'createPage({})\n'
102
- break
103
- case 'component':
104
- script.content = 'import {createComponent} from "@mpxjs/core"\n' +
105
- 'createComponent({})\n'
106
- }
91
+ script = { tag: 'script' }
107
92
  }
108
93
  output += genComponentTag(script, {
109
94
  attrs (script) {
@@ -138,9 +123,10 @@ module.exports = function (script, {
138
123
  }
139
124
  global.__networkTimeout = ${JSON.stringify(jsonConfig.networkTimeout)}
140
125
  global.__mpxGenericsMap = {}
126
+ global.__mpxOptionsMap = {}
141
127
  global.__style = ${JSON.stringify(jsonConfig.style || 'v1')}
142
128
  global.__mpxPageConfig = ${JSON.stringify(jsonConfig.window)}
143
- global.__mpxTransRpxFn = ${mpx.webConfig.transRpxFn}\n`
129
+ global.__mpxTransRpxFn = ${webConfig.transRpxFn}\n`
144
130
  if (i18n) {
145
131
  const i18nObj = Object.assign({}, i18n)
146
132
  content += ` import VueI18n from 'vue-i18n'
@@ -214,19 +200,23 @@ module.exports = function (script, {
214
200
  componentsMap[componentName] = `getComponent(require(${componentRequest}), { __mpxBuiltIn: true })`
215
201
  })
216
202
 
203
+ content += ` global.currentModuleId = ${JSON.stringify(moduleId)}\n`
217
204
  content += ` global.currentSrcMode = ${JSON.stringify(scriptSrcMode)}\n`
218
205
  if (!isProduction) {
219
206
  content += ` global.currentResource = ${JSON.stringify(loaderContext.resourcePath)}\n`
220
207
  }
221
- // 为了正确获取currentSrcMode便于运行时进行转换,对于src引入的组件script采用require方式引入(由于webpack会将import的执行顺序上升至最顶),这意味着对于src引入脚本中的named export将不会生效,不过鉴于mpx和小程序中本身也没有在组件script中声明export的用法,所以应该没有影响
222
- content += '\n\n\n/** Source start **/\n'
223
- content += script.src
224
- // 继承单文件组件query避免多个单文件模块实例引用一个src模块,因模块缓存导致createComponent不执行的问题
225
- ? `require(${stringifyRequest(addQuery(script.src, queryObj))})\n`
226
- : script.content
227
- content += '\n/** Source end **/\n\n\n'
208
+
209
+ content += ' /** script content **/\n'
210
+
211
+ // 传递ctorType以补全js内容
212
+ const extraOptions = {
213
+ ctorType
214
+ }
215
+ // todo 仅靠vueContentCache保障模块唯一性还是不够严谨,后续需要考虑去除原始query后构建request
216
+ content += ` ${getRequire('script', script, extraOptions)}\n`
217
+
228
218
  // createApp/Page/Component执行完成后立刻获取当前的option并暂存
229
- content += ` const currentOption = global.currentOption\n`
219
+ content += ` const currentOption = global.__mpxOptionsMap[${JSON.stringify(moduleId)}]\n`
230
220
  // 获取pageConfig
231
221
  const pageConfig = {}
232
222
  if (ctorType === 'page') {
@@ -265,7 +255,6 @@ module.exports = function (script, {
265
255
  ${JSON.stringify(componentGenerics)},
266
256
  ${JSON.stringify(genericsInfo)},
267
257
  getWxsMixin(wxsModules)`
268
-
269
258
  if (ctorType === 'app') {
270
259
  content += `,
271
260
  Vue,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mpxjs/webpack-plugin",
3
- "version": "2.7.50-alpha.3",
3
+ "version": "2.7.52",
4
4
  "description": "mpx compile core",
5
5
  "keywords": [
6
6
  "mpx"
@@ -80,5 +80,5 @@
80
80
  "engines": {
81
81
  "node": ">=14.14.0"
82
82
  },
83
- "gitHead": "149081b776c5684bb60a2e26f6e3e0ecb5e60a66"
83
+ "gitHead": "187abad504151455e045c0adf2fe7f81412e0fef"
84
84
  }