@mpxjs/webpack-plugin 2.8.0 → 2.8.6

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.
@@ -0,0 +1,447 @@
1
+ const valueParser = require('postcss-value-parser')
2
+
3
+ const {
4
+ resolveRequests,
5
+ normalizeUrl,
6
+ requestify,
7
+ isURLRequestable,
8
+ WEBPACK_IGNORE_COMMENT_REGEXP
9
+ } = require('../utils')
10
+
11
+ const isUrlFunc = /url/i
12
+ const isImageSetFunc = /^(?:-webkit-)?image-set$/i
13
+ const needParseDeclaration = /(?:url|(?:-webkit-)?image-set)\(/i
14
+
15
+ function getNodeFromUrlFunc (node) {
16
+ return node.nodes && node.nodes[0]
17
+ }
18
+
19
+ function getWebpackIgnoreCommentValue (index, nodes, inBetween) {
20
+ if (index === 0 && typeof inBetween !== 'undefined') {
21
+ return inBetween
22
+ }
23
+
24
+ let prevValueNode = nodes[index - 1]
25
+
26
+ if (!prevValueNode) {
27
+ // eslint-disable-next-line consistent-return
28
+ return
29
+ }
30
+
31
+ if (prevValueNode.type === 'space') {
32
+ if (!nodes[index - 2]) {
33
+ // eslint-disable-next-line consistent-return
34
+ return
35
+ }
36
+
37
+ prevValueNode = nodes[index - 2]
38
+ }
39
+
40
+ if (prevValueNode.type !== 'comment') {
41
+ // eslint-disable-next-line consistent-return
42
+ return
43
+ }
44
+
45
+ const matched = prevValueNode.value.match(WEBPACK_IGNORE_COMMENT_REGEXP)
46
+
47
+ return matched && matched[2] === 'true'
48
+ }
49
+
50
+ function shouldHandleURL (url, declaration, result, options) {
51
+ if (url.length === 0) {
52
+ result.warn(`Unable to find uri in '${declaration.toString()}'`, {
53
+ node: declaration
54
+ })
55
+
56
+ return { requestable: false, needResolve: false }
57
+ }
58
+
59
+ return isURLRequestable(url, options)
60
+ }
61
+
62
+ function parseDeclaration (declaration, key, result, options) {
63
+ if (!needParseDeclaration.test(declaration[key])) {
64
+ return
65
+ }
66
+
67
+ const parsed = valueParser(
68
+ declaration.raws && declaration.raws.value && declaration.raws.value.raw
69
+ ? declaration.raws.value.raw
70
+ : declaration[key]
71
+ )
72
+
73
+ let inBetween
74
+
75
+ if (declaration.raws && declaration.raws.between) {
76
+ const lastCommentIndex = declaration.raws.between.lastIndexOf('/*')
77
+
78
+ const matched = declaration.raws.between
79
+ .slice(lastCommentIndex)
80
+ .match(WEBPACK_IGNORE_COMMENT_REGEXP)
81
+
82
+ if (matched) {
83
+ inBetween = matched[2] === 'true'
84
+ }
85
+ }
86
+
87
+ let isIgnoreOnDeclaration = false
88
+
89
+ const prevNode = declaration.prev()
90
+
91
+ if (prevNode && prevNode.type === 'comment') {
92
+ const matched = prevNode.text.match(WEBPACK_IGNORE_COMMENT_REGEXP)
93
+
94
+ if (matched) {
95
+ isIgnoreOnDeclaration = matched[2] === 'true'
96
+ }
97
+ }
98
+
99
+ let needIgnore
100
+
101
+ const parsedURLs = []
102
+
103
+ parsed.walk((valueNode, index, valueNodes) => {
104
+ if (valueNode.type !== 'function') {
105
+ return
106
+ }
107
+
108
+ if (isUrlFunc.test(valueNode.value)) {
109
+ needIgnore = getWebpackIgnoreCommentValue(index, valueNodes, inBetween)
110
+
111
+ if (
112
+ (isIgnoreOnDeclaration && typeof needIgnore === 'undefined') ||
113
+ needIgnore
114
+ ) {
115
+ if (needIgnore) {
116
+ // eslint-disable-next-line no-undefined
117
+ needIgnore = undefined
118
+ }
119
+
120
+ return
121
+ }
122
+
123
+ const { nodes } = valueNode
124
+ const isStringValue = nodes.length !== 0 && nodes[0].type === 'string'
125
+ let url = isStringValue ? nodes[0].value : valueParser.stringify(nodes)
126
+
127
+ url = normalizeUrl(url, isStringValue)
128
+
129
+ const { requestable, needResolve } = shouldHandleURL(
130
+ url,
131
+ declaration,
132
+ result,
133
+ options
134
+ )
135
+
136
+ // Do not traverse inside `url`
137
+ if (!requestable) {
138
+ // eslint-disable-next-line consistent-return
139
+ return false
140
+ }
141
+
142
+ const queryParts = url.split('!')
143
+
144
+ let prefix
145
+
146
+ if (queryParts.length > 1) {
147
+ url = queryParts.pop()
148
+ prefix = queryParts.join('!')
149
+ }
150
+
151
+ parsedURLs.push({
152
+ declaration,
153
+ parsed,
154
+ node: getNodeFromUrlFunc(valueNode),
155
+ prefix,
156
+ url,
157
+ needQuotes: false,
158
+ needResolve
159
+ })
160
+
161
+ // eslint-disable-next-line consistent-return
162
+ return false
163
+ } else if (isImageSetFunc.test(valueNode.value)) {
164
+ for (const [innerIndex, nNode] of valueNode.nodes.entries()) {
165
+ const { type, value } = nNode
166
+
167
+ if (type === 'function' && isUrlFunc.test(value)) {
168
+ needIgnore = getWebpackIgnoreCommentValue(
169
+ innerIndex,
170
+ valueNode.nodes
171
+ )
172
+
173
+ if (
174
+ (isIgnoreOnDeclaration && typeof needIgnore === 'undefined') ||
175
+ needIgnore
176
+ ) {
177
+ if (needIgnore) {
178
+ // eslint-disable-next-line no-undefined
179
+ needIgnore = undefined
180
+ }
181
+
182
+ // eslint-disable-next-line no-continue
183
+ continue
184
+ }
185
+
186
+ const { nodes } = nNode
187
+ const isStringValue =
188
+ nodes.length !== 0 && nodes[0].type === 'string'
189
+ let url = isStringValue
190
+ ? nodes[0].value
191
+ : valueParser.stringify(nodes)
192
+
193
+ url = normalizeUrl(url, isStringValue)
194
+
195
+ const { requestable, needResolve } = shouldHandleURL(
196
+ url,
197
+ declaration,
198
+ result,
199
+ options
200
+ )
201
+
202
+ // Do not traverse inside `url`
203
+ if (!requestable) {
204
+ // eslint-disable-next-line consistent-return
205
+ return false
206
+ }
207
+
208
+ const queryParts = url.split('!')
209
+
210
+ let prefix
211
+
212
+ if (queryParts.length > 1) {
213
+ url = queryParts.pop()
214
+ prefix = queryParts.join('!')
215
+ }
216
+
217
+ parsedURLs.push({
218
+ declaration,
219
+ parsed,
220
+ node: getNodeFromUrlFunc(nNode),
221
+ prefix,
222
+ url,
223
+ needQuotes: false,
224
+ needResolve
225
+ })
226
+ } else if (type === 'string') {
227
+ needIgnore = getWebpackIgnoreCommentValue(
228
+ innerIndex,
229
+ valueNode.nodes
230
+ )
231
+
232
+ if (
233
+ (isIgnoreOnDeclaration && typeof needIgnore === 'undefined') ||
234
+ needIgnore
235
+ ) {
236
+ if (needIgnore) {
237
+ // eslint-disable-next-line no-undefined
238
+ needIgnore = undefined
239
+ }
240
+
241
+ // eslint-disable-next-line no-continue
242
+ continue
243
+ }
244
+
245
+ let url = normalizeUrl(value, true)
246
+
247
+ const { requestable, needResolve } = shouldHandleURL(
248
+ url,
249
+ declaration,
250
+ result,
251
+ options
252
+ )
253
+
254
+ // Do not traverse inside `url`
255
+ if (!requestable) {
256
+ // eslint-disable-next-line consistent-return
257
+ return false
258
+ }
259
+
260
+ const queryParts = url.split('!')
261
+
262
+ let prefix
263
+
264
+ if (queryParts.length > 1) {
265
+ url = queryParts.pop()
266
+ prefix = queryParts.join('!')
267
+ }
268
+
269
+ parsedURLs.push({
270
+ declaration,
271
+ parsed,
272
+ node: nNode,
273
+ prefix,
274
+ url,
275
+ needQuotes: true,
276
+ needResolve
277
+ })
278
+ }
279
+ }
280
+
281
+ // Do not traverse inside `image-set`
282
+ // eslint-disable-next-line consistent-return
283
+ return false
284
+ }
285
+ })
286
+
287
+ // eslint-disable-next-line consistent-return
288
+ return parsedURLs
289
+ }
290
+
291
+ const plugin = (options = {}) => {
292
+ return {
293
+ postcssPlugin: 'postcss-url-parser',
294
+ prepare (result) {
295
+ const parsedDeclarations = []
296
+
297
+ return {
298
+ Declaration (declaration) {
299
+ const { isSupportDataURL, isSupportAbsoluteURL } = options
300
+ const parsedURL = parseDeclaration(declaration, 'value', result, {
301
+ isSupportDataURL,
302
+ isSupportAbsoluteURL
303
+ })
304
+
305
+ if (!parsedURL) {
306
+ return
307
+ }
308
+
309
+ parsedDeclarations.push(...parsedURL)
310
+ },
311
+ async OnceExit () {
312
+ if (parsedDeclarations.length === 0) {
313
+ return
314
+ }
315
+
316
+ const resolvedDeclarations = await Promise.all(
317
+ parsedDeclarations.map(async (parsedDeclaration) => {
318
+ const { url, needResolve } = parsedDeclaration
319
+
320
+ if (options.filter) {
321
+ const needKeep = await options.filter(url)
322
+
323
+ if (!needKeep) {
324
+ // eslint-disable-next-line consistent-return
325
+ return
326
+ }
327
+ }
328
+
329
+ if (!needResolve) {
330
+ // eslint-disable-next-line consistent-return
331
+ return parsedDeclaration
332
+ }
333
+
334
+ const splittedUrl = url.split(/(\?)?#/)
335
+ const [pathname, query, hashOrQuery] = splittedUrl
336
+
337
+ let hash = query ? '?' : ''
338
+ hash += hashOrQuery ? `#${hashOrQuery}` : ''
339
+
340
+ const { resolver, rootContext } = options
341
+ const request = requestify(
342
+ pathname,
343
+ rootContext,
344
+ Boolean(resolver)
345
+ )
346
+
347
+ if (!resolver) {
348
+ // eslint-disable-next-line consistent-return
349
+ return { ...parsedDeclaration, url: request, hash }
350
+ }
351
+
352
+ const resolvedURL = await resolveRequests(
353
+ resolver,
354
+ options.context,
355
+ [...new Set([request, url])]
356
+ )
357
+
358
+ if (!resolvedURL) {
359
+ // eslint-disable-next-line consistent-return
360
+ return
361
+ }
362
+
363
+ // eslint-disable-next-line consistent-return
364
+ return { ...parsedDeclaration, url: resolvedURL, hash }
365
+ })
366
+ )
367
+
368
+ const urlToNameMap = new Map()
369
+ const urlToReplacementMap = new Map()
370
+
371
+ let hasUrlImportHelper = false
372
+
373
+ for (
374
+ let index = 0;
375
+ index <= resolvedDeclarations.length - 1;
376
+ index++
377
+ ) {
378
+ const item = resolvedDeclarations[index]
379
+
380
+ if (!item) {
381
+ // eslint-disable-next-line no-continue
382
+ continue
383
+ }
384
+
385
+ if (!hasUrlImportHelper) {
386
+ options.imports.push({
387
+ type: 'get_url_import',
388
+ importName: '___CSS_LOADER_GET_URL_IMPORT___',
389
+ url: options.urlHandler(
390
+ require.resolve('../runtime/getUrl.js')
391
+ ),
392
+ index: -1
393
+ })
394
+
395
+ hasUrlImportHelper = true
396
+ }
397
+
398
+ const { url, prefix } = item
399
+ const newUrl = prefix ? `${prefix}!${url}` : url
400
+ let importName = urlToNameMap.get(newUrl)
401
+
402
+ if (!importName) {
403
+ importName = `___CSS_LOADER_URL_IMPORT_${urlToNameMap.size}___`
404
+ urlToNameMap.set(newUrl, importName)
405
+
406
+ options.imports.push({
407
+ type: 'url',
408
+ importName,
409
+ url: options.resolver
410
+ ? options.urlHandler(newUrl)
411
+ : JSON.stringify(newUrl),
412
+ index
413
+ })
414
+ }
415
+
416
+ const { hash, needQuotes } = item
417
+ const replacementKey = JSON.stringify({ newUrl, hash, needQuotes })
418
+ let replacementName = urlToReplacementMap.get(replacementKey)
419
+
420
+ if (!replacementName) {
421
+ replacementName = `___CSS_LOADER_URL_REPLACEMENT_${urlToReplacementMap.size}___`
422
+ urlToReplacementMap.set(replacementKey, replacementName)
423
+
424
+ options.replacements.push({
425
+ replacementName,
426
+ importName,
427
+ hash,
428
+ needQuotes
429
+ })
430
+ }
431
+
432
+ // eslint-disable-next-line no-param-reassign
433
+ item.node.type = 'word'
434
+ // eslint-disable-next-line no-param-reassign
435
+ item.node.value = replacementName
436
+ // eslint-disable-next-line no-param-reassign
437
+ item.declaration.value = item.parsed.toString()
438
+ }
439
+ }
440
+ }
441
+ }
442
+ }
443
+ }
444
+
445
+ plugin.postcss = true
446
+
447
+ module.exports = plugin
@@ -0,0 +1,104 @@
1
+ /*
2
+ MIT License http://www.opensource.org/licenses/mit-license.php
3
+ Author Tobias Koppers @sokra
4
+ */
5
+ module.exports = (cssWithMappingToString) => {
6
+ const list = []
7
+
8
+ // return the list of modules as css string
9
+ list.toString = function toString () {
10
+ return this.map((item) => {
11
+ let content = ''
12
+
13
+ const needLayer = typeof item[5] !== 'undefined'
14
+
15
+ if (item[4]) {
16
+ content += `@supports (${item[4]}) {`
17
+ }
18
+
19
+ if (item[2]) {
20
+ content += `@media ${item[2]} {`
21
+ }
22
+
23
+ if (needLayer) {
24
+ content += `@layer${item[5].length > 0 ? ` ${item[5]}` : ''} {`
25
+ }
26
+
27
+ content += cssWithMappingToString(item)
28
+
29
+ if (needLayer) {
30
+ content += '}'
31
+ }
32
+
33
+ if (item[2]) {
34
+ content += '}'
35
+ }
36
+
37
+ if (item[4]) {
38
+ content += '}'
39
+ }
40
+
41
+ return content
42
+ }).join('')
43
+ }
44
+
45
+ // import a list of modules into the list
46
+ list.i = function i (modules, media, dedupe, supports, layer) {
47
+ if (typeof modules === 'string') {
48
+ modules = [[null, modules, undefined]]
49
+ }
50
+
51
+ const alreadyImportedModules = {}
52
+
53
+ if (dedupe) {
54
+ for (let k = 0; k < this.length; k++) {
55
+ const id = this[k][0]
56
+
57
+ if (id != null) {
58
+ alreadyImportedModules[id] = true
59
+ }
60
+ }
61
+ }
62
+
63
+ for (let k = 0; k < modules.length; k++) {
64
+ const item = [].concat(modules[k])
65
+
66
+ if (dedupe && alreadyImportedModules[item[0]]) {
67
+ continue
68
+ }
69
+
70
+ if (typeof layer !== 'undefined') {
71
+ if (typeof item[5] === 'undefined') {
72
+ item[5] = layer
73
+ } else {
74
+ item[1] = `@layer${item[5].length > 0 ? ` ${item[5]}` : ''} {${
75
+ item[1]
76
+ }}`
77
+ item[5] = layer
78
+ }
79
+ }
80
+
81
+ if (media) {
82
+ if (!item[2]) {
83
+ item[2] = media
84
+ } else {
85
+ item[1] = `@media ${item[2]} {${item[1]}}`
86
+ item[2] = media
87
+ }
88
+ }
89
+
90
+ if (supports) {
91
+ if (!item[4]) {
92
+ item[4] = `${supports}`
93
+ } else {
94
+ item[1] = `@supports (${item[4]}) {${item[1]}}`
95
+ item[4] = supports
96
+ }
97
+ }
98
+
99
+ list.push(item)
100
+ }
101
+ }
102
+
103
+ return list
104
+ }
@@ -0,0 +1,28 @@
1
+ module.exports = (url, options) => {
2
+ if (!options) {
3
+ options = {}
4
+ }
5
+
6
+ if (!url) {
7
+ return url
8
+ }
9
+
10
+ url = String(url.__esModule ? url.default : url)
11
+
12
+ // If url is already wrapped in quotes, remove them
13
+ if (/^['"].*['"]$/.test(url)) {
14
+ url = url.slice(1, -1)
15
+ }
16
+
17
+ if (options.hash) {
18
+ url += options.hash
19
+ }
20
+
21
+ // Should url be wrapped?
22
+ // See https://drafts.csswg.org/css-values-3/#urls
23
+ if (/["'() \t\n]|(%20)/.test(url) || options.needQuotes) {
24
+ return `"${url.replace(/"/g, '\\"').replace(/\n/g, '\\n')}"`
25
+ }
26
+
27
+ return url
28
+ }
@@ -0,0 +1 @@
1
+ module.exports = (i) => i[1]
@@ -0,0 +1,25 @@
1
+ module.exports = (item) => {
2
+ const content = item[1]
3
+ const cssMapping = item[3]
4
+
5
+ if (!cssMapping) {
6
+ return content
7
+ }
8
+
9
+ if (typeof btoa === 'function') {
10
+ // eslint-disable-next-line no-undef
11
+ const base64 = btoa(
12
+ unescape(encodeURIComponent(JSON.stringify(cssMapping)))
13
+ )
14
+ const data = `sourceMappingURL=data:application/json;charset=utf-8;base64,${base64}`
15
+ const sourceMapping = `/*# ${data} */`
16
+
17
+ const sourceURLs = cssMapping.sources.map(
18
+ (source) => `/*# sourceURL=${cssMapping.sourceRoot || ''}${source} */`
19
+ )
20
+
21
+ return [content].concat(sourceURLs).concat([sourceMapping]).join('\n')
22
+ }
23
+
24
+ return [content].join('\n')
25
+ }