@mpxjs/webpack-plugin 2.7.0-beta.5 → 2.7.0-beta.9

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.
@@ -21,7 +21,7 @@ class DynamicEntryDependency extends NullDependency {
21
21
 
22
22
  get key () {
23
23
  const { resource, entryType, outputPath, packageRoot, relativePath, range } = this
24
- return [resource, entryType, outputPath, packageRoot, relativePath, ...range].join('|')
24
+ return toPosix([resource, entryType, outputPath, packageRoot, relativePath, ...range].join('|'))
25
25
  }
26
26
 
27
27
  addEntry (compilation, callback) {
@@ -1,28 +1,32 @@
1
1
  const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
2
  const makeSerializable = require('webpack/lib/util/makeSerializable')
3
3
 
4
- class RecordStaticResourceDependency extends NullDependency {
5
- constructor (resourcePath, outputPath, packageRoot = '') {
4
+ class RecordResourceMapDependency extends NullDependency {
5
+ constructor (resourcePath, resourceType, outputPath, packageRoot = '') {
6
6
  super()
7
7
  this.resourcePath = resourcePath
8
+ this.resourceType = resourceType
8
9
  this.outputPath = outputPath
9
10
  this.packageRoot = packageRoot
10
11
  }
11
12
 
12
13
  get type () {
13
- return 'mpx record static resource'
14
+ return 'mpx record resource map'
14
15
  }
15
16
 
16
17
  mpxAction (module, compilation, callback) {
17
18
  const mpx = compilation.__mpx__
18
19
  const packageName = this.packageRoot || 'main'
19
- mpx.staticResourcesMap[packageName][this.resourcePath] = this.outputPath
20
+ const resourceMap = mpx[`${this.resourceType}sMap`] || mpx.otherResourcesMap
21
+ const subResourceMap = resourceMap.main ? resourceMap[packageName] : resourceMap
22
+ subResourceMap[this.resourcePath] = this.outputPath
20
23
  return callback()
21
24
  }
22
25
 
23
26
  serialize (context) {
24
27
  const { write } = context
25
28
  write(this.resourcePath)
29
+ write(this.resourceType)
26
30
  write(this.outputPath)
27
31
  write(this.packageRoot)
28
32
  super.serialize(context)
@@ -31,17 +35,18 @@ class RecordStaticResourceDependency extends NullDependency {
31
35
  deserialize (context) {
32
36
  const { read } = context
33
37
  this.resourcePath = read()
38
+ this.resourceType = read()
34
39
  this.outputPath = read()
35
40
  this.packageRoot = read()
36
41
  super.deserialize(context)
37
42
  }
38
43
  }
39
44
 
40
- RecordStaticResourceDependency.Template = class RecordStaticResourceDependencyTemplate {
45
+ RecordResourceMapDependency.Template = class RecordResourceMapDependencyTemplate {
41
46
  apply () {
42
47
  }
43
48
  }
44
49
 
45
- makeSerializable(RecordStaticResourceDependency, '@mpxjs/webpack-plugin/lib/dependencies/RecordStaticResourceDependency')
50
+ makeSerializable(RecordResourceMapDependency, '@mpxjs/webpack-plugin/lib/dependencies/RecordResourceMapDependency')
46
51
 
47
- module.exports = RecordStaticResourceDependency
52
+ module.exports = RecordResourceMapDependency
@@ -37,8 +37,13 @@ class ResolveDependency extends NullDependency {
37
37
 
38
38
  // resolved可能会动态变更,需用此更新hash
39
39
  updateHash (hash, context) {
40
- const resolved = this.getResolved()
41
- if (resolved) hash.update(resolved)
40
+ this.resolved = this.getResolved()
41
+ const { resource, issuerResource, compilation } = this
42
+ if (this.resolved) {
43
+ hash.update(this.resolved)
44
+ } else {
45
+ compilation.errors.push(new Error(`Path ${resource} is not a page/component/static resource, which is resolved from ${issuerResource}!`))
46
+ }
42
47
  super.updateHash(hash, context)
43
48
  }
44
49
 
@@ -68,12 +73,8 @@ ResolveDependency.Template = class ResolveDependencyTemplate {
68
73
  }
69
74
 
70
75
  getContent (dep) {
71
- const { resource, issuerResource, compilation } = dep
76
+ const { resolved = '', compilation } = dep
72
77
  const publicPath = compilation.outputOptions.publicPath || ''
73
- const resolved = dep.getResolved()
74
- if (!resolved) {
75
- compilation.errors.push(new Error(`Path ${resource} is not a page/component/static resource, which is resolved from ${issuerResource}!`))
76
- }
77
78
  return JSON.stringify(publicPath + resolved)
78
79
  }
79
80
  }
package/lib/extractor.js CHANGED
@@ -3,9 +3,9 @@ const loaderUtils = require('loader-utils')
3
3
  const parseRequest = require('./utils/parse-request')
4
4
  const toPosix = require('./utils/to-posix')
5
5
  const fixRelative = require('./utils/fix-relative')
6
- const normalize = require('./utils/normalize')
7
6
  const addQuery = require('./utils/add-query')
8
7
  const { MPX_DISABLE_EXTRACTOR_CACHE, DEFAULT_RESULT_SOURCE } = require('./utils/const')
8
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
9
9
 
10
10
  module.exports = content => content
11
11
 
@@ -37,10 +37,10 @@ module.exports.pitch = async function (remainingRequest) {
37
37
  })
38
38
 
39
39
  let request = remainingRequest
40
- // static的情况下需要添加recordLoader记录相关静态资源的输出路径
40
+ // static的情况下需要记录相关静态资源的输出路径
41
41
  if (isStatic) {
42
- const recordLoader = normalize.lib('record-loader')
43
- request = `${recordLoader}!${remainingRequest}`
42
+ const packageRoot = queryObj.packageRoot || ''
43
+ this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'staticResource', file, packageRoot))
44
44
  }
45
45
 
46
46
  let content = await this.importModule(`!!${request}`)
@@ -2,7 +2,7 @@ const path = require('path')
2
2
  const loaderUtils = require('loader-utils')
3
3
  const toPosix = require('./utils/to-posix')
4
4
  const parseRequest = require('./utils/parse-request')
5
- const RecordStaticResourceDependency = require('./dependencies/RecordStaticResourceDependency')
5
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
6
6
 
7
7
  module.exports = function loader (content, prevOptions) {
8
8
  const options = prevOptions || loaderUtils.getOptions(this) || {}
@@ -28,7 +28,7 @@ module.exports = function loader (content, prevOptions) {
28
28
  const { resourcePath, queryObj } = parseRequest(this.resource)
29
29
  const packageRoot = queryObj.packageRoot || ''
30
30
  url = outputPath = toPosix(path.join(packageRoot, outputPath))
31
- this._module.addPresentationalDependency(new RecordStaticResourceDependency(resourcePath, outputPath, packageRoot))
31
+ this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'staticResource', outputPath, packageRoot))
32
32
  }
33
33
 
34
34
  let publicPath = `__webpack_public_path__ + ${JSON.stringify(url)}`
package/lib/index.js CHANGED
@@ -24,7 +24,7 @@ const PackageEntryPlugin = require('./resolver/PackageEntryPlugin')
24
24
  // const RequireHeaderDependency = require('webpack/lib/dependencies/RequireHeaderDependency')
25
25
  // const RemovedModuleDependency = require('./dependencies/RemovedModuleDependency')
26
26
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
27
- const RecordStaticResourceDependency = require('./dependencies/RecordStaticResourceDependency')
27
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
28
28
  const RecordGlobalComponentsDependency = require('./dependencies/RecordGlobalComponentsDependency')
29
29
  const DynamicEntryDependency = require('./dependencies/DynamicEntryDependency')
30
30
  const FlagPluginDependency = require('./dependencies/FlagPluginDependency')
@@ -49,6 +49,7 @@ const async = require('async')
49
49
  const stringifyLoadersAndResource = require('./utils/stringify-loaders-resource')
50
50
  const emitFile = require('./utils/emit-file')
51
51
  const { MPX_PROCESSED_FLAG, MPX_DISABLE_EXTRACTOR_CACHE } = require('./utils/const')
52
+ const isEmptyObject = require('./utils/is-empty-object')
52
53
 
53
54
  const isProductionLikeMode = options => {
54
55
  return options.mode === 'production' || !options.mode
@@ -79,6 +80,11 @@ const isChunkInPackage = (chunkName, packageName) => {
79
80
  const getPackageCacheGroup = packageName => {
80
81
  if (packageName === 'main') {
81
82
  return {
83
+ // 对于独立分包模块不应用该cacheGroup
84
+ test: (module) => {
85
+ const { queryObj } = parseRequest(module.resource)
86
+ return !queryObj.isIndependent
87
+ },
82
88
  name: 'bundle',
83
89
  minChunks: 2,
84
90
  chunks: 'all'
@@ -359,18 +365,17 @@ class MpxWebpackPlugin {
359
365
 
360
366
  let mpx
361
367
 
362
- // 构建分包队列,在finishMake钩子当中最先执行,stage传递-1000
363
- compiler.hooks.finishMake.tapAsync({
364
- name: 'MpxWebpackPlugin',
365
- stage: -1000
366
- }, (compilation, callback) => {
368
+ const processSubpackagesEntriesMap = (compilation, callback) => {
367
369
  const mpx = compilation.__mpx__
368
- if (mpx && mpx.subpackagesEntriesMap) {
369
- async.eachOfSeries(mpx.subpackagesEntriesMap, (deps, packageRoot, callback) => {
370
+ if (mpx && !isEmptyObject(mpx.subpackagesEntriesMap)) {
371
+ const subpackagesEntriesMap = mpx.subpackagesEntriesMap
372
+ // 执行分包队列前清空mpx.subpackagesEntriesMap
373
+ mpx.subpackagesEntriesMap = {}
374
+ async.eachOfSeries(subpackagesEntriesMap, (deps, packageRoot, callback) => {
370
375
  mpx.currentPackageRoot = packageRoot
371
- mpx.componentsMap[packageRoot] = {}
372
- mpx.staticResourcesMap[packageRoot] = {}
373
- mpx.subpackageModulesMap[packageRoot] = {}
376
+ mpx.componentsMap[packageRoot] = mpx.componentsMap[packageRoot] || {}
377
+ mpx.staticResourcesMap[packageRoot] = mpx.staticResourcesMap[packageRoot] || {}
378
+ mpx.subpackageModulesMap[packageRoot] = mpx.subpackageModulesMap[packageRoot] || {}
374
379
  async.each(deps, (dep, callback) => {
375
380
  dep.addEntry(compilation, (err, { resultPath }) => {
376
381
  if (err) return callback(err)
@@ -378,10 +383,22 @@ class MpxWebpackPlugin {
378
383
  callback()
379
384
  })
380
385
  }, callback)
381
- }, callback)
386
+ }, (err) => {
387
+ if (err) return callback(err)
388
+ // 如果执行完当前队列后产生了新的分包执行队列(一般由异步分包组件造成),则继续执行
389
+ processSubpackagesEntriesMap(compilation, callback)
390
+ })
382
391
  } else {
383
392
  callback()
384
393
  }
394
+ }
395
+
396
+ // 构建分包队列,在finishMake钩子当中最先执行,stage传递-1000
397
+ compiler.hooks.finishMake.tapAsync({
398
+ name: 'MpxWebpackPlugin',
399
+ stage: -1000
400
+ }, (compilation, callback) => {
401
+ processSubpackagesEntriesMap(compilation, callback)
385
402
  })
386
403
 
387
404
  compiler.hooks.compilation.tap('MpxWebpackPlugin ', (compilation, { normalModuleFactory }) => {
@@ -416,8 +433,8 @@ class MpxWebpackPlugin {
416
433
  compilation.dependencyFactories.set(RemoveEntryDependency, new NullFactory())
417
434
  compilation.dependencyTemplates.set(RemoveEntryDependency, new RemoveEntryDependency.Template())
418
435
 
419
- compilation.dependencyFactories.set(RecordStaticResourceDependency, new NullFactory())
420
- compilation.dependencyTemplates.set(RecordStaticResourceDependency, new RecordStaticResourceDependency.Template())
436
+ compilation.dependencyFactories.set(RecordResourceMapDependency, new NullFactory())
437
+ compilation.dependencyTemplates.set(RecordResourceMapDependency, new RecordResourceMapDependency.Template())
421
438
 
422
439
  compilation.dependencyFactories.set(RecordGlobalComponentsDependency, new NullFactory())
423
440
  compilation.dependencyTemplates.set(RecordGlobalComponentsDependency, new RecordGlobalComponentsDependency.Template())
@@ -597,6 +614,7 @@ class MpxWebpackPlugin {
597
614
  if (currentResourceMap[resourcePath] === outputPath) {
598
615
  alreadyOutputed = true
599
616
  } else {
617
+ // todo 用outputPathMap来检测冲突
600
618
  // 输出冲突检测,如果存在输出路径冲突,对输出路径进行重命名
601
619
  for (let key in currentResourceMap) {
602
620
  if (currentResourceMap[key] === outputPath && key !== resourcePath) {
@@ -627,8 +645,9 @@ class MpxWebpackPlugin {
627
645
  async.forEach(presentationalDependencies.filter((dep) => dep.mpxAction), (dep, callback) => {
628
646
  dep.mpxAction(module, compilation, callback)
629
647
  }, (err) => {
630
- if (err) return callback(err)
631
- rawProcessModuleDependencies.call(compilation, module, callback)
648
+ rawProcessModuleDependencies.call(compilation, module, (innerErr) => {
649
+ return callback(err || innerErr)
650
+ })
632
651
  })
633
652
  }
634
653
 
@@ -677,10 +696,12 @@ class MpxWebpackPlugin {
677
696
  compilation.errors.push(e)
678
697
  }
679
698
  })
680
- if (packageRoot) {
681
- module.request = addQuery(module.request, { packageRoot })
682
- module.resource = addQuery(module.resource, { packageRoot })
683
- }
699
+ const queryObj = {}
700
+ if (packageRoot) queryObj.packageRoot = packageRoot
701
+ // todo 后续可以考虑用module.layer来隔离独立分包的模块
702
+ if (isIndependent) queryObj.isIndependent = true
703
+ module.request = addQuery(module.request, queryObj)
704
+ module.resource = addQuery(module.resource, queryObj)
684
705
  }
685
706
  }
686
707
 
@@ -701,17 +722,6 @@ class MpxWebpackPlugin {
701
722
  }
702
723
  })
703
724
 
704
- // todo 统一通过dep+mpx actions处理
705
- compilation.hooks.stillValidModule.tap('MpxWebpackPlugin', (module) => {
706
- const buildInfo = module.buildInfo
707
- if (buildInfo.pagesMap) {
708
- Object.assign(mpx.pagesMap, buildInfo.pagesMap)
709
- }
710
- if (buildInfo.componentsMap && buildInfo.packageName) {
711
- Object.assign(mpx.componentsMap[buildInfo.packageName], buildInfo.componentsMap)
712
- }
713
- })
714
-
715
725
  compilation.hooks.finishModules.tap('MpxWebpackPlugin', (modules) => {
716
726
  // 自动跟进分包配置修改splitChunksPlugin配置
717
727
  if (splitChunksPlugin) {
@@ -1158,7 +1168,7 @@ try {
1158
1168
  if (loader.loader.includes(info[0])) {
1159
1169
  loader.loader = info[1]
1160
1170
  }
1161
- if (loader.loader === info[1]) {
1171
+ if (loader.loader.includes(info[1])) {
1162
1172
  insertBeforeIndex = index
1163
1173
  }
1164
1174
  })
@@ -1193,41 +1203,43 @@ try {
1193
1203
  loader: extractorPath
1194
1204
  })
1195
1205
  }
1196
-
1197
1206
  createData.resource = addQuery(createData.resource, { mpx: MPX_PROCESSED_FLAG }, true)
1198
- createData.request = stringifyLoadersAndResource(loaders, createData.resource)
1199
1207
  }
1200
1208
 
1201
- // const mpxStyleOptions = queryObj.mpxStyleOptions
1202
- // const firstLoader = (data.loaders[0] && data.loaders[0].loader) || ''
1203
- // const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher.js')
1204
- // let cssLoaderIndex = -1
1205
- // let vueStyleLoaderIndex = -1
1206
- // let mpxStyleLoaderIndex = -1
1207
- // data.loaders.forEach((loader, index) => {
1208
- // const currentLoader = loader.loader
1209
- // if (currentLoader.includes('css-loader')) {
1210
- // cssLoaderIndex = index
1211
- // } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader.js')) {
1212
- // vueStyleLoaderIndex = index
1213
- // } else if (currentLoader.includes('@mpxjs/webpack-plugin/lib/style-compiler/index.js')) {
1214
- // mpxStyleLoaderIndex = index
1215
- // }
1216
- // })
1217
- // if (mpxStyleLoaderIndex === -1) {
1218
- // let loaderIndex = -1
1219
- // if (cssLoaderIndex > -1 && vueStyleLoaderIndex === -1) {
1220
- // loaderIndex = cssLoaderIndex
1221
- // } else if (cssLoaderIndex > -1 && vueStyleLoaderIndex > -1 && !isPitcherRequest) {
1222
- // loaderIndex = vueStyleLoaderIndex
1223
- // }
1224
- // if (loaderIndex > -1) {
1225
- // data.loaders.splice(loaderIndex + 1, 0, {
1226
- // loader: normalize.lib('style-compiler/index.js'),
1227
- // options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
1228
- // })
1229
- // }
1230
- // }
1209
+ if (mpx.mode === 'web') {
1210
+ const mpxStyleOptions = queryObj.mpxStyleOptions
1211
+ const firstLoader = (loaders[0] && loaders[0].loader) || ''
1212
+ const isPitcherRequest = firstLoader.includes('vue-loader/lib/loaders/pitcher')
1213
+ let cssLoaderIndex = -1
1214
+ let vueStyleLoaderIndex = -1
1215
+ let mpxStyleLoaderIndex = -1
1216
+ loaders.forEach((loader, index) => {
1217
+ const currentLoader = loader.loader
1218
+ if (currentLoader.includes('css-loader')) {
1219
+ cssLoaderIndex = index
1220
+ } else if (currentLoader.includes('vue-loader/lib/loaders/stylePostLoader')) {
1221
+ vueStyleLoaderIndex = index
1222
+ } else if (currentLoader.includes(styleCompilerPath)) {
1223
+ mpxStyleLoaderIndex = index
1224
+ }
1225
+ })
1226
+ if (mpxStyleLoaderIndex === -1) {
1227
+ let loaderIndex = -1
1228
+ if (cssLoaderIndex > -1 && vueStyleLoaderIndex === -1) {
1229
+ loaderIndex = cssLoaderIndex
1230
+ } else if (cssLoaderIndex > -1 && vueStyleLoaderIndex > -1 && !isPitcherRequest) {
1231
+ loaderIndex = vueStyleLoaderIndex
1232
+ }
1233
+ if (loaderIndex > -1) {
1234
+ loaders.splice(loaderIndex + 1, 0, {
1235
+ loader: styleCompilerPath,
1236
+ options: (mpxStyleOptions && JSON.parse(mpxStyleOptions)) || {}
1237
+ })
1238
+ }
1239
+ }
1240
+ }
1241
+
1242
+ createData.request = stringifyLoadersAndResource(loaders, createData.resource)
1231
1243
  // 根据用户传入的modeRules对特定资源添加mode query
1232
1244
  this.runModeRules(createData)
1233
1245
  })
@@ -6,7 +6,7 @@ const parseRequest = require('../utils/parse-request')
6
6
  const loaderUtils = require('loader-utils')
7
7
  const resolve = require('../utils/resolve')
8
8
 
9
- module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
9
+ module.exports = function createJSONHelper ({ loaderContext, emitWarning, customGetDynamicEntry }) {
10
10
  const mpx = loaderContext.getMpx()
11
11
  const resolveMode = mpx.resolveMode
12
12
  const externals = mpx.externals
@@ -14,6 +14,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
14
14
  const publicPath = loaderContext._compilation.outputOptions.publicPath || ''
15
15
  const pathHash = mpx.pathHash
16
16
  const getOutputPath = mpx.getOutputPath
17
+ const mode = mpx.mode
17
18
 
18
19
  const isUrlRequest = r => isUrlRequestRaw(r, root, externals)
19
20
  const urlToRequest = r => loaderUtils.urlToRequest(r)
@@ -23,6 +24,7 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
23
24
  let dynamicEntryCount = 0
24
25
 
25
26
  const getDynamicEntry = (resource, type, outputPath = '', packageRoot = '', relativePath = '') => {
27
+ if (typeof customGetDynamicEntry === 'function') return customGetDynamicEntry(resource, type, outputPath, packageRoot, relativePath)
26
28
  const key = `mpx_dynamic_entry_${dynamicEntryCount++}`
27
29
  const value = `__mpx_dynamic_entry__( ${JSON.stringify(resource)},${JSON.stringify(type)},${JSON.stringify(outputPath)},${JSON.stringify(packageRoot)},${JSON.stringify(relativePath)})`
28
30
  dynamicEntryMap.set(key, value)
@@ -44,7 +46,9 @@ module.exports = function createJSONHelper ({ loaderContext, emitWarning }) {
44
46
 
45
47
  resolve(context, component, loaderContext, (err, resource, info) => {
46
48
  if (err) return callback(err)
47
- const resourcePath = parseRequest(resource).resourcePath
49
+ const { resourcePath, queryObj } = parseRequest(resource)
50
+ // 目前只有微信支持分包异步化
51
+ if (queryObj.root && mode === 'wx') tarRoot = queryObj.root
48
52
  const parsed = path.parse(resourcePath)
49
53
  const ext = parsed.ext
50
54
  const resourceName = path.join(parsed.dir, parsed.name)
@@ -217,14 +217,6 @@ module.exports = function (content) {
217
217
  const localPages = []
218
218
  const subPackagesCfg = {}
219
219
  const pageKeySet = new Set()
220
- // 添加首页标识
221
- if (json.pages && json.pages[0]) {
222
- if (typeof json.pages[0] !== 'string') {
223
- json.pages[0].src = addQuery(json.pages[0].src, { isFirst: true })
224
- } else {
225
- json.pages[0] = addQuery(json.pages[0], { isFirst: true })
226
- }
227
- }
228
220
 
229
221
  const processPages = (pages, context, tarRoot = '', callback) => {
230
222
  if (pages) {
@@ -514,14 +506,22 @@ module.exports = function (content) {
514
506
 
515
507
  async.parallel([
516
508
  (callback) => {
517
- processPlugins(json.plugins, this.context, '', callback)
518
- },
519
- (callback) => {
509
+ // 添加首页标识
510
+ if (json.pages && json.pages[0]) {
511
+ if (typeof json.pages[0] !== 'string') {
512
+ json.pages[0].src = addQuery(json.pages[0].src, { isFirst: true })
513
+ } else {
514
+ json.pages[0] = addQuery(json.pages[0], { isFirst: true })
515
+ }
516
+ }
520
517
  processPages(json.pages, this.context, '', callback)
521
518
  },
522
519
  (callback) => {
523
520
  processComponents(json.usingComponents, this.context, callback)
524
521
  },
522
+ (callback) => {
523
+ processPlugins(json.plugins, this.context, '', callback)
524
+ },
525
525
  (callback) => {
526
526
  processWorkers(json.workers, this.context, callback)
527
527
  },
package/lib/loader.js CHANGED
@@ -15,6 +15,7 @@ const getJSONContent = require('./utils/get-json-content')
15
15
  const normalize = require('./utils/normalize')
16
16
  const getEntryName = require('./utils/get-entry-name')
17
17
  const AppEntryDependency = require('./dependencies/AppEntryDependency')
18
+ const { MPX_APP_MODULE_ID } = require('./utils/const')
18
19
 
19
20
  module.exports = function (content) {
20
21
  this.cacheable()
@@ -27,11 +28,8 @@ module.exports = function (content) {
27
28
  const packageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
28
29
  const pagesMap = mpx.pagesMap
29
30
  const componentsMap = mpx.componentsMap[packageName]
30
- const resolveMode = mpx.resolveMode
31
- const projectRoot = mpx.projectRoot
32
31
  const mode = mpx.mode
33
32
  const env = mpx.env
34
- const defs = mpx.defs
35
33
  const i18n = mpx.i18n
36
34
  const globalSrcMode = mpx.srcMode
37
35
  const localSrcMode = queryObj.mode
@@ -39,10 +37,10 @@ module.exports = function (content) {
39
37
  const vueContentCache = mpx.vueContentCache
40
38
  const autoScope = matchCondition(resourcePath, mpx.autoScopeRules)
41
39
 
42
- // 支持资源query传入pagecomponent支持页面/组件单独编译
43
- if ((queryObj.component && !componentsMap[resourcePath]) || (queryObj.page && !pagesMap[resourcePath])) {
40
+ // 支持资源query传入isPageisComponent支持页面/组件单独编译
41
+ if ((queryObj.isComponent && !componentsMap[resourcePath]) || (queryObj.isPage && !pagesMap[resourcePath])) {
44
42
  const entryName = getEntryName(this)
45
- if (queryObj.component) {
43
+ if (queryObj.isComponent) {
46
44
  componentsMap[resourcePath] = entryName || 'noEntryComponent'
47
45
  } else {
48
46
  pagesMap[resourcePath] = entryName || 'noEntryPage'
@@ -58,18 +56,11 @@ module.exports = function (content) {
58
56
  ctorType = 'component'
59
57
  }
60
58
 
61
- if (ctorType === 'app') {
62
- const appName = getEntryName(this)
63
- this._module.addPresentationalDependency(new AppEntryDependency(resourcePath, appName))
64
- }
65
-
66
59
  const loaderContext = this
67
60
  const stringifyRequest = r => loaderUtils.stringifyRequest(loaderContext, r)
68
61
  const isProduction = this.minimize || process.env.NODE_ENV === 'production'
69
-
70
62
  const filePath = resourcePath
71
-
72
- const moduleId = 'm' + mpx.pathHash(filePath)
63
+ const moduleId = ctorType === 'app' ? MPX_APP_MODULE_ID : 'm' + mpx.pathHash(filePath)
73
64
 
74
65
  const parts = parseComponent(content, {
75
66
  filePath,
@@ -120,8 +111,8 @@ module.exports = function (content) {
120
111
 
121
112
  // 处理mode为web时输出vue格式文件
122
113
  if (mode === 'web') {
123
- if (ctorType === 'app' && !queryObj.app) {
124
- const request = addQuery(this.resource, { app: true })
114
+ if (ctorType === 'app' && !queryObj.isApp) {
115
+ const request = addQuery(this.resource, { isApp: true })
125
116
  output += `
126
117
  import App from ${stringifyRequest(request)}
127
118
  import Vue from 'vue'
@@ -142,20 +133,15 @@ module.exports = function (content) {
142
133
  async.parallel([
143
134
  (callback) => {
144
135
  processTemplate(parts.template, {
136
+ loaderContext,
145
137
  hasScoped,
146
138
  hasComment,
147
139
  isNative,
148
- mode,
149
140
  srcMode,
150
- defs,
151
- loaderContext,
152
141
  moduleId,
153
142
  ctorType,
154
143
  usingComponents,
155
- componentGenerics,
156
- decodeHTMLText: mpx.decodeHTMLText,
157
- externalClasses: mpx.externalClasses,
158
- checkUsingComponents: mpx.checkUsingComponents
144
+ componentGenerics
159
145
  }, callback)
160
146
  },
161
147
  (callback) => {
@@ -167,15 +153,9 @@ module.exports = function (content) {
167
153
  },
168
154
  (callback) => {
169
155
  processJSON(parts.json, {
170
- mode,
171
- env,
172
- resolveMode,
173
156
  loaderContext,
174
157
  pagesMap,
175
- pagesEntryMap: mpx.pagesEntryMap,
176
- pathHash: mpx.pathHash,
177
- componentsMap,
178
- projectRoot
158
+ componentsMap
179
159
  }, callback)
180
160
  }
181
161
  ], (err, res) => {
@@ -191,23 +171,20 @@ module.exports = function (content) {
191
171
  }
192
172
 
193
173
  processScript(parts.script, {
174
+ loaderContext,
194
175
  ctorType,
195
176
  srcMode,
196
- loaderContext,
197
177
  isProduction,
198
- i18n,
199
178
  componentGenerics,
200
- projectRoot,
201
179
  jsonConfig: jsonRes.jsonObj,
202
- componentId: queryObj.componentId || '',
180
+ outputPath: queryObj.outputPath || '',
203
181
  tabBarMap: jsonRes.tabBarMap,
204
182
  tabBarStr: jsonRes.tabBarStr,
205
183
  builtInComponentsMap: templateRes.builtInComponentsMap,
206
184
  genericsInfo: templateRes.genericsInfo,
207
185
  wxsModuleMap: templateRes.wxsModuleMap,
208
186
  localComponentsMap: jsonRes.localComponentsMap,
209
- localPagesMap: jsonRes.localPagesMap,
210
- forceDisableBuiltInLoader: mpx.forceDisableBuiltInLoader
187
+ localPagesMap: jsonRes.localPagesMap
211
188
  }, callback)
212
189
  }
213
190
  ], (err, scriptRes) => {
@@ -218,6 +195,19 @@ module.exports = function (content) {
218
195
  })
219
196
  }
220
197
 
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
+
221
211
  const {
222
212
  getRequire
223
213
  } = createHelpers(loaderContext)
@@ -227,14 +217,16 @@ module.exports = function (content) {
227
217
  if (!isProduction) {
228
218
  output += `global.currentResource = ${JSON.stringify(filePath)}\n`
229
219
  }
230
- if (ctorType === 'app' && i18n) {
231
- output += `global.i18n = ${JSON.stringify({ locale: i18n.locale, version: 0 })}\n`
232
-
220
+ // app或独立分包页面注入i18n
221
+ if (i18n && (ctorType === 'app' || (ctorType === 'page' && queryObj.isIndependent))) {
233
222
  const i18nWxsPath = normalize.lib('runtime/i18n.wxs')
234
223
  const i18nWxsLoaderPath = normalize.lib('wxs/i18n-loader.js')
235
224
  const i18nWxsRequest = i18nWxsLoaderPath + '!' + i18nWxsPath
236
225
 
237
- output += `global.i18nMethods = require(${loaderUtils.stringifyRequest(loaderContext, i18nWxsRequest)})\n`
226
+ output += `if (!global.i18n) {
227
+ global.i18n = ${JSON.stringify({ locale: i18n.locale, version: 0 })}
228
+ global.i18nMethods = require(${loaderUtils.stringifyRequest(loaderContext, i18nWxsRequest)})
229
+ }\n`
238
230
  }
239
231
  // 注入构造函数
240
232
  let ctor = 'App'
@@ -313,6 +305,7 @@ module.exports = function (content) {
313
305
  if (script.src) extraOptions.resourcePath = resourcePath
314
306
  output += getRequire('script', script, extraOptions) + '\n'
315
307
  } else {
308
+ // todo 依然创建request在selector中进行补全或者将i18n通过CommonJsVariableDependency改造为initFragments的方式进行注入,否则在app.mpx中没有script区块的情况下无法保证i18n注入代码在@mpxjs/core之前执行
316
309
  switch (ctorType) {
317
310
  case 'app':
318
311
  output += 'import {createApp} from "@mpxjs/core"\n' +
@@ -73,7 +73,12 @@ module.exports = function getSpec ({ warn, error }) {
73
73
  swan: deletePath()
74
74
  },
75
75
  {
76
- test: 'onReachBottomDistance|disableScroll',
76
+ test: 'onReachBottomDistance',
77
+ qq: deletePath(),
78
+ jd: deletePath()
79
+ },
80
+ {
81
+ test: 'disableScroll',
77
82
  ali: deletePath(),
78
83
  qq: deletePath(),
79
84
  jd: deletePath()
@@ -84,7 +89,7 @@ module.exports = function getSpec ({ warn, error }) {
84
89
  swan: deletePath()
85
90
  },
86
91
  {
87
- test: 'navigationBarTextStyle|navigationStyle|backgroundColor|backgroundTextStyle',
92
+ test: 'navigationBarTextStyle|navigationStyle|backgroundTextStyle',
88
93
  ali: deletePath()
89
94
  },
90
95
  {