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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/lib/dependencies/AppEntryDependency.js +56 -0
  2. package/lib/dependencies/CommonJsVariableDependency.js +69 -0
  3. package/lib/dependencies/DynamicEntryDependency.js +131 -0
  4. package/lib/dependencies/FlagPluginDependency.js +23 -0
  5. package/lib/dependencies/InjectDependency.js +43 -0
  6. package/lib/dependencies/RecordGlobalComponentsDependency.js +50 -0
  7. package/lib/dependencies/RecordResourceMapDependency.js +52 -0
  8. package/lib/dependencies/RemoveEntryDependency.js +40 -0
  9. package/lib/{dependency → dependencies}/ReplaceDependency.js +19 -2
  10. package/lib/dependencies/ResolveDependency.js +84 -0
  11. package/lib/extractor.js +73 -178
  12. package/lib/file-loader.js +7 -19
  13. package/lib/helpers.js +42 -330
  14. package/lib/index.js +497 -376
  15. package/lib/json-compiler/helper.js +148 -0
  16. package/lib/json-compiler/index.js +195 -439
  17. package/lib/json-compiler/plugin.js +150 -0
  18. package/lib/json-compiler/{theme-loader.js → theme.js} +5 -3
  19. package/lib/loader.js +107 -226
  20. package/lib/native-loader.js +65 -132
  21. package/lib/parser.js +1 -2
  22. package/lib/record-loader.js +11 -0
  23. package/lib/{path-loader.js → resolve-loader.js} +0 -0
  24. package/lib/resolver/AddEnvPlugin.js +3 -2
  25. package/lib/resolver/AddModePlugin.js +3 -2
  26. package/lib/runtime/base.styl +5 -0
  27. package/lib/runtime/i18n.wxs +3 -3
  28. package/lib/runtime/optionProcessor.js +3 -3
  29. package/lib/selector.js +9 -11
  30. package/lib/style-compiler/index.js +12 -19
  31. package/lib/template-compiler/compiler.js +21 -162
  32. package/lib/template-compiler/index.js +47 -136
  33. package/lib/url-loader.js +11 -29
  34. package/lib/utils/add-query.js +1 -1
  35. package/lib/utils/const.js +9 -0
  36. package/lib/utils/emit-file.js +10 -0
  37. package/lib/utils/eval-json-js.js +31 -0
  38. package/lib/utils/get-entry-name.js +13 -0
  39. package/lib/utils/get-json-content.js +41 -0
  40. package/lib/utils/is-url-request.js +10 -1
  41. package/lib/utils/normalize.js +0 -13
  42. package/lib/utils/parse-request.js +3 -3
  43. package/lib/utils/resolve.js +13 -0
  44. package/lib/utils/set.js +47 -0
  45. package/lib/utils/stringify-loaders-resource.js +25 -0
  46. package/lib/utils/stringify-query.js +4 -0
  47. package/lib/web/processJSON.js +113 -142
  48. package/lib/web/processScript.js +32 -26
  49. package/lib/web/processTemplate.js +57 -39
  50. package/lib/wxml/{wxml-loader.js → loader.js} +24 -60
  51. package/lib/wxs/WxsModuleIdsPlugin.js +32 -0
  52. package/lib/wxs/WxsParserPlugin.js +2 -2
  53. package/lib/wxs/WxsPlugin.js +4 -8
  54. package/lib/wxs/WxsTemplatePlugin.js +46 -92
  55. package/lib/wxs/{wxs-i18n-loader.js → i18n-loader.js} +1 -3
  56. package/lib/wxs/{wxs-loader.js → loader.js} +41 -50
  57. package/lib/wxs/{wxs-pre-loader.js → pre-loader.js} +3 -4
  58. package/lib/wxss/loader.js +31 -43
  59. package/lib/wxss/localsLoader.js +1 -5
  60. package/package.json +5 -9
  61. package/lib/built-in-loader.js +0 -49
  62. package/lib/content-loader.js +0 -13
  63. package/lib/dependency/ChildCompileDependency.js +0 -24
  64. package/lib/dependency/InjectDependency.js +0 -26
  65. package/lib/dependency/RemovedModuleDependency.js +0 -23
  66. package/lib/dependency/ResolveDependency.js +0 -49
  67. package/lib/plugin-loader.js +0 -287
  68. package/lib/staticConfig.js +0 -4
  69. package/lib/utils/get-main-compilation.js +0 -6
  70. package/lib/utils/read-json-for-src.js +0 -34
  71. package/lib/utils/try-require.js +0 -16
  72. package/lib/wxss/getImportPrefix.js +0 -30
package/lib/extractor.js CHANGED
@@ -1,215 +1,110 @@
1
- const loaderUtils = require('loader-utils')
2
1
  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')
2
+ const loaderUtils = require('loader-utils')
10
3
  const parseRequest = require('./utils/parse-request')
11
- const getMainCompilation = require('./utils/get-main-compilation')
12
4
  const toPosix = require('./utils/to-posix')
13
- const config = require('./config')
14
5
  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')
15
9
 
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__
24
-
25
- const pagesMap = mpx.pagesMap
26
- const getOutputPath = mpx.getOutputPath
10
+ module.exports = content => content
27
11
 
28
- const extract = mpx.extract
29
- const extractedMap = mpx.extractedMap
12
+ module.exports.pitch = async function (remainingRequest) {
13
+ const mpx = this.getMpx()
30
14
  const mode = mpx.mode
31
- const typeExtMap = config[mode].typeExtMap
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 issuerFile = queryObj.issuerFile
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
+ }
32
29
 
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
30
+ const file = mpx.getExtractedFile(this.resource, {
31
+ warn: (err) => {
32
+ this.emitWarning(err)
33
+ },
34
+ error: (err) => {
35
+ this.emitError(err)
36
+ }
37
37
  })
38
- const rootResourcePath = parseRequest(rootModule.resource).resourcePath
39
38
 
40
- let resultSource = defaultResultSource
41
-
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
- }
39
+ let request = remainingRequest
40
+ // static的情况下需要用record-loader记录相关静态资源的输出路径,不能直接在这里记录,需要确保在子依赖开始构建前完成记录,因为子依赖构建时可能就需要访问当前资源的输出路径
41
+ if (isStatic) {
42
+ const recordLoader = normalize.lib('record-loader')
43
+ request = `${recordLoader}!${remainingRequest}`
63
44
  }
64
45
 
65
- const type = options.type
66
- const fromImport = options.fromImport
67
- const index = +options.index || 0
68
- const { queryObj } = parseRequest(this.resource)
46
+ let content = await this.importModule(`!!${request}`)
47
+ // 处理wxss-loader的返回
48
+ if (Array.isArray(content)) {
49
+ content = content.map((item) => {
50
+ return item[1]
51
+ }).join('\n')
52
+ }
69
53
 
70
- let issuerFile
71
- if (queryObj.issuerResource) {
72
- issuerFile = getFile(queryObj.issuerResource, type)
54
+ const extractedInfo = {
55
+ content,
56
+ index
73
57
  }
74
58
 
75
- const file = getFile(this.resource, type)
76
- const filename = /(.*)\..*/.exec(file)[1]
59
+ this.emitFile(file, '', undefined, {
60
+ skipEmit: true,
61
+ extractedInfo
62
+ })
77
63
 
78
- const sideEffects = []
64
+ let resultSource = DEFAULT_RESULT_SOURCE
79
65
 
80
- sideEffects.push((additionalAssets) => {
81
- additionalAssets[file].modules = additionalAssets[file].modules || []
82
- additionalAssets[file].modules.push(this._module)
83
- })
66
+ const { buildInfo } = this._module
84
67
 
85
- if (index === -1) {
86
- // 需要返回路径或产生副作用
68
+ // 如果importModule子模块中包含动态特性,比如动态添加入口和静态资源输出路径,则当前extractor模块不可缓存
69
+ if (buildInfo.assetsInfo.has(MPX_DISABLE_EXTRACTOR_CACHE)) {
70
+ this.cacheable(false)
71
+ }
72
+
73
+ const assetInfo = buildInfo.assetsInfo && buildInfo.assetsInfo.get(resourcePath)
74
+ if (assetInfo && assetInfo.extractedResultSource) {
75
+ resultSource = assetInfo.extractedResultSource
76
+ }
77
+
78
+ if (isStatic) {
87
79
  switch (type) {
88
- // styles中index为-1就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
80
+ // styles为static就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
81
+ // 为了支持持久化缓存,.mpx中使用src引用样式对issueFile asset产生的副作用迁移到ExtractDependency中处理
89
82
  case 'styles':
90
83
  if (issuerFile) {
91
84
  let relativePath = toPosix(path.relative(path.dirname(issuerFile), file))
92
85
  relativePath = fixRelative(relativePath, mode)
93
86
  if (fromImport) {
94
- resultSource = `module.exports = ${JSON.stringify(relativePath)};`
87
+ resultSource += `module.exports = ${JSON.stringify(relativePath)};\n`
95
88
  } else {
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)
89
+ this.emitFile(issuerFile, '', undefined, {
90
+ skipEmit: true,
91
+ extractedInfo: {
92
+ content: `@import "${relativePath}";\n`,
93
+ index: -1
94
+ }
102
95
  })
103
96
  }
104
97
  }
105
98
  break
106
99
  case 'template':
107
- resultSource = `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};`
100
+ resultSource += `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};\n`
108
101
  break
109
102
  case 'json':
110
- // 目前json中index为-1时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
111
- resultSource = `module.exports = ${JSON.stringify(file)};`
103
+ // 目前json为static时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
104
+ resultSource += `module.exports = ${JSON.stringify(file)};\n`
112
105
  break
113
106
  }
114
107
  }
115
108
 
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
- })
109
+ return resultSource
215
110
  }
@@ -1,14 +1,12 @@
1
1
  const path = require('path')
2
2
  const loaderUtils = require('loader-utils')
3
- const getMainCompilation = require('./utils/get-main-compilation')
4
3
  const toPosix = require('./utils/to-posix')
4
+ const parseRequest = require('./utils/parse-request')
5
+ const RecordResourceMapDependency = require('./dependencies/RecordResourceMapDependency')
5
6
 
6
7
  module.exports = function loader (content, prevOptions) {
7
8
  const options = prevOptions || loaderUtils.getOptions(this) || {}
8
9
  const context = options.context || this.rootContext
9
- const mainCompilation = getMainCompilation(this._compilation)
10
- const mpx = mainCompilation.__mpx__
11
- const assetsInfo = mpx.assetsInfo
12
10
 
13
11
  let url = loaderUtils.interpolateName(this, options.name, {
14
12
  context,
@@ -16,10 +14,9 @@ module.exports = function loader (content, prevOptions) {
16
14
  regExp: options.regExp
17
15
  })
18
16
 
19
- let outputPath
17
+ let outputPath = url
20
18
 
21
19
  if (options.publicPath) {
22
- outputPath = url
23
20
  if (options.outputPathCDN) {
24
21
  if (typeof options.outputPathCDN === 'function') {
25
22
  outputPath = options.outputPathCDN(outputPath, this.resourcePath, context)
@@ -28,14 +25,10 @@ module.exports = function loader (content, prevOptions) {
28
25
  }
29
26
  }
30
27
  } else {
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
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))
39
32
  }
40
33
 
41
34
  let publicPath = `__webpack_public_path__ + ${JSON.stringify(url)}`
@@ -51,11 +44,6 @@ module.exports = function loader (content, prevOptions) {
51
44
  publicPath = JSON.stringify(publicPath)
52
45
  }
53
46
 
54
- // 因为子编译会合并assetsInfo会互相覆盖,使用全局mpx对象收集完之后再合并到主assetsInfo中
55
- const assetInfo = assetsInfo.get(outputPath) || { modules: [] }
56
- assetInfo.modules.push(this._module)
57
- assetsInfo.set(outputPath, assetInfo)
58
-
59
47
  this.emitFile(outputPath, content)
60
48
 
61
49
  // TODO revert to ES2015 Module export, when new CSS Pipeline is in place