@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
package/README.md CHANGED
@@ -13,6 +13,6 @@ module.exports = {
13
13
  new mpxWebpackPlugin({
14
14
  mode: 'wx'
15
15
  })
16
- ]
16
+ ],
17
17
  }
18
18
  ```
@@ -0,0 +1,49 @@
1
+ const parseComponent = require('./parser')
2
+ const loaderUtils = require('loader-utils')
3
+ const parseRequest = require('./utils/parse-request')
4
+ const normalize = require('./utils/normalize')
5
+ const selectorPath = normalize.lib('selector')
6
+ const genComponentTag = require('./utils/gen-component-tag')
7
+ const getMainCompilation = require('./utils/get-main-compilation')
8
+
9
+ module.exports = function (content) {
10
+ this.cacheable()
11
+ const mainCompilation = getMainCompilation(this._compilation)
12
+ const mpx = mainCompilation.__mpx__
13
+ if (!mpx) {
14
+ return content
15
+ }
16
+ const mode = mpx.mode
17
+ const env = mpx.env
18
+ const defs = mpx.defs
19
+ const resourcePath = parseRequest(this.resource).resourcePath
20
+ const parts = parseComponent(content, {
21
+ filePath: resourcePath,
22
+ needMap: this.sourceMap,
23
+ mode,
24
+ defs,
25
+ env
26
+ })
27
+
28
+ let output = ''
29
+
30
+ // 内建组件编写规范比较统一,不需要处理太多情况
31
+ if (parts.template) {
32
+ output += genComponentTag(parts.template)
33
+ }
34
+
35
+ if (parts.script) {
36
+ output += '\n' + genComponentTag(parts.script, (script) => {
37
+ let content = ''
38
+ if (parts.styles && parts.styles.length) {
39
+ parts.styles.forEach((style, i) => {
40
+ const requestString = loaderUtils.stringifyRequest(this, `builtInComponent.styl!=!${selectorPath}?type=styles&index=${i}!${loaderUtils.getRemainingRequest(this)}`)
41
+ content += `\n import ${requestString}`
42
+ })
43
+ }
44
+ content += script.content
45
+ return content
46
+ })
47
+ }
48
+ return output
49
+ }
package/lib/config.js CHANGED
@@ -356,20 +356,6 @@ module.exports = {
356
356
  templatePrefix: 'module.exports = \n'
357
357
  }
358
358
  },
359
- tenon: {
360
- directive: {
361
- if: 'v-if',
362
- elseif: 'v-else-if',
363
- else: 'v-else'
364
- },
365
- wxs: {
366
- tag: 'wxs',
367
- module: 'module',
368
- src: 'src',
369
- ext: '.wxs',
370
- templatePrefix: 'module.exports = \n'
371
- }
372
- },
373
359
  qa: {
374
360
  typeExtMap: {
375
361
  json: '.json',
@@ -0,0 +1,13 @@
1
+ module.exports = function (content) {
2
+ if (!this.__mpx__) {
3
+ return content
4
+ }
5
+ // todo 由于additionalAssets阶段还会进行一次依赖同步,此处获取的依赖不一定是最终的依赖,可能会有bad case
6
+ this.__mpx__.fileDependencies.forEach(file => {
7
+ this.addDependency(file)
8
+ })
9
+ this.__mpx__.contextDependencies.forEach(context => {
10
+ this.addContextDependency(context)
11
+ })
12
+ return this.__mpx__.content
13
+ }
@@ -0,0 +1,24 @@
1
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
+
3
+ class ChildCompileDependency extends NullDependency {
4
+ constructor (module) {
5
+ super()
6
+ this.childCompileEntryModule = module
7
+ }
8
+
9
+ get type () {
10
+ return 'mpx child compile'
11
+ }
12
+
13
+ updateHash (hash) {
14
+ super.updateHash(hash)
15
+ hash.update(this.childCompileEntryModule.identifier())
16
+ }
17
+ }
18
+
19
+ ChildCompileDependency.Template = class ChildCompileDependencyTemplate {
20
+ apply () {
21
+ }
22
+ }
23
+
24
+ module.exports = ChildCompileDependency
@@ -0,0 +1,26 @@
1
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
+
3
+ class InjectDependency extends NullDependency {
4
+ constructor (options) {
5
+ super()
6
+ this.content = options.content
7
+ this.index = options.index || 0
8
+ }
9
+
10
+ get type () {
11
+ return 'mpx inject'
12
+ }
13
+
14
+ updateHash (hash) {
15
+ super.updateHash(hash)
16
+ hash.update(this.content)
17
+ }
18
+ }
19
+
20
+ InjectDependency.Template = class InjectDependencyTemplate {
21
+ apply (dep, source) {
22
+ source.insert(dep.index, '/* mpx inject */ ' + dep.content)
23
+ }
24
+ }
25
+
26
+ module.exports = InjectDependency
@@ -0,0 +1,23 @@
1
+ const ModuleDependency = require('webpack/lib/dependencies//ModuleDependency')
2
+
3
+ class RemovedModuleDependency extends ModuleDependency {
4
+ constructor (request, removedModule, range) {
5
+ super(request)
6
+ this.removedModule = removedModule
7
+ this.range = range
8
+ }
9
+
10
+ get type () {
11
+ return 'removed module'
12
+ }
13
+ }
14
+
15
+ RemovedModuleDependency.Template = class RemovedModuleDependencyTemplate {
16
+ apply (dep, source) {
17
+ if (dep.range) {
18
+ source.replace(dep.range[0], dep.range[1] - 1, '')
19
+ }
20
+ }
21
+ }
22
+
23
+ module.exports = RemovedModuleDependency
@@ -1,5 +1,4 @@
1
1
  const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
- const makeSerializable = require('webpack/lib/util/makeSerializable')
3
2
 
4
3
  class ReplaceDependency extends NullDependency {
5
4
  constructor (replacement, range) {
@@ -12,23 +11,9 @@ class ReplaceDependency extends NullDependency {
12
11
  return 'mpx replace'
13
12
  }
14
13
 
15
- updateHash (hash, context) {
14
+ updateHash (hash) {
15
+ super.updateHash(hash)
16
16
  hash.update(this.replacement)
17
- super.updateHash(hash, context)
18
- }
19
-
20
- serialize (context) {
21
- const { write } = context
22
- write(this.replacement)
23
- write(this.range)
24
- super.serialize(context)
25
- }
26
-
27
- deserialize (context) {
28
- const { read } = context
29
- this.replacement = read()
30
- this.range = read()
31
- super.deserialize(context)
32
17
  }
33
18
  }
34
19
 
@@ -38,6 +23,4 @@ ReplaceDependency.Template = class ReplaceDependencyTemplate {
38
23
  }
39
24
  }
40
25
 
41
- makeSerializable(ReplaceDependency, '@mpxjs/webpack-plugin/lib/dependencies/ReplaceDependency')
42
-
43
26
  module.exports = ReplaceDependency
@@ -0,0 +1,49 @@
1
+ const NullDependency = require('webpack/lib/dependencies/NullDependency')
2
+ const parseRequest = require('../utils/parse-request')
3
+
4
+ class ResolveDependency extends NullDependency {
5
+ constructor (resource, packageName, pagesMap, componentsMap, staticResourcesMap, publicPath, range, issuerResource, compilation) {
6
+ super()
7
+ this.resource = resource
8
+ this.packageName = packageName
9
+ this.pagesMap = pagesMap
10
+ this.componentsMap = componentsMap
11
+ this.staticResourcesMap = staticResourcesMap
12
+ this.publicPath = publicPath
13
+ this.range = range
14
+ this.issuerResource = issuerResource
15
+ this.compilation = compilation
16
+ }
17
+
18
+ get type () {
19
+ return 'mpx resolve'
20
+ }
21
+
22
+ updateHash (hash) {
23
+ super.updateHash(hash)
24
+ hash.update(this.resource)
25
+ }
26
+ }
27
+
28
+ ResolveDependency.Template = class ResolveDependencyTemplate {
29
+ apply (dep, source) {
30
+ const content = this.getContent(dep)
31
+ source.replace(dep.range[0], dep.range[1] - 1, content)
32
+ }
33
+
34
+ getContent (dep) {
35
+ const resourcePath = parseRequest(dep.resource).resourcePath
36
+ const pagesMap = dep.pagesMap
37
+ const componentsMap = dep.componentsMap[dep.packageName]
38
+ const mainComponentsMap = dep.componentsMap.main
39
+ const staticResourcesMap = dep.staticResourcesMap[dep.packageName]
40
+ const mainStaticResourcesMap = dep.staticResourcesMap.main
41
+ const resolved = pagesMap[resourcePath] || componentsMap[resourcePath] || mainComponentsMap[resourcePath] || staticResourcesMap[resourcePath] || mainStaticResourcesMap[resourcePath] || ''
42
+ if (!resolved) {
43
+ dep.compilation.errors.push(new Error(`Path ${dep.resource} is not a page/component/static resource, which is resolved from ${dep.issuerResource}!`))
44
+ }
45
+ return JSON.stringify(dep.publicPath + resolved)
46
+ }
47
+ }
48
+
49
+ module.exports = ResolveDependency
package/lib/extractor.js CHANGED
@@ -1,119 +1,215 @@
1
- const path = require('path')
2
1
  const loaderUtils = require('loader-utils')
2
+ const path = require('path')
3
+ const NodeTemplatePlugin = require('webpack/lib/node/NodeTemplatePlugin')
4
+ const NodeTargetPlugin = require('webpack/lib/node/NodeTargetPlugin')
5
+ const LibraryTemplatePlugin = require('webpack/lib/LibraryTemplatePlugin')
6
+ const SingleEntryPlugin = require('webpack/lib/SingleEntryPlugin')
7
+ const LimitChunkCountPlugin = require('webpack/lib/optimize/LimitChunkCountPlugin')
8
+ const ChildCompileDependency = require('./dependency/ChildCompileDependency')
9
+ const normalize = require('./utils/normalize')
3
10
  const parseRequest = require('./utils/parse-request')
11
+ const getMainCompilation = require('./utils/get-main-compilation')
4
12
  const toPosix = require('./utils/to-posix')
13
+ const config = require('./config')
5
14
  const fixRelative = require('./utils/fix-relative')
6
- const addQuery = require('./utils/add-query')
7
- const normalize = require('./utils/normalize')
8
- const { MPX_DISABLE_EXTRACTOR_CACHE, DEFAULT_RESULT_SOURCE } = require('./utils/const')
9
15
 
10
- module.exports = content => content
16
+ const defaultResultSource = '// removed by extractor'
17
+
18
+ module.exports = function (content) {
19
+ this.cacheable()
20
+ const options = loaderUtils.getOptions(this) || {}
21
+
22
+ const mainCompilation = getMainCompilation(this._compilation)
23
+ const mpx = mainCompilation.__mpx__
11
24
 
12
- module.exports.pitch = async function (remainingRequest) {
13
- const mpx = this.getMpx()
25
+ const pagesMap = mpx.pagesMap
26
+ const getOutputPath = mpx.getOutputPath
27
+
28
+ const extract = mpx.extract
29
+ const extractedMap = mpx.extractedMap
14
30
  const mode = mpx.mode
15
- const { resourcePath, queryObj } = parseRequest(this.resource)
16
- const type = queryObj.type
17
- const index = queryObj.index || 0
18
- const isStatic = queryObj.isStatic
19
- const issuerResource = queryObj.issuerResource
20
- const fromImport = queryObj.fromImport
21
- const needBabel = queryObj.needBabel
22
-
23
- if (needBabel) {
24
- // 创建js request应用babel
25
- let request = addQuery(this.request, {}, true, ['needBabel'])
26
- const fakeRequest = addQuery(`${resourcePath}.js`, queryObj)
27
- return `module.exports = require(${loaderUtils.stringifyRequest(this, `${fakeRequest}!=!${request}`)});\n`
28
- }
31
+ const typeExtMap = config[mode].typeExtMap
29
32
 
30
- const file = mpx.getExtractedFile(this.resource, {
31
- warn: (err) => {
32
- this.emitWarning(err)
33
- },
34
- error: (err) => {
35
- this.emitError(err)
36
- }
33
+ const rootName = mainCompilation._preparedEntrypoints[0].name
34
+ const rootRequest = mainCompilation._preparedEntrypoints[0].request
35
+ const rootModule = mainCompilation.entries.find((module) => {
36
+ return module.rawRequest === rootRequest
37
37
  })
38
+ const rootResourcePath = parseRequest(rootModule.resource).resourcePath
38
39
 
39
- if (issuerResource) {
40
- // 清空issuerResource/index query避免importModule对于不同的issuer无法复用模块缓存
41
- remainingRequest = addQuery(remainingRequest, {}, false, ['issuerResource', 'index'])
42
- }
40
+ let resultSource = defaultResultSource
43
41
 
44
- let request = remainingRequest
45
- // static的情况下需要用record-loader记录相关静态资源的输出路径,不能直接在这里记录,需要确保在子依赖开始构建前完成记录,因为子依赖构建时可能就需要访问当前资源的输出路径
46
- if (isStatic) {
47
- const recordLoader = normalize.lib('record-loader')
48
- request = `${recordLoader}!${remainingRequest}`
49
- }
50
-
51
- let content = await this.importModule(`!!${request}`)
52
- // 处理wxss-loader的返回
53
- if (Array.isArray(content)) {
54
- content = content.map((item) => {
55
- return item[1]
56
- }).join('\n')
42
+ const getFile = (resourceRaw, type) => {
43
+ const { resourcePath, queryObj } = parseRequest(resourceRaw)
44
+ const currentPackageName = queryObj.packageRoot || mpx.currentPackageRoot || 'main'
45
+ const componentsMap = mpx.componentsMap[currentPackageName]
46
+ let filename = pagesMap[resourcePath] || componentsMap[resourcePath]
47
+ if (!filename && resourcePath === rootResourcePath) {
48
+ filename = rootName
49
+ }
50
+ if (filename) {
51
+ return filename + typeExtMap[type]
52
+ } else {
53
+ const outputPath = getOutputPath(resourcePath, type, { ext: typeExtMap[type] })
54
+ return mpx.getPackageInfo({
55
+ resource: resourceRaw,
56
+ outputPath,
57
+ resourceType: 'staticResources',
58
+ warn: (err) => {
59
+ this.emitWarning(err)
60
+ }
61
+ }).outputPath
62
+ }
57
63
  }
58
64
 
59
- let resultSource = DEFAULT_RESULT_SOURCE
60
-
61
- if (typeof content !== 'string') return resultSource
65
+ const type = options.type
66
+ const fromImport = options.fromImport
67
+ const index = +options.index || 0
68
+ const { queryObj } = parseRequest(this.resource)
62
69
 
63
- const extractedInfo = {
64
- content,
65
- index
70
+ let issuerFile
71
+ if (queryObj.issuerResource) {
72
+ issuerFile = getFile(queryObj.issuerResource, type)
66
73
  }
67
74
 
68
- this.emitFile(file, '', undefined, {
69
- skipEmit: true,
70
- extractedInfo
71
- })
72
-
73
- const { buildInfo } = this._module
75
+ const file = getFile(this.resource, type)
76
+ const filename = /(.*)\..*/.exec(file)[1]
74
77
 
75
- // 如果importModule子模块中包含动态特性,比如动态添加入口和静态资源输出路径,则当前extractor模块不可缓存
76
- if (buildInfo.assetsInfo.has(MPX_DISABLE_EXTRACTOR_CACHE)) {
77
- this.cacheable(false)
78
- }
78
+ const sideEffects = []
79
79
 
80
- const assetInfo = buildInfo.assetsInfo && buildInfo.assetsInfo.get(resourcePath)
81
- if (assetInfo && assetInfo.extractedResultSource) {
82
- resultSource = assetInfo.extractedResultSource
83
- }
80
+ sideEffects.push((additionalAssets) => {
81
+ additionalAssets[file].modules = additionalAssets[file].modules || []
82
+ additionalAssets[file].modules.push(this._module)
83
+ })
84
84
 
85
- if (isStatic) {
85
+ if (index === -1) {
86
+ // 需要返回路径或产生副作用
86
87
  switch (type) {
87
- // styles为static就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
88
- // 为了支持持久化缓存,.mpx中使用src引用样式对issueFile asset产生的副作用迁移到ExtractDependency中处理
88
+ // styles中index为-1就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
89
89
  case 'styles':
90
- if (issuerResource) {
91
- const issuerFile = mpx.getExtractedFile(issuerResource)
90
+ if (issuerFile) {
92
91
  let relativePath = toPosix(path.relative(path.dirname(issuerFile), file))
93
92
  relativePath = fixRelative(relativePath, mode)
94
93
  if (fromImport) {
95
- resultSource += `module.exports = ${JSON.stringify(relativePath)};\n`
94
+ resultSource = `module.exports = ${JSON.stringify(relativePath)};`
96
95
  } else {
97
- this.emitFile(issuerFile, '', undefined, {
98
- skipEmit: true,
99
- extractedInfo: {
100
- content: `@import "${relativePath}";\n`,
101
- index,
102
- pre: true
103
- }
96
+ sideEffects.push((additionalAssets) => {
97
+ additionalAssets[issuerFile] = additionalAssets[issuerFile] || []
98
+ additionalAssets[issuerFile].prefix = additionalAssets[issuerFile].prefix || []
99
+ additionalAssets[issuerFile].prefix.push(`@import "${relativePath}";\n`)
100
+ additionalAssets[issuerFile].relativeModules = additionalAssets[issuerFile].relativeModules || []
101
+ additionalAssets[issuerFile].relativeModules.push(this._module)
104
102
  })
105
103
  }
106
104
  }
107
105
  break
108
106
  case 'template':
109
- resultSource += `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};\n`
107
+ resultSource = `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};`
110
108
  break
111
109
  case 'json':
112
- // 目前json为static时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
113
- resultSource += `module.exports = ${JSON.stringify(file)};\n`
110
+ // 目前json中index为-1时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
111
+ resultSource = `module.exports = ${JSON.stringify(file)};`
114
112
  break
115
113
  }
116
114
  }
117
115
 
118
- return resultSource
116
+ const id = `${file}:${index}:${issuerFile}:${fromImport}`
117
+
118
+ // 由于webpack中moduleMap只在compilation维度有效,不同子编译之间可能会对相同的引用文件进行重复的无效抽取,建立全局extractedMap避免这种情况出现
119
+ if (extractedMap[id]) {
120
+ extractedMap[id].modules.push(this._module)
121
+ return extractedMap[id].resultSource
122
+ }
123
+ const nativeCallback = this.async()
124
+ extractedMap[id] = {
125
+ resultSource,
126
+ dep: null,
127
+ modules: [this._module]
128
+ }
129
+
130
+ // 使用子编译器生成需要抽离的json,styles和template
131
+ const contentLoader = normalize.lib('content-loader')
132
+ const request = `!!${contentLoader}?${JSON.stringify(options)}!${this.resource}`
133
+
134
+ const childFilename = 'extractor-filename'
135
+ const outputOptions = {
136
+ filename: childFilename
137
+ }
138
+ const childCompiler = mainCompilation.createChildCompiler(request, outputOptions, [
139
+ new NodeTemplatePlugin(outputOptions),
140
+ new LibraryTemplatePlugin(null, 'commonjs2'),
141
+ new NodeTargetPlugin(),
142
+ new SingleEntryPlugin(this.context, request, filename),
143
+ new LimitChunkCountPlugin({ maxChunks: 1 })
144
+ ])
145
+
146
+ childCompiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation) => {
147
+ compilation.hooks.normalModuleLoader.tap('MpxWebpackPlugin', (loaderContext) => {
148
+ // 传递编译结果,子编译器进入content-loader后直接输出
149
+ loaderContext.__mpx__ = {
150
+ content,
151
+ fileDependencies: this.getDependencies(),
152
+ contextDependencies: this.getContextDependencies()
153
+ }
154
+ })
155
+ compilation.hooks.succeedEntry.tap('MpxWebpackPlugin', (entry, name, module) => {
156
+ const dep = new ChildCompileDependency(module)
157
+ extractedMap[id].dep = dep
158
+ })
159
+ })
160
+
161
+ let source
162
+ childCompiler.hooks.afterCompile.tapAsync('MpxWebpackPlugin', (compilation, callback) => {
163
+ source = compilation.assets[childFilename] && compilation.assets[childFilename].source()
164
+
165
+ // Remove all chunk assets
166
+ compilation.chunks.forEach((chunk) => {
167
+ chunk.files.forEach((file) => {
168
+ delete compilation.assets[file]
169
+ })
170
+ })
171
+
172
+ callback()
173
+ })
174
+
175
+ childCompiler.runAsChild((err, entries, compilation) => {
176
+ if (err) return nativeCallback(err)
177
+ if (compilation.errors.length > 0) {
178
+ mainCompilation.errors.push(...compilation.errors)
179
+ }
180
+
181
+ compilation.fileDependencies.forEach((dep) => {
182
+ this.addDependency(dep)
183
+ }, this)
184
+ compilation.contextDependencies.forEach((dep) => {
185
+ this.addContextDependency(dep)
186
+ }, this)
187
+
188
+ if (!source) {
189
+ return nativeCallback(new Error('Didn\'t get a result from child compiler'))
190
+ }
191
+
192
+ try {
193
+ let text = this.exec(source, request)
194
+ if (Array.isArray(text)) {
195
+ text = text.map((item) => {
196
+ return item[1]
197
+ }).join('\n')
198
+ }
199
+
200
+ extract(text, file, index, sideEffects)
201
+
202
+ // 在production模式下移除extract残留空模块
203
+ if (resultSource === defaultResultSource && this.minimize) {
204
+ this._module.needRemove = true
205
+ }
206
+ } catch (err) {
207
+ return nativeCallback(err)
208
+ }
209
+ if (resultSource) {
210
+ nativeCallback(null, resultSource)
211
+ } else {
212
+ nativeCallback()
213
+ }
214
+ })
119
215
  }
@@ -1,12 +1,14 @@
1
1
  const path = require('path')
2
2
  const loaderUtils = require('loader-utils')
3
+ const getMainCompilation = require('./utils/get-main-compilation')
3
4
  const toPosix = require('./utils/to-posix')
4
- const parseRequest = require('./utils/parse-request')
5
- const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
6
5
 
7
6
  module.exports = function loader (content, prevOptions) {
8
7
  const options = prevOptions || loaderUtils.getOptions(this) || {}
9
8
  const context = options.context || this.rootContext
9
+ const mainCompilation = getMainCompilation(this._compilation)
10
+ const mpx = mainCompilation.__mpx__
11
+ const assetsInfo = mpx.assetsInfo
10
12
 
11
13
  let url = loaderUtils.interpolateName(this, options.name, {
12
14
  context,
@@ -14,9 +16,10 @@ module.exports = function loader (content, prevOptions) {
14
16
  regExp: options.regExp
15
17
  })
16
18
 
17
- let outputPath = url
19
+ let outputPath
18
20
 
19
21
  if (options.publicPath) {
22
+ outputPath = url
20
23
  if (options.outputPathCDN) {
21
24
  if (typeof options.outputPathCDN === 'function') {
22
25
  outputPath = options.outputPathCDN(outputPath, this.resourcePath, context)
@@ -25,10 +28,14 @@ module.exports = function loader (content, prevOptions) {
25
28
  }
26
29
  }
27
30
  } else {
28
- const { resourcePath, queryObj } = parseRequest(this.resource)
29
- const packageRoot = queryObj.packageRoot || ''
30
- url = outputPath = toPosix(path.join(packageRoot, outputPath))
31
- this._module.addPresentationalDependency(new RecordResourceMapDependency(resourcePath, 'staticResource', outputPath, packageRoot))
31
+ url = outputPath = mpx.getPackageInfo({
32
+ resource: this.resource,
33
+ outputPath: url,
34
+ resourceType: 'staticResources',
35
+ warn: (err) => {
36
+ this.emitWarning(err)
37
+ }
38
+ }).outputPath
32
39
  }
33
40
 
34
41
  let publicPath = `__webpack_public_path__ + ${JSON.stringify(url)}`
@@ -44,6 +51,11 @@ module.exports = function loader (content, prevOptions) {
44
51
  publicPath = JSON.stringify(publicPath)
45
52
  }
46
53
 
54
+ // 因为子编译会合并assetsInfo会互相覆盖,使用全局mpx对象收集完之后再合并到主assetsInfo中
55
+ const assetInfo = assetsInfo.get(outputPath) || { modules: [] }
56
+ assetInfo.modules.push(this._module)
57
+ assetsInfo.set(outputPath, assetInfo)
58
+
47
59
  this.emitFile(outputPath, content)
48
60
 
49
61
  // TODO revert to ES2015 Module export, when new CSS Pipeline is in place