css-loader 3.4.1 → 3.5.2
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.
- package/CHANGELOG.md +31 -0
- package/README.md +149 -11
- package/dist/index.js +44 -22
- package/dist/options.json +22 -2
- package/dist/plugins/postcss-icss-parser.js +27 -24
- package/dist/plugins/postcss-import-parser.js +89 -81
- package/dist/plugins/postcss-url-parser.js +71 -117
- package/dist/runtime/api.js +21 -3
- package/dist/utils.js +180 -198
- package/package.json +29 -28
|
@@ -17,112 +17,120 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|
|
17
17
|
|
|
18
18
|
const pluginName = 'postcss-import-parser';
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
const {
|
|
23
|
-
nodes
|
|
24
|
-
} = node;
|
|
25
|
-
const isStringValue = nodes.length !== 0 && nodes[0].type === 'string';
|
|
26
|
-
const url = isStringValue ? nodes[0].value : _postcssValueParser.default.stringify(nodes);
|
|
27
|
-
return {
|
|
28
|
-
url,
|
|
29
|
-
isStringValue
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (node.type === 'string') {
|
|
34
|
-
const url = node.value;
|
|
35
|
-
return {
|
|
36
|
-
url,
|
|
37
|
-
isStringValue: true
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function parseImport(params) {
|
|
45
|
-
const {
|
|
46
|
-
nodes
|
|
47
|
-
} = (0, _postcssValueParser.default)(params);
|
|
48
|
-
|
|
49
|
-
if (nodes.length === 0) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const value = getParsedValue(nodes[0]);
|
|
54
|
-
|
|
55
|
-
if (!value) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
let {
|
|
60
|
-
url
|
|
61
|
-
} = value;
|
|
62
|
-
|
|
63
|
-
if (url.trim().length === 0) {
|
|
64
|
-
return null;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if ((0, _loaderUtils.isUrlRequest)(url)) {
|
|
68
|
-
const {
|
|
69
|
-
isStringValue
|
|
70
|
-
} = value;
|
|
71
|
-
url = (0, _utils.normalizeUrl)(url, isStringValue);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
return {
|
|
75
|
-
url,
|
|
76
|
-
media: _postcssValueParser.default.stringify(nodes.slice(1)).trim().toLowerCase()
|
|
77
|
-
};
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function walkAtRules(css, result, filter) {
|
|
81
|
-
const items = [];
|
|
20
|
+
var _default = _postcss.default.plugin(pluginName, options => (css, result) => {
|
|
21
|
+
const importsMap = new Map();
|
|
82
22
|
css.walkAtRules(/^import$/i, atRule => {
|
|
83
23
|
// Convert only top-level @import
|
|
84
24
|
if (atRule.parent.type !== 'root') {
|
|
85
25
|
return;
|
|
86
|
-
}
|
|
26
|
+
} // Nodes do not exists - `@import url('http://') :root {}`
|
|
27
|
+
|
|
87
28
|
|
|
88
29
|
if (atRule.nodes) {
|
|
89
|
-
result.warn("It looks like you didn't end your @import statement correctly.
|
|
30
|
+
result.warn("It looks like you didn't end your @import statement correctly. Child nodes are attached to it.", {
|
|
90
31
|
node: atRule
|
|
91
32
|
});
|
|
92
33
|
return;
|
|
93
34
|
}
|
|
94
35
|
|
|
95
|
-
const
|
|
36
|
+
const {
|
|
37
|
+
nodes
|
|
38
|
+
} = (0, _postcssValueParser.default)(atRule.params); // No nodes - `@import ;`
|
|
39
|
+
// Invalid type - `@import foo-bar;`
|
|
96
40
|
|
|
97
|
-
if (
|
|
98
|
-
|
|
99
|
-
return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
|
|
41
|
+
if (nodes.length === 0 || nodes[0].type !== 'string' && nodes[0].type !== 'function') {
|
|
42
|
+
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
|
|
100
43
|
node: atRule
|
|
101
44
|
});
|
|
45
|
+
return;
|
|
102
46
|
}
|
|
103
47
|
|
|
104
|
-
|
|
48
|
+
let isStringValue;
|
|
49
|
+
let url;
|
|
50
|
+
|
|
51
|
+
if (nodes[0].type === 'string') {
|
|
52
|
+
isStringValue = true;
|
|
53
|
+
url = nodes[0].value;
|
|
54
|
+
} else if (nodes[0].type === 'function') {
|
|
55
|
+
// Invalid function - `@import nourl(test.css);`
|
|
56
|
+
if (nodes[0].value.toLowerCase() !== 'url') {
|
|
57
|
+
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
|
|
58
|
+
node: atRule
|
|
59
|
+
});
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
isStringValue = nodes[0].nodes.length !== 0 && nodes[0].nodes[0].type === 'string';
|
|
64
|
+
url = isStringValue ? nodes[0].nodes[0].value : _postcssValueParser.default.stringify(nodes[0].nodes);
|
|
65
|
+
} // Empty url - `@import "";` or `@import url();`
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
if (url.trim().length === 0) {
|
|
69
|
+
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
|
|
70
|
+
node: atRule
|
|
71
|
+
});
|
|
105
72
|
return;
|
|
106
73
|
}
|
|
107
74
|
|
|
108
|
-
|
|
109
|
-
items.push(parsed);
|
|
110
|
-
});
|
|
111
|
-
return items;
|
|
112
|
-
}
|
|
75
|
+
const isRequestable = (0, _loaderUtils.isUrlRequest)(url);
|
|
113
76
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
77
|
+
if (isRequestable) {
|
|
78
|
+
url = (0, _utils.normalizeUrl)(url, isStringValue); // Empty url after normalize - `@import '\
|
|
79
|
+
// \
|
|
80
|
+
// \
|
|
81
|
+
// ';
|
|
82
|
+
|
|
83
|
+
if (url.trim().length === 0) {
|
|
84
|
+
result.warn(`Unable to find uri in "${atRule.toString()}"`, {
|
|
85
|
+
node: atRule
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const media = _postcssValueParser.default.stringify(nodes.slice(1)).trim().toLowerCase();
|
|
92
|
+
|
|
93
|
+
if (options.filter && !options.filter({
|
|
118
94
|
url,
|
|
119
95
|
media
|
|
120
|
-
}
|
|
96
|
+
})) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
atRule.remove();
|
|
101
|
+
|
|
102
|
+
if (isRequestable) {
|
|
103
|
+
const importKey = url;
|
|
104
|
+
let importName = importsMap.get(importKey);
|
|
105
|
+
|
|
106
|
+
if (!importName) {
|
|
107
|
+
importName = `___CSS_LOADER_AT_RULE_IMPORT_${importsMap.size}___`;
|
|
108
|
+
importsMap.set(importKey, importName);
|
|
109
|
+
result.messages.push({
|
|
110
|
+
type: 'import',
|
|
111
|
+
value: {
|
|
112
|
+
importName,
|
|
113
|
+
url: options.urlHandler ? options.urlHandler(url) : url
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
result.messages.push({
|
|
119
|
+
type: 'api-import',
|
|
120
|
+
value: {
|
|
121
|
+
type: 'internal',
|
|
122
|
+
importName,
|
|
123
|
+
media
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
121
129
|
result.messages.push({
|
|
122
130
|
pluginName,
|
|
123
|
-
type: 'import',
|
|
131
|
+
type: 'api-import',
|
|
124
132
|
value: {
|
|
125
|
-
type: '
|
|
133
|
+
type: 'external',
|
|
126
134
|
url,
|
|
127
135
|
media
|
|
128
136
|
}
|
|
@@ -41,7 +41,7 @@ function walkUrls(parsed, callback) {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
if (isImageSetFunc.test(node.value)) {
|
|
44
|
-
node.nodes
|
|
44
|
+
for (const nNode of node.nodes) {
|
|
45
45
|
const {
|
|
46
46
|
type,
|
|
47
47
|
value
|
|
@@ -59,139 +59,93 @@ function walkUrls(parsed, callback) {
|
|
|
59
59
|
if (type === 'string') {
|
|
60
60
|
callback(nNode, value, true, true);
|
|
61
61
|
}
|
|
62
|
-
}
|
|
62
|
+
} // Do not traverse inside `image-set`
|
|
63
63
|
// eslint-disable-next-line consistent-return
|
|
64
64
|
|
|
65
|
+
|
|
65
66
|
return false;
|
|
66
67
|
}
|
|
67
68
|
});
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const urls = [];
|
|
77
|
-
walkUrls(parsed, (node, url, needQuotes, isStringValue) => {
|
|
78
|
-
if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
|
|
79
|
-
result.warn(`Unable to find uri in '${decl ? decl.toString() : value}'`, {
|
|
80
|
-
node: decl
|
|
81
|
-
});
|
|
82
|
-
return;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
if (filter && !filter(url)) {
|
|
71
|
+
var _default = _postcss.default.plugin(pluginName, options => (css, result) => {
|
|
72
|
+
const importsMap = new Map();
|
|
73
|
+
const replacementsMap = new Map();
|
|
74
|
+
let hasHelper = false;
|
|
75
|
+
css.walkDecls(decl => {
|
|
76
|
+
if (!needParseDecl.test(decl.value)) {
|
|
86
77
|
return;
|
|
87
78
|
}
|
|
88
79
|
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
});
|
|
99
|
-
}); // eslint-disable-next-line consistent-return
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
parsed,
|
|
103
|
-
urls
|
|
104
|
-
};
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function walkDecls(css, result, filter) {
|
|
108
|
-
const items = [];
|
|
109
|
-
css.walkDecls(decl => {
|
|
110
|
-
const item = getUrlsFromValue(decl.value, result, filter, decl);
|
|
80
|
+
const parsed = (0, _postcssValueParser.default)(decl.value);
|
|
81
|
+
walkUrls(parsed, (node, url, needQuotes, isStringValue) => {
|
|
82
|
+
// https://www.w3.org/TR/css-syntax-3/#typedef-url-token
|
|
83
|
+
if (url.replace(/^[\s]+|[\s]+$/g, '').length === 0) {
|
|
84
|
+
result.warn(`Unable to find uri in '${decl ? decl.toString() : decl.value}'`, {
|
|
85
|
+
node: decl
|
|
86
|
+
});
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
111
89
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
90
|
+
if (options.filter && !options.filter(url)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
115
93
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
94
|
+
const splittedUrl = url.split(/(\?)?#/);
|
|
95
|
+
const [urlWithoutHash, singleQuery, hashValue] = splittedUrl;
|
|
96
|
+
const hash = singleQuery || hashValue ? `${singleQuery ? '?' : ''}${hashValue ? `#${hashValue}` : ''}` : '';
|
|
97
|
+
const normalizedUrl = (0, _utils.normalizeUrl)(urlWithoutHash, isStringValue);
|
|
98
|
+
const importKey = normalizedUrl;
|
|
99
|
+
let importName = importsMap.get(importKey);
|
|
100
|
+
|
|
101
|
+
if (!importName) {
|
|
102
|
+
importName = `___CSS_LOADER_URL_IMPORT_${importsMap.size}___`;
|
|
103
|
+
importsMap.set(importKey, importName);
|
|
104
|
+
|
|
105
|
+
if (!hasHelper) {
|
|
106
|
+
const urlToHelper = require.resolve('../runtime/getUrl.js');
|
|
107
|
+
|
|
108
|
+
result.messages.push({
|
|
109
|
+
pluginName,
|
|
110
|
+
type: 'import',
|
|
111
|
+
value: {
|
|
112
|
+
importName: '___CSS_LOADER_GET_URL_IMPORT___',
|
|
113
|
+
url: options.urlHandler ? options.urlHandler(urlToHelper) : urlToHelper
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
hasHelper = true;
|
|
117
|
+
}
|
|
124
118
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
119
|
+
result.messages.push({
|
|
120
|
+
pluginName,
|
|
121
|
+
type: 'import',
|
|
122
|
+
value: {
|
|
123
|
+
importName,
|
|
124
|
+
url: options.urlHandler ? options.urlHandler(normalizedUrl) : normalizedUrl
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
128
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const {
|
|
132
|
-
url,
|
|
133
|
-
needQuotes,
|
|
134
|
-
hash,
|
|
135
|
-
node
|
|
136
|
-
} = currentValue;
|
|
137
|
-
const found = accumulator.find(item => url === item.url && needQuotes === item.needQuotes && hash === item.hash);
|
|
138
|
-
|
|
139
|
-
if (!found) {
|
|
140
|
-
accumulator.push({
|
|
141
|
-
url,
|
|
129
|
+
const replacementKey = JSON.stringify({
|
|
130
|
+
importKey,
|
|
142
131
|
hash,
|
|
143
|
-
needQuotes
|
|
144
|
-
nodes: [node]
|
|
132
|
+
needQuotes
|
|
145
133
|
});
|
|
146
|
-
|
|
147
|
-
found.nodes.push(node);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
return accumulator;
|
|
151
|
-
}, []);
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
var _default = _postcss.default.plugin(pluginName, options => function process(css, result) {
|
|
155
|
-
const traversed = walkDecls(css, result, options.filter);
|
|
156
|
-
const flattenTraversed = flatten(traversed.map(item => item.urls));
|
|
157
|
-
const urlsWithNodes = collectUniqueUrlsWithNodes(flattenTraversed);
|
|
158
|
-
const replacers = new Map();
|
|
159
|
-
urlsWithNodes.forEach((urlWithNodes, index) => {
|
|
160
|
-
const {
|
|
161
|
-
url,
|
|
162
|
-
hash,
|
|
163
|
-
needQuotes,
|
|
164
|
-
nodes
|
|
165
|
-
} = urlWithNodes;
|
|
166
|
-
const replacementName = `___CSS_LOADER_URL_REPLACEMENT_${index}___`;
|
|
167
|
-
result.messages.push({
|
|
168
|
-
pluginName,
|
|
169
|
-
type: 'import',
|
|
170
|
-
value: {
|
|
171
|
-
type: 'url',
|
|
172
|
-
replacementName,
|
|
173
|
-
url,
|
|
174
|
-
needQuotes,
|
|
175
|
-
hash
|
|
176
|
-
}
|
|
177
|
-
}, {
|
|
178
|
-
pluginName,
|
|
179
|
-
type: 'replacer',
|
|
180
|
-
value: {
|
|
181
|
-
type: 'url',
|
|
182
|
-
replacementName
|
|
183
|
-
}
|
|
184
|
-
});
|
|
185
|
-
nodes.forEach(node => {
|
|
186
|
-
replacers.set(node, replacementName);
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
traversed.forEach(item => {
|
|
190
|
-
walkUrls(item.parsed, node => {
|
|
191
|
-
const replacementName = replacers.get(node);
|
|
134
|
+
let replacementName = replacementsMap.get(replacementKey);
|
|
192
135
|
|
|
193
136
|
if (!replacementName) {
|
|
194
|
-
|
|
137
|
+
replacementName = `___CSS_LOADER_URL_REPLACEMENT_${replacementsMap.size}___`;
|
|
138
|
+
replacementsMap.set(replacementKey, replacementName);
|
|
139
|
+
result.messages.push({
|
|
140
|
+
pluginName,
|
|
141
|
+
type: 'url-replacement',
|
|
142
|
+
value: {
|
|
143
|
+
replacementName,
|
|
144
|
+
importName,
|
|
145
|
+
hash,
|
|
146
|
+
needQuotes
|
|
147
|
+
}
|
|
148
|
+
});
|
|
195
149
|
} // eslint-disable-next-line no-param-reassign
|
|
196
150
|
|
|
197
151
|
|
|
@@ -200,7 +154,7 @@ var _default = _postcss.default.plugin(pluginName, options => function process(c
|
|
|
200
154
|
node.value = replacementName;
|
|
201
155
|
}); // eslint-disable-next-line no-param-reassign
|
|
202
156
|
|
|
203
|
-
|
|
157
|
+
decl.value = parsed.toString();
|
|
204
158
|
});
|
|
205
159
|
});
|
|
206
160
|
|
package/dist/runtime/api.js
CHANGED
|
@@ -23,14 +23,32 @@ module.exports = function (useSourceMap) {
|
|
|
23
23
|
// eslint-disable-next-line func-names
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
list.i = function (modules, mediaQuery) {
|
|
26
|
+
list.i = function (modules, mediaQuery, dedupe) {
|
|
27
27
|
if (typeof modules === 'string') {
|
|
28
28
|
// eslint-disable-next-line no-param-reassign
|
|
29
29
|
modules = [[null, modules, '']];
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
var alreadyImportedModules = {};
|
|
33
|
+
|
|
34
|
+
if (dedupe) {
|
|
35
|
+
for (var i = 0; i < this.length; i++) {
|
|
36
|
+
// eslint-disable-next-line prefer-destructuring
|
|
37
|
+
var id = this[i][0];
|
|
38
|
+
|
|
39
|
+
if (id != null) {
|
|
40
|
+
alreadyImportedModules[id] = true;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
for (var _i = 0; _i < modules.length; _i++) {
|
|
46
|
+
var item = [].concat(modules[_i]);
|
|
47
|
+
|
|
48
|
+
if (dedupe && alreadyImportedModules[item[0]]) {
|
|
49
|
+
// eslint-disable-next-line no-continue
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
34
52
|
|
|
35
53
|
if (mediaQuery) {
|
|
36
54
|
if (!item[2]) {
|