@mpxjs/webpack-plugin 2.6.102 → 2.7.0-beta.1

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 (59) hide show
  1. package/lib/dependencies/AppEntryDependency.js +56 -0
  2. package/lib/dependencies/CommonJsVariableDependency.js +74 -0
  3. package/lib/dependencies/DynamicEntryDependency.js +127 -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/RecordStaticResourceDependency.js +47 -0
  8. package/lib/{dependency → dependencies}/ReplaceDependency.js +19 -2
  9. package/lib/dependencies/ResolveDependency.js +83 -0
  10. package/lib/extractor.js +72 -179
  11. package/lib/file-loader.js +7 -19
  12. package/lib/helpers.js +41 -330
  13. package/lib/index.js +472 -356
  14. package/lib/json-compiler/helper.js +152 -0
  15. package/lib/json-compiler/index.js +148 -407
  16. package/lib/json-compiler/plugin.js +134 -0
  17. package/lib/json-compiler/{theme-loader.js → theme.js} +5 -3
  18. package/lib/loader.js +76 -171
  19. package/lib/native-loader.js +40 -70
  20. package/lib/record-loader.js +11 -0
  21. package/lib/{path-loader.js → resolve-loader.js} +0 -0
  22. package/lib/runtime/i18n.wxs +3 -3
  23. package/lib/selector.js +10 -7
  24. package/lib/style-compiler/index.js +20 -12
  25. package/lib/style-compiler/plugins/trans-special.js +21 -0
  26. package/lib/template-compiler/compiler.js +44 -176
  27. package/lib/template-compiler/index.js +47 -128
  28. package/lib/url-loader.js +11 -29
  29. package/lib/utils/add-query.js +1 -1
  30. package/lib/utils/const.js +5 -0
  31. package/lib/utils/emit-file.js +10 -0
  32. package/lib/utils/get-entry-name.js +13 -0
  33. package/lib/utils/is-url-request.js +10 -1
  34. package/lib/utils/normalize.js +0 -13
  35. package/lib/utils/parse-request.js +3 -3
  36. package/lib/utils/set.js +47 -0
  37. package/lib/utils/stringify-loaders-resource.js +25 -0
  38. package/lib/utils/stringify-query.js +4 -0
  39. package/lib/web/processScript.js +3 -3
  40. package/lib/web/processTemplate.js +2 -0
  41. package/lib/wxml/{wxml-loader.js → loader.js} +24 -60
  42. package/lib/wxs/WxsModuleIdsPlugin.js +32 -0
  43. package/lib/wxs/WxsParserPlugin.js +2 -2
  44. package/lib/wxs/WxsPlugin.js +4 -8
  45. package/lib/wxs/WxsTemplatePlugin.js +46 -92
  46. package/lib/wxs/{wxs-i18n-loader.js → i18n-loader.js} +0 -0
  47. package/lib/wxs/{wxs-loader.js → loader.js} +33 -38
  48. package/lib/wxs/{wxs-pre-loader.js → pre-loader.js} +0 -0
  49. package/lib/wxss/loader.js +31 -43
  50. package/lib/wxss/localsLoader.js +1 -5
  51. package/package.json +4 -8
  52. package/lib/content-loader.js +0 -13
  53. package/lib/dependency/ChildCompileDependency.js +0 -24
  54. package/lib/dependency/InjectDependency.js +0 -26
  55. package/lib/dependency/RemovedModuleDependency.js +0 -23
  56. package/lib/dependency/ResolveDependency.js +0 -49
  57. package/lib/plugin-loader.js +0 -287
  58. package/lib/utils/try-require.js +0 -16
  59. package/lib/wxss/getImportPrefix.js +0 -30
package/lib/extractor.js CHANGED
@@ -1,216 +1,109 @@
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 normalize = require('./utils/normalize')
7
+ const addQuery = require('./utils/add-query')
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
10
+ module.exports = content => content
26
11
 
27
- const extract = mpx.extract
28
- const pathHash = mpx.pathHash
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 resourceName = path.parse(resourcePath).name
54
- const outputPath = path.join(type, resourceName + pathHash(resourcePath) + typeExtMap[type])
55
- return mpx.getPackageInfo({
56
- resource: resourceRaw,
57
- outputPath,
58
- resourceType: 'staticResources',
59
- warn: (err) => {
60
- this.emitWarning(err)
61
- }
62
- }).outputPath
63
- }
39
+ let request = remainingRequest
40
+ // static的情况下需要添加recordLoader记录相关静态资源的输出路径
41
+ if (isStatic) {
42
+ const recordLoader = normalize.lib('record-loader')
43
+ request = `${recordLoader}!${remainingRequest}`
64
44
  }
65
45
 
66
- const type = options.type
67
- const fromImport = options.fromImport
68
- const index = +options.index || 0
69
- 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
+ }
70
53
 
71
- let issuerFile
72
- if (queryObj.issuerResource) {
73
- issuerFile = getFile(queryObj.issuerResource, type)
54
+ const extractedInfo = {
55
+ content,
56
+ index
74
57
  }
75
58
 
76
- const file = getFile(this.resource, type)
77
- const filename = /(.*)\..*/.exec(file)[1]
59
+ this.emitFile(file, '', undefined, {
60
+ skipEmit: true,
61
+ extractedInfo
62
+ })
78
63
 
79
- const sideEffects = []
64
+ let resultSource = DEFAULT_RESULT_SOURCE
80
65
 
81
- sideEffects.push((additionalAssets) => {
82
- additionalAssets[file].modules = additionalAssets[file].modules || []
83
- additionalAssets[file].modules.push(this._module)
84
- })
66
+ const { buildInfo } = this._module
85
67
 
86
- if (index === -1) {
87
- // 需要返回路径或产生副作用
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) {
88
79
  switch (type) {
89
- // styles中index为-1就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
80
+ // styles为static就两种情况,一种是.mpx中使用src引用样式,第二种为css-loader中处理@import
81
+ // 为了支持持久化缓存,.mpx中使用src引用样式对issueFile asset产生的副作用迁移到ExtractDependency中处理
90
82
  case 'styles':
91
83
  if (issuerFile) {
92
84
  let relativePath = toPosix(path.relative(path.dirname(issuerFile), file))
93
85
  relativePath = fixRelative(relativePath, mode)
94
86
  if (fromImport) {
95
- resultSource = `module.exports = ${JSON.stringify(relativePath)};`
87
+ resultSource += `module.exports = ${JSON.stringify(relativePath)};\n`
96
88
  } else {
97
- sideEffects.push((additionalAssets) => {
98
- additionalAssets[issuerFile] = additionalAssets[issuerFile] || []
99
- additionalAssets[issuerFile].prefix = additionalAssets[issuerFile].prefix || []
100
- additionalAssets[issuerFile].prefix.push(`@import "${relativePath}";\n`)
101
- additionalAssets[issuerFile].relativeModules = additionalAssets[issuerFile].relativeModules || []
102
- additionalAssets[issuerFile].relativeModules.push(this._module)
89
+ this.emitFile(issuerFile, '', undefined, {
90
+ extractedInfo: {
91
+ content: `@import "${relativePath}";\n`,
92
+ index: -1
93
+ }
103
94
  })
104
95
  }
105
96
  }
106
97
  break
107
98
  case 'template':
108
- resultSource = `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};`
99
+ resultSource += `module.exports = __webpack_public_path__ + ${JSON.stringify(file)};\n`
109
100
  break
110
101
  case 'json':
111
- // 目前json中index为-1时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
112
- resultSource = `module.exports = ${JSON.stringify(file)};`
102
+ // 目前json为static时只有处理theme.json一种情况,该情况下返回的路径只能为不带有./或../开头的相对路径,否则微信小程序预览构建会报错,issue#622
103
+ resultSource += `module.exports = ${JSON.stringify(file)};\n`
113
104
  break
114
105
  }
115
106
  }
116
107
 
117
- const id = `${file}:${index}:${issuerFile}:${fromImport}`
118
-
119
- // 由于webpack中moduleMap只在compilation维度有效,不同子编译之间可能会对相同的引用文件进行重复的无效抽取,建立全局extractedMap避免这种情况出现
120
- if (extractedMap[id]) {
121
- extractedMap[id].modules.push(this._module)
122
- return extractedMap[id].resultSource
123
- }
124
- const nativeCallback = this.async()
125
- extractedMap[id] = {
126
- resultSource,
127
- dep: null,
128
- modules: [this._module]
129
- }
130
-
131
- // 使用子编译器生成需要抽离的json,styles和template
132
- const contentLoader = normalize.lib('content-loader')
133
- const request = `!!${contentLoader}?${JSON.stringify(options)}!${this.resource}`
134
-
135
- const childFilename = 'extractor-filename'
136
- const outputOptions = {
137
- filename: childFilename
138
- }
139
- const childCompiler = mainCompilation.createChildCompiler(request, outputOptions, [
140
- new NodeTemplatePlugin(outputOptions),
141
- new LibraryTemplatePlugin(null, 'commonjs2'),
142
- new NodeTargetPlugin(),
143
- new SingleEntryPlugin(this.context, request, filename),
144
- new LimitChunkCountPlugin({ maxChunks: 1 })
145
- ])
146
-
147
- childCompiler.hooks.thisCompilation.tap('MpxWebpackPlugin', (compilation) => {
148
- compilation.hooks.normalModuleLoader.tap('MpxWebpackPlugin', (loaderContext) => {
149
- // 传递编译结果,子编译器进入content-loader后直接输出
150
- loaderContext.__mpx__ = {
151
- content,
152
- fileDependencies: this.getDependencies(),
153
- contextDependencies: this.getContextDependencies()
154
- }
155
- })
156
- compilation.hooks.succeedEntry.tap('MpxWebpackPlugin', (entry, name, module) => {
157
- const dep = new ChildCompileDependency(module)
158
- extractedMap[id].dep = dep
159
- })
160
- })
161
-
162
- let source
163
- childCompiler.hooks.afterCompile.tapAsync('MpxWebpackPlugin', (compilation, callback) => {
164
- source = compilation.assets[childFilename] && compilation.assets[childFilename].source()
165
-
166
- // Remove all chunk assets
167
- compilation.chunks.forEach((chunk) => {
168
- chunk.files.forEach((file) => {
169
- delete compilation.assets[file]
170
- })
171
- })
172
-
173
- callback()
174
- })
175
-
176
- childCompiler.runAsChild((err, entries, compilation) => {
177
- if (err) return nativeCallback(err)
178
- if (compilation.errors.length > 0) {
179
- mainCompilation.errors.push(...compilation.errors)
180
- }
181
-
182
- compilation.fileDependencies.forEach((dep) => {
183
- this.addDependency(dep)
184
- }, this)
185
- compilation.contextDependencies.forEach((dep) => {
186
- this.addContextDependency(dep)
187
- }, this)
188
-
189
- if (!source) {
190
- return nativeCallback(new Error('Didn\'t get a result from child compiler'))
191
- }
192
-
193
- try {
194
- let text = this.exec(source, request)
195
- if (Array.isArray(text)) {
196
- text = text.map((item) => {
197
- return item[1]
198
- }).join('\n')
199
- }
200
-
201
- extract(text, file, index, sideEffects)
202
-
203
- // 在production模式下移除extract残留空模块
204
- if (resultSource === defaultResultSource && this.minimize) {
205
- this._module.needRemove = true
206
- }
207
- } catch (err) {
208
- return nativeCallback(err)
209
- }
210
- if (resultSource) {
211
- nativeCallback(null, resultSource)
212
- } else {
213
- nativeCallback()
214
- }
215
- })
108
+ return resultSource
216
109
  }
@@ -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 RecordStaticResourceDependency = require('./dependencies/RecordStaticResourceDependency')
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 RecordStaticResourceDependency(resourcePath, 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