forked from webpack-contrib/css-loader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpostcss-icss-parser.js
124 lines (97 loc) · 3.4 KB
/
postcss-icss-parser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import { extractICSS, replaceValueSymbols, replaceSymbols } from "icss-utils";
import { normalizeUrl, resolveRequests, requestify } from "../utils";
const plugin = (options = {}) => {
return {
postcssPlugin: "postcss-icss-parser",
async OnceExit(root) {
const importReplacements = Object.create(null);
const { icssImports, icssExports } = extractICSS(root);
const imports = new Map();
const tasks = [];
const { loaderContext } = options;
const resolver = loaderContext.getResolve({
dependencyType: "icss",
conditionNames: ["style"],
extensions: ["..."],
mainFields: ["css", "style", "main", "..."],
mainFiles: ["index", "..."],
preferRelative: true,
});
// eslint-disable-next-line guard-for-in
for (const url in icssImports) {
const tokens = icssImports[url];
if (Object.keys(tokens).length === 0) {
// eslint-disable-next-line no-continue
continue;
}
let normalizedUrl = url;
let prefix = "";
const queryParts = normalizedUrl.split("!");
if (queryParts.length > 1) {
normalizedUrl = queryParts.pop();
prefix = queryParts.join("!");
}
const request = requestify(
normalizeUrl(normalizedUrl, true),
loaderContext.rootContext
);
const doResolve = async () => {
const resolvedUrl = await resolveRequests(
resolver,
loaderContext.context,
[...new Set([normalizedUrl, request])]
);
if (!resolvedUrl) {
return;
}
// eslint-disable-next-line consistent-return
return { url: resolvedUrl, prefix, tokens };
};
tasks.push(doResolve());
}
const results = await Promise.all(tasks);
for (let index = 0; index <= results.length - 1; index++) {
const item = results[index];
if (!item) {
// eslint-disable-next-line no-continue
continue;
}
const newUrl = item.prefix ? `${item.prefix}!${item.url}` : item.url;
const importKey = newUrl;
let importName = imports.get(importKey);
if (!importName) {
importName = `___CSS_LOADER_ICSS_IMPORT_${imports.size}___`;
imports.set(importKey, importName);
options.imports.push({
type: "icss_import",
importName,
url: options.urlHandler(newUrl),
icss: true,
index,
});
options.api.push({ importName, dedupe: true, index });
}
for (const [replacementIndex, token] of Object.keys(
item.tokens
).entries()) {
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${index}_REPLACEMENT_${replacementIndex}___`;
const localName = item.tokens[token];
importReplacements[token] = replacementName;
options.replacements.push({ replacementName, importName, localName });
}
}
if (Object.keys(importReplacements).length > 0) {
replaceSymbols(root, importReplacements);
}
for (const name of Object.keys(icssExports)) {
const value = replaceValueSymbols(
icssExports[name],
importReplacements
);
options.exports.push({ name, value });
}
},
};
};
plugin.postcss = true;
export default plugin;