Skip to content

Commit 5e1fa89

Browse files
refactor: postcss plugins
1 parent fdcf687 commit 5e1fa89

File tree

11 files changed

+165
-108
lines changed

11 files changed

+165
-108
lines changed

README.md

+16-6
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ url(image.png) => require('./image.png')
121121
url(./image.png) => require('./image.png')
122122
```
123123

124-
To import styles from a `node_modules` path (include `resolve.modules`) and for `alias`, prefix it with a `~`:
124+
To import assets from a `node_modules` path (include `resolve.modules`) and for `alias`, prefix it with a `~`:
125125

126126
```
127127
url(~module/image.png) => require('module/image.png')
@@ -130,14 +130,24 @@ url(~aliasDirectory/image.png) => require('otherDirectory/image.png')
130130

131131
### `import`
132132

133-
To disable `@import` resolving by `css-loader` set the option to `false`.
133+
Enable/disable `@import` resolving. Absolute urls are not resolving.
134+
135+
Examples resolutions:
134136

135-
Absolute urls are not resolving.
137+
```
138+
@import 'style.css' => require('./style.css')
139+
@import url(style.css) => require('./style.css')
140+
@import url('style.css') => require('./style.css')
141+
@import './style.css' => require('./style.css')
142+
@import url(./style.css) => require('./style.css')
143+
@import url('./style.css') => require('./style.css')
144+
```
136145

137-
To import styles from a node module path, prefix it with a `~`:
146+
To import styles from a `node_modules` path (include `resolve.modules`) and for `alias`, prefix it with a `~`:
138147

139-
```css
140-
@import '~module/styles.css';
148+
```
149+
@import url(~module/style.css) => require('module/style.css')
150+
@import url(~aliasDirectory/style.css) => require('otherDirectory/style.css')
141151
```
142152

143153
### [`modules`](https://github.com/css-modules/css-modules)

lib/loader.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ module.exports = function loader(content, map, meta) {
191191
)}, ${JSON.stringify(media)}]);`;
192192
}
193193

194-
const importUrl = importUrlPrefix + url;
194+
const importUrl = importUrlPrefix + urlToRequest(url);
195195

196196
return `exports.i(require(${stringifyRequest(
197197
this,

lib/plugins/postcss-import-parser.js

+59-55
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
const postcss = require('postcss');
22
const valueParser = require('postcss-value-parser');
3-
const loaderUtils = require('loader-utils');
43

54
const pluginName = 'postcss-import-parser';
65

@@ -19,7 +18,7 @@ function getUrl(node) {
1918
return node.value;
2019
}
2120

22-
return '';
21+
return null;
2322
}
2423

2524
function parseImport(params) {
@@ -31,7 +30,7 @@ function parseImport(params) {
3130

3231
const url = getUrl(nodes[0]);
3332

34-
if (url.trim().length === 0) {
33+
if (!url || url.trim().length === 0) {
3534
return null;
3635
}
3736

@@ -44,61 +43,66 @@ function parseImport(params) {
4443
};
4544
}
4645

46+
function walkAtRules(css, result, filter) {
47+
const items = [];
48+
49+
css.walkAtRules(/^import$/i, (atRule) => {
50+
// Convert only top-level @import
51+
if (atRule.parent.type !== 'root') {
52+
return;
53+
}
54+
55+
if (atRule.nodes) {
56+
result.warn(
57+
"It looks like you didn't end your @import statement correctly. " +
58+
'Child nodes are attached to it.',
59+
{ node: atRule }
60+
);
61+
return;
62+
}
63+
64+
const parsed = parseImport(atRule.params);
65+
66+
if (!parsed) {
67+
// eslint-disable-next-line consistent-return
68+
return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
69+
node: atRule,
70+
});
71+
}
72+
73+
if (filter && !filter(parsed)) {
74+
return;
75+
}
76+
77+
atRule.remove();
78+
79+
const { url, media } = parsed;
80+
81+
items.push({ url, media });
82+
});
83+
84+
return items;
85+
}
86+
87+
function uniq(array) {
88+
return array.reduce(
89+
(acc, d) =>
90+
!acc.find((el) => el.url === d.url && el.media === d.media)
91+
? [...acc, d]
92+
: acc,
93+
[]
94+
);
95+
}
96+
4797
module.exports = postcss.plugin(
4898
pluginName,
49-
() =>
99+
(options = {}) =>
50100
function process(css, result) {
51-
css.walkAtRules(/^import$/i, (atRule) => {
52-
// Convert only top-level @import
53-
if (atRule.parent.type !== 'root') {
54-
return;
55-
}
56-
57-
if (atRule.nodes) {
58-
result.warn(
59-
"It looks like you didn't end your @import statement correctly. " +
60-
'Child nodes are attached to it.',
61-
{ node: atRule }
62-
);
63-
return;
64-
}
65-
66-
const parsed = parseImport(atRule.params);
67-
68-
if (!parsed) {
69-
// eslint-disable-next-line consistent-return
70-
return result.warn(`Unable to find uri in '${atRule.toString()}'`, {
71-
node: atRule,
72-
});
73-
}
74-
75-
atRule.remove();
76-
77-
const { media } = parsed;
78-
let { url } = parsed;
79-
const isUrlRequest = loaderUtils.isUrlRequest(url);
80-
81-
if (isUrlRequest) {
82-
url = loaderUtils.urlToRequest(url);
83-
}
84-
85-
const alreadyIncluded = result.messages.find(
86-
(message) =>
87-
message.pluginName === pluginName &&
88-
message.type === 'import' &&
89-
message.item.url === url &&
90-
message.item.media === media
91-
);
92-
93-
if (alreadyIncluded) {
94-
return;
95-
}
96-
97-
result.messages.push({
98-
pluginName,
99-
type: 'import',
100-
item: { url, media },
101-
});
101+
const traversed = walkAtRules(css, result, options.filter);
102+
const paths = uniq(traversed);
103+
104+
paths.forEach((item) => {
105+
result.messages.push({ pluginName, type: 'import', item });
102106
});
103107
}
104108
);

lib/plugins/postcss-url-parser.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function filterUrls(parsed, result, decl, filter) {
3939
return;
4040
}
4141

42-
if (!filter(url)) {
42+
if (filter && !filter(url)) {
4343
return;
4444
}
4545

@@ -96,7 +96,7 @@ function uniq(array) {
9696

9797
module.exports = postcss.plugin(
9898
pluginName,
99-
(options) =>
99+
(options = {}) =>
100100
function process(css, result) {
101101
const traversed = walkDeclsWithUrl(css, result, options.filter);
102102
const paths = uniq(flatten(traversed.map((item) => item.values)));
@@ -121,6 +121,7 @@ module.exports = postcss.plugin(
121121

122122
traversed.forEach((item) => {
123123
mapUrls(item.parsed, (value) => urls[value]);
124+
124125
// eslint-disable-next-line no-param-reassign
125126
item.decl.value = item.parsed.toString();
126127
});

0 commit comments

Comments
 (0)