@mpxjs/webpack-plugin 2.7.53 → 2.7.54

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.
@@ -1,157 +1,259 @@
1
+ /* eslint-disable operator-linebreak */
1
2
  /*
2
3
  MIT License http://www.opensource.org/licenses/mit-license.php
3
4
  Author Tobias Koppers @sokra
4
- Modified by @hiyuki
5
5
  */
6
- const loaderUtils = require('loader-utils')
7
- const processCss = require('./processCss')
8
- const compileExports = require('./compile-exports')
9
- const createResolver = require('./createResolver')
10
- const isUrlRequest = require('../utils/is-url-request')
6
+ // base on css-loader@6.7.1
7
+
8
+ const postcss = require('postcss')
9
+ const postcssPkg = require('postcss/package.json')
10
+ const { satisfies } = require('semver')
11
+
12
+ const CssSyntaxError = require('./CssSyntaxError')
13
+ const Warning = require('./Warning')
14
+ const schema = require('./options.json')
15
+ const { icssParser, importParser, urlParser } = require('./plugins')
16
+ const {
17
+ normalizeOptions,
18
+ shouldUseModulesPlugins,
19
+ shouldUseImportPlugin,
20
+ shouldUseURLPlugin,
21
+ shouldUseIcssPlugin,
22
+ getPreRequester,
23
+ getExportCode,
24
+ getFilter,
25
+ getImportCode,
26
+ getModuleCode,
27
+ getModulesPlugins,
28
+ normalizeSourceMap,
29
+ sort,
30
+ combineRequests,
31
+ stringifyRequest
32
+ } = require('./utils')
11
33
  const createHelpers = require('../helpers')
12
34
 
13
- module.exports = function (content, map) {
14
- if (this.cacheable) this.cacheable()
35
+ module.exports = async function loader (content, map, meta) {
36
+ let rawOptions = this.getOptions(schema)
37
+ const plugins = []
15
38
  const callback = this.async()
16
- const query = loaderUtils.getOptions(this) || {}
17
- const moduleMode = query.modules || query.module
18
- const camelCaseKeys = query.camelCase || query.camelcase
19
- const resolve = createResolver(query.alias)
39
+
20
40
  const mpx = this.getMpx()
21
41
  const externals = mpx.externals
22
42
  const root = mpx.projectRoot
23
43
  const sourceMap = mpx.cssSourceMap || false
24
44
 
25
- if (sourceMap) {
26
- if (map) {
27
- if (typeof map === 'string') {
28
- map = JSON.stringify(map)
29
- }
30
-
31
- if (map.sources) {
32
- map.sources = map.sources.map(function (source) {
33
- return source.replace(/\\/g, '/')
34
- })
35
- map.sourceRoot = ''
36
- }
37
- }
38
- } else {
39
- // Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
40
- map = null
45
+ let options
46
+
47
+ try {
48
+ options = normalizeOptions(rawOptions, this)
49
+ options = Object.assign({}, options, { sourceMap, root, externals })
50
+ } catch (error) {
51
+ callback(error)
52
+
53
+ return
41
54
  }
42
55
 
43
- const { getRequestString } = createHelpers(this)
56
+ const replacements = []
57
+ const exports = []
44
58
 
45
- processCss(content, map, {
46
- mode: moduleMode ? 'local' : 'global',
47
- from: loaderUtils.getRemainingRequest(this).split('!').pop(),
48
- to: loaderUtils.getCurrentRequest(this).split('!').pop(),
49
- query,
50
- resolve,
51
- minimize: this.minimize,
52
- loaderContext: this,
53
- sourceMap
54
- }, (err, result) => {
55
- if (err) return callback(err)
56
-
57
- let cssAsString = JSON.stringify(result.source)
58
-
59
- const alreadyImported = {}
60
- const importJs = result.importItems.filter((imp) => {
61
- if (!imp.mediaQuery) {
62
- if (alreadyImported[imp.url]) {
63
- return false
64
- }
65
- alreadyImported[imp.url] = true
66
- }
67
- return true
68
- }).map((imp, i) => {
69
- if (!isUrlRequest(imp.url, root, externals)) {
70
- return 'exports.push([module.id, ' +
71
- JSON.stringify('@import url(' + imp.url + ');') + ', ' +
72
- JSON.stringify(imp.mediaQuery) + ']);'
73
- } else {
74
- const requestString = getRequestString('styles', { src: imp.url }, {
75
- isStatic: true,
76
- issuerResource: this.resource,
77
- fromImport: true
78
- }, i)
79
- return 'exports.push([module.id, ' +
80
- JSON.stringify('@import "') +
81
- '+ require(' + requestString + ') +' +
82
- JSON.stringify('";') + ', ' +
83
- JSON.stringify(imp.mediaQuery) + ']);'
84
- }
85
- }).join('\n')
86
-
87
- const importItemMatcher = (item) => {
88
- const match = result.importItemRegExp.exec(item)
89
- const idx = +match[1]
90
- const importItem = result.importItems[idx]
91
- const importUrl = importItem.url
92
- return '" + require(' + loaderUtils.stringifyRequest(this, importUrl) + ').locals' +
93
- '[' + JSON.stringify(importItem.export) + '] + "'
59
+ if (shouldUseModulesPlugins(options)) {
60
+ plugins.push(...getModulesPlugins(options, this))
61
+ }
62
+
63
+ let importPluginImports = []
64
+ const importPluginApi = []
65
+
66
+ let isSupportAbsoluteURL = false
67
+
68
+ // TODO enable by default in the next major release
69
+ if (
70
+ this._compilation &&
71
+ this._compilation.options &&
72
+ this._compilation.options.experiments &&
73
+ this._compilation.options.experiments.buildHttp
74
+ ) {
75
+ isSupportAbsoluteURL = true
76
+ }
77
+ const isSupportDataURL =
78
+ options.esModule && Boolean('fsStartTime' in this._compiler)
79
+
80
+ if (shouldUseImportPlugin(options)) {
81
+ plugins.push(
82
+ importParser({
83
+ isSupportAbsoluteURL: false,
84
+ isSupportDataURL: false,
85
+ isCSSStyleSheet: options.exportType === 'css-style-sheet',
86
+ loaderContext: this,
87
+ imports: importPluginImports,
88
+ api: importPluginApi,
89
+ filter: options.import.filter,
90
+ urlHandler: (url) =>
91
+ stringifyRequest(
92
+ this,
93
+ combineRequests(getPreRequester(this)(options.importLoaders), url)
94
+ ),
95
+ externals: options.externals,
96
+ root: options.root
97
+ })
98
+ )
99
+ }
100
+
101
+ const urlPluginImports = []
102
+
103
+ if (shouldUseURLPlugin(options)) {
104
+ const needToResolveURL = !options.esModule
105
+
106
+ plugins.push(
107
+ urlParser({
108
+ isSupportAbsoluteURL,
109
+ isSupportDataURL,
110
+ imports: urlPluginImports,
111
+ replacements,
112
+ context: this.context,
113
+ rootContext: this.rootContext,
114
+ filter: getFilter(options.url.filter, this.resourcePath),
115
+ resolver: needToResolveURL
116
+ ? this.getResolve({ mainFiles: [], extensions: [] })
117
+ : // eslint-disable-next-line no-undefined
118
+ undefined,
119
+ urlHandler: (url) => stringifyRequest(this, url)
120
+ // Support data urls as input in new URL added in webpack@5.38.0
121
+ })
122
+ )
123
+ }
124
+
125
+ const icssPluginImports = []
126
+ const icssPluginApi = []
127
+
128
+ const needToUseIcssPlugin = shouldUseIcssPlugin(options)
129
+
130
+ if (needToUseIcssPlugin) {
131
+ plugins.push(
132
+ icssParser({
133
+ loaderContext: this,
134
+ imports: icssPluginImports,
135
+ api: icssPluginApi,
136
+ replacements,
137
+ exports,
138
+ urlHandler: (url) =>
139
+ stringifyRequest(
140
+ this,
141
+ combineRequests(getPreRequester(this)(options.importLoaders), url)
142
+ )
143
+ })
144
+ )
145
+ }
146
+
147
+ // Reuse CSS AST (PostCSS AST e.g 'postcss-loader') to avoid reparsing
148
+ if (meta) {
149
+ const { ast } = meta
150
+
151
+ if (
152
+ ast &&
153
+ ast.type === 'postcss' &&
154
+ satisfies(ast.version, `^${postcssPkg.version}`)
155
+ ) {
156
+ // eslint-disable-next-line no-param-reassign
157
+ content = ast.root
94
158
  }
159
+ }
160
+
161
+ const { resourcePath } = this
162
+
163
+ let result
95
164
 
96
- cssAsString = cssAsString.replace(result.importItemRegExpG, importItemMatcher)
97
-
98
- // helper for ensuring valid CSS strings from requires
99
- let urlEscapeHelper = ''
100
-
101
- if (query.url !== false && result.urlItems.length > 0) {
102
- urlEscapeHelper = 'var escape = require(' + loaderUtils.stringifyRequest(this, '!!' + require.resolve('./url/escape.js')) + ');\n'
103
-
104
- cssAsString = cssAsString.replace(result.urlItemRegExpG, (item) => {
105
- const match = result.urlItemRegExp.exec(item)
106
- let idx = +match[1]
107
- const urlItem = result.urlItems[idx]
108
- const url = resolve(urlItem.url)
109
- idx = url.indexOf('?#')
110
- if (idx < 0) idx = url.indexOf('#')
111
- var urlRequest
112
- if (idx > 0) { // idx === 0 is catched by isUrlRequest
113
- // in cases like url('webfont.eot?#iefix')
114
- urlRequest = url.substr(0, idx)
115
- return '" + escape(require(' + loaderUtils.stringifyRequest(this, urlRequest) + ')) + "' +
116
- url.substr(idx)
165
+ try {
166
+ result = await postcss(plugins).process(content, {
167
+ hideNothingWarning: true,
168
+ from: resourcePath,
169
+ to: resourcePath,
170
+ map: options.sourceMap
171
+ ? {
172
+ prev: map ? normalizeSourceMap(map, resourcePath) : null,
173
+ inline: false,
174
+ annotation: false
117
175
  }
118
- urlRequest = url
119
- return '" + escape(require(' + loaderUtils.stringifyRequest(this, urlRequest) + ')) + "'
120
- })
176
+ : false
177
+ })
178
+ } catch (error) {
179
+ if (error.file) {
180
+ this.addDependency(error.file)
121
181
  }
122
182
 
123
- let exportJs = compileExports(result, importItemMatcher, camelCaseKeys)
124
- if (exportJs) {
125
- exportJs = 'exports.locals = ' + exportJs + ';'
183
+ callback(
184
+ error.name === 'CssSyntaxError' ? new CssSyntaxError(error) : error
185
+ )
186
+
187
+ return
188
+ }
189
+
190
+ for (const warning of result.warnings()) {
191
+ this.emitWarning(new Warning(warning))
192
+ }
193
+
194
+ const { getRequestString } = createHelpers(this)
195
+
196
+ // 符合css后缀名的文件经过mpx处理后会带上相应的后缀防止 WebPack 的默认解析规则,后续 require/import 相应路径时,导出的不是一段 css 代码了,事实上是一个文件路径。
197
+ importPluginImports = importPluginImports.map((importItem, index) => {
198
+ const splittedUrl = importItem.url.slice(1, -1)
199
+ const requestString = getRequestString('styles', { src: splittedUrl }, {
200
+ isStatic: true,
201
+ issuerResource: this.resource,
202
+ fromImport: true
203
+ }, index)
204
+ return {
205
+ ...importItem,
206
+ url: requestString
126
207
  }
208
+ })
127
209
 
128
- let moduleJs
129
- if (sourceMap && result.map) {
130
- // add a SourceMap
131
- map = result.map
132
- if (map.sources) {
133
- map.sources = map.sources.map(function (source) {
134
- return source.split('!').pop().replace(/\\/g, '/')
135
- }, this)
136
- map.sourceRoot = ''
137
- }
138
- map.file = map.file.split('!').pop().replace(/\\/g, '/')
139
- map = JSON.stringify(map)
140
- moduleJs = 'exports.push([module.id, ' + cssAsString + ', "", ' + map + ']);'
210
+ const imports = []
211
+ .concat(icssPluginImports.sort(sort))
212
+ .concat(importPluginImports.sort())
213
+ .concat(urlPluginImports.sort(sort))
214
+
215
+ const api = []
216
+ .concat(importPluginApi.sort(sort))
217
+ .concat(icssPluginApi.sort(sort))
218
+
219
+ if (options.modules.exportOnlyLocals !== true) {
220
+ imports.unshift({
221
+ type: 'api_import',
222
+ importName: '___CSS_LOADER_API_IMPORT___',
223
+ url: stringifyRequest(this, require.resolve('./runtime/api'))
224
+ })
225
+
226
+ if (options.sourceMap) {
227
+ imports.unshift({
228
+ importName: '___CSS_LOADER_API_SOURCEMAP_IMPORT___',
229
+ url: stringifyRequest(this, require.resolve('./runtime/sourceMaps'))
230
+ })
141
231
  } else {
142
- moduleJs = 'exports.push([module.id, ' + cssAsString + ', ""]);'
232
+ imports.unshift({
233
+ importName: '___CSS_LOADER_API_NO_SOURCEMAP_IMPORT___',
234
+ url: stringifyRequest(this, require.resolve('./runtime/noSourceMaps'))
235
+ })
143
236
  }
237
+ }
144
238
 
145
- // embed runtime
146
- callback(null, urlEscapeHelper +
147
- 'exports = module.exports = require(' +
148
- loaderUtils.stringifyRequest(this, '!!' + require.resolve('./css-base.js')) +
149
- ')(' + sourceMap + ');\n' +
150
- '// imports\n' +
151
- importJs + '\n\n' +
152
- '// module\n' +
153
- moduleJs + '\n\n' +
154
- '// exports\n' +
155
- exportJs)
156
- })
239
+ const importCode = getImportCode(imports, options)
240
+
241
+ let moduleCode
242
+
243
+ try {
244
+ moduleCode = getModuleCode(result, api, replacements, options, this)
245
+ } catch (error) {
246
+ callback(error)
247
+
248
+ return
249
+ }
250
+
251
+ const exportCode = getExportCode(
252
+ exports,
253
+ replacements,
254
+ needToUseIcssPlugin,
255
+ options
256
+ )
257
+
258
+ callback(null, `${importCode}${moduleCode}${exportCode}`)
157
259
  }
@@ -0,0 +1,209 @@
1
+ {
2
+ "title": "CSS Loader options",
3
+ "additionalProperties": false,
4
+ "properties": {
5
+ "url": {
6
+ "description": "Allows to enables/disables `url()`/`image-set()` functions handling.",
7
+ "link": "https://github.com/webpack-contrib/css-loader#url",
8
+ "anyOf": [
9
+ {
10
+ "type": "boolean"
11
+ },
12
+ {
13
+ "type": "object",
14
+ "properties": {
15
+ "filter": {
16
+ "instanceof": "Function"
17
+ }
18
+ },
19
+ "additionalProperties": false
20
+ }
21
+ ]
22
+ },
23
+ "import": {
24
+ "description": "Allows to enables/disables `@import` at-rules handling.",
25
+ "link": "https://github.com/webpack-contrib/css-loader#import",
26
+ "anyOf": [
27
+ {
28
+ "type": "boolean"
29
+ },
30
+ {
31
+ "type": "object",
32
+ "properties": {
33
+ "filter": {
34
+ "instanceof": "Function"
35
+ }
36
+ },
37
+ "additionalProperties": false
38
+ }
39
+ ]
40
+ },
41
+ "modules": {
42
+ "description": "Allows to enable/disable CSS Modules or ICSS and setup configuration.",
43
+ "link": "https://github.com/webpack-contrib/css-loader#modules",
44
+ "anyOf": [
45
+ {
46
+ "type": "boolean"
47
+ },
48
+ {
49
+ "enum": ["local", "global", "pure", "icss"]
50
+ },
51
+ {
52
+ "type": "object",
53
+ "additionalProperties": false,
54
+ "properties": {
55
+ "auto": {
56
+ "description": "Allows auto enable CSS modules based on filename.",
57
+ "link": "https://github.com/webpack-contrib/css-loader#auto",
58
+ "anyOf": [
59
+ {
60
+ "instanceof": "RegExp"
61
+ },
62
+ {
63
+ "instanceof": "Function"
64
+ },
65
+ {
66
+ "type": "boolean"
67
+ }
68
+ ]
69
+ },
70
+ "mode": {
71
+ "description": "Setup `mode` option.",
72
+ "link": "https://github.com/webpack-contrib/css-loader#mode",
73
+ "anyOf": [
74
+ {
75
+ "enum": ["local", "global", "pure", "icss"]
76
+ },
77
+ {
78
+ "instanceof": "Function"
79
+ }
80
+ ]
81
+ },
82
+ "localIdentName": {
83
+ "description": "Allows to configure the generated local ident name.",
84
+ "link": "https://github.com/webpack-contrib/css-loader#localidentname",
85
+ "type": "string",
86
+ "minLength": 1
87
+ },
88
+ "localIdentContext": {
89
+ "description": "Allows to redefine basic loader context for local ident name.",
90
+ "link": "https://github.com/webpack-contrib/css-loader#localidentcontext",
91
+ "type": "string",
92
+ "minLength": 1
93
+ },
94
+ "localIdentHashSalt": {
95
+ "description": "Allows to add custom hash to generate more unique classes.",
96
+ "link": "https://github.com/webpack-contrib/css-loader#localidenthashsalt",
97
+ "type": "string",
98
+ "minLength": 1
99
+ },
100
+ "localIdentHashFunction": {
101
+ "description": "Allows to specify hash function to generate classes.",
102
+ "link": "https://github.com/webpack-contrib/css-loader#localidenthashfunction",
103
+ "type": "string",
104
+ "minLength": 1
105
+ },
106
+ "localIdentHashDigest": {
107
+ "description": "Allows to specify hash digest to generate classes.",
108
+ "link": "https://github.com/webpack-contrib/css-loader#localidenthashdigest",
109
+ "type": "string",
110
+ "minLength": 1
111
+ },
112
+ "localIdentHashDigestLength": {
113
+ "description": "Allows to specify hash digest length to generate classes.",
114
+ "link": "https://github.com/webpack-contrib/css-loader#localidenthashdigestlength",
115
+ "type": "number"
116
+ },
117
+ "hashStrategy": {
118
+ "description": "Allows to specify should localName be used when computing the hash.",
119
+ "link": "https://github.com/webpack-contrib/css-loader#hashstrategy",
120
+ "enum": ["resource-path-and-local-name", "minimal-subset"]
121
+ },
122
+ "localIdentRegExp": {
123
+ "description": "Allows to specify custom RegExp for local ident name.",
124
+ "link": "https://github.com/webpack-contrib/css-loader#localidentregexp",
125
+ "anyOf": [
126
+ {
127
+ "type": "string",
128
+ "minLength": 1
129
+ },
130
+ {
131
+ "instanceof": "RegExp"
132
+ }
133
+ ]
134
+ },
135
+ "getLocalIdent": {
136
+ "description": "Allows to specify a function to generate the classname.",
137
+ "link": "https://github.com/webpack-contrib/css-loader#getlocalident",
138
+ "instanceof": "Function"
139
+ },
140
+ "namedExport": {
141
+ "description": "Enables/disables ES modules named export for locals.",
142
+ "link": "https://github.com/webpack-contrib/css-loader#namedexport",
143
+ "type": "boolean"
144
+ },
145
+ "exportGlobals": {
146
+ "description": "Allows to export names from global class or id, so you can use that as local name.",
147
+ "link": "https://github.com/webpack-contrib/css-loader#exportglobals",
148
+ "type": "boolean"
149
+ },
150
+ "exportLocalsConvention": {
151
+ "description": "Style of exported classnames.",
152
+ "link": "https://github.com/webpack-contrib/css-loader#localsconvention",
153
+ "anyOf": [
154
+ {
155
+ "enum": [
156
+ "asIs",
157
+ "camelCase",
158
+ "camelCaseOnly",
159
+ "dashes",
160
+ "dashesOnly"
161
+ ]
162
+ },
163
+ {
164
+ "instanceof": "Function"
165
+ }
166
+ ]
167
+ },
168
+ "exportOnlyLocals": {
169
+ "description": "Export only locals.",
170
+ "link": "https://github.com/webpack-contrib/css-loader#exportonlylocals",
171
+ "type": "boolean"
172
+ }
173
+ }
174
+ }
175
+ ]
176
+ },
177
+ "sourceMap": {
178
+ "description": "Allows to enable/disable source maps.",
179
+ "link": "https://github.com/webpack-contrib/css-loader#sourcemap",
180
+ "type": "boolean"
181
+ },
182
+ "importLoaders": {
183
+ "description": "Allows enables/disables or setups number of loaders applied before CSS loader for `@import`/CSS Modules and ICSS imports.",
184
+ "link": "https://github.com/webpack-contrib/css-loader#importloaders",
185
+ "anyOf": [
186
+ {
187
+ "type": "boolean"
188
+ },
189
+ {
190
+ "type": "string"
191
+ },
192
+ {
193
+ "type": "integer"
194
+ }
195
+ ]
196
+ },
197
+ "esModule": {
198
+ "description": "Use the ES modules syntax.",
199
+ "link": "https://github.com/webpack-contrib/css-loader#esmodule",
200
+ "type": "boolean"
201
+ },
202
+ "exportType": {
203
+ "description": "Allows exporting styles as array with modules, string or constructable stylesheet (i.e. `CSSStyleSheet`).",
204
+ "link": "https://github.com/webpack-contrib/css-loader#exporttype",
205
+ "enum": ["array", "string", "css-style-sheet"]
206
+ }
207
+ },
208
+ "type": "object"
209
+ }
@@ -0,0 +1,5 @@
1
+ const importParser = require('./postcss-import-parser')
2
+ const icssParser = require('./postcss-icss-parser')
3
+ const urlParser = require('./postcss-url-parser')
4
+
5
+ module.exports = { importParser, icssParser, urlParser }