Skip to content

Commit 1b29b28

Browse files
authoredMar 23, 2020
refactor: code
1 parent 3bc3a41 commit 1b29b28

File tree

7 files changed

+236
-284
lines changed

7 files changed

+236
-284
lines changed
 

‎src/index.js

+21-10
Original file line numberDiff line numberDiff line change
@@ -87,26 +87,34 @@ export default function loader(content, map, meta) {
8787
: false,
8888
})
8989
.then((result) => {
90-
result
91-
.warnings()
92-
.forEach((warning) => this.emitWarning(new Warning(warning)));
90+
for (const warning of result.warnings()) {
91+
this.emitWarning(new Warning(warning));
92+
}
9393

9494
const imports = [];
95+
const apiImports = [];
96+
const urlReplacements = [];
97+
const icssReplacements = [];
9598
const exports = [];
96-
const replacers = [];
9799

98100
for (const message of result.messages) {
99101
// eslint-disable-next-line default-case
100102
switch (message.type) {
101103
case 'import':
102104
imports.push(message.value);
103105
break;
106+
case 'api-import':
107+
apiImports.push(message.value);
108+
break;
109+
case 'url-replacement':
110+
urlReplacements.push(message.value);
111+
break;
112+
case 'icss-replacement':
113+
icssReplacements.push(message.value);
114+
break;
104115
case 'export':
105116
exports.push(message.value);
106117
break;
107-
case 'replacer':
108-
replacers.push(message.value);
109-
break;
110118
}
111119
}
112120

@@ -118,23 +126,26 @@ export default function loader(content, map, meta) {
118126
this,
119127
imports,
120128
exportType,
121-
sourceMap,
122129
importLoaders,
123130
esModule
124131
);
125132
const moduleCode = getModuleCode(
126133
this,
127134
result,
128135
exportType,
136+
esModule,
129137
sourceMap,
130-
replacers
138+
importLoaders,
139+
apiImports,
140+
urlReplacements,
141+
icssReplacements
131142
);
132143
const exportCode = getExportCode(
133144
this,
134145
exports,
135146
exportType,
136-
replacers,
137147
localsConvention,
148+
icssReplacements,
138149
esModule
139150
);
140151

‎src/plugins/postcss-icss-parser.js

+44-56
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@ import postcss from 'postcss';
22
import { extractICSS, replaceValueSymbols, replaceSymbols } from 'icss-utils';
33
import { urlToRequest } from 'loader-utils';
44

5-
const pluginName = 'postcss-icss-parser';
6-
7-
function normalizeIcssImports(icssImports) {
5+
function makeRequestableIcssImports(icssImports) {
86
return Object.keys(icssImports).reduce((accumulator, url) => {
97
const tokensMap = icssImports[url];
108
const tokens = Object.keys(tokensMap);
@@ -30,60 +28,50 @@ function normalizeIcssImports(icssImports) {
3028
}, {});
3129
}
3230

33-
export default postcss.plugin(
34-
pluginName,
35-
() =>
36-
function process(css, result) {
37-
const importReplacements = Object.create(null);
38-
const { icssImports, icssExports } = extractICSS(css);
39-
const normalizedIcssImports = normalizeIcssImports(icssImports);
40-
41-
Object.keys(normalizedIcssImports).forEach((url, importIndex) => {
42-
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;
43-
44-
result.messages.push({
45-
pluginName,
46-
type: 'import',
47-
value: { type: 'icss-import', importName, url },
48-
});
49-
50-
const tokenMap = normalizedIcssImports[url];
51-
const tokens = Object.keys(tokenMap);
52-
53-
tokens.forEach((token, replacementIndex) => {
54-
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
55-
const localName = tokenMap[token];
56-
57-
importReplacements[token] = replacementName;
58-
59-
result.messages.push({
60-
pluginName,
61-
type: 'replacer',
62-
value: {
63-
type: 'icss-import',
64-
importName,
65-
replacementName,
66-
localName,
67-
},
68-
});
69-
});
70-
});
71-
72-
if (Object.keys(importReplacements).length > 0) {
73-
replaceSymbols(css, importReplacements);
31+
export default postcss.plugin('postcss-icss-parser', () => (css, result) => {
32+
const importReplacements = Object.create(null);
33+
const extractedICSS = extractICSS(css);
34+
const icssImports = makeRequestableIcssImports(extractedICSS.icssImports);
35+
36+
for (const [importIndex, url] of Object.keys(icssImports).entries()) {
37+
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;
38+
39+
result.messages.push(
40+
{
41+
type: 'import',
42+
value: { type: 'icss', importName, url },
43+
},
44+
{
45+
type: 'api-import',
46+
value: { type: 'internal', importName, dedupe: true },
7447
}
48+
);
49+
50+
const tokenMap = icssImports[url];
51+
const tokens = Object.keys(tokenMap);
52+
53+
for (const [replacementIndex, token] of tokens.entries()) {
54+
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
55+
const localName = tokenMap[token];
7556

76-
Object.keys(icssExports).forEach((name) => {
77-
const value = replaceValueSymbols(
78-
icssExports[name],
79-
importReplacements
80-
);
81-
82-
result.messages.push({
83-
pluginName,
84-
type: 'export',
85-
value: { name, value },
86-
});
57+
importReplacements[token] = replacementName;
58+
59+
result.messages.push({
60+
type: 'icss-replacement',
61+
value: { replacementName, importName, localName },
8762
});
8863
}
89-
);
64+
}
65+
66+
if (Object.keys(importReplacements).length > 0) {
67+
replaceSymbols(css, importReplacements);
68+
}
69+
70+
const { icssExports } = extractedICSS;
71+
72+
for (const name of Object.keys(icssExports)) {
73+
const value = replaceValueSymbols(icssExports[name], importReplacements);
74+
75+
result.messages.push({ type: 'export', value: { name, value } });
76+
}
77+
});

‎src/plugins/postcss-import-parser.js

+26-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { normalizeUrl } from '../utils';
77
const pluginName = 'postcss-import-parser';
88

99
export default postcss.plugin(pluginName, (options) => (css, result) => {
10+
const importsMap = new Map();
11+
1012
css.walkAtRules(/^import$/i, (atRule) => {
1113
// Convert only top-level @import
1214
if (atRule.parent.type !== 'root') {
@@ -96,10 +98,32 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
9698

9799
atRule.remove();
98100

101+
if (isRequestable) {
102+
const importKey = url;
103+
let importName = importsMap.get(importKey);
104+
105+
if (!importName) {
106+
importName = `___CSS_LOADER_AT_RULE_IMPORT_${importsMap.size}___`;
107+
importsMap.set(importKey, importName);
108+
109+
result.messages.push({
110+
type: 'import',
111+
value: { type: '@import', importName, url },
112+
});
113+
}
114+
115+
result.messages.push({
116+
type: 'api-import',
117+
value: { type: 'internal', importName, media },
118+
});
119+
120+
return;
121+
}
122+
99123
result.messages.push({
100124
pluginName,
101-
type: 'import',
102-
value: { type: '@import', isRequestable, url, media },
125+
type: 'api-import',
126+
value: { type: 'external', url, media },
103127
});
104128
});
105129
});

‎src/plugins/postcss-url-parser.js

+27-12
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function walkUrls(parsed, callback) {
3232
}
3333

3434
if (isImageSetFunc.test(node.value)) {
35-
node.nodes.forEach((nNode) => {
35+
for (const nNode of node.nodes) {
3636
const { type, value } = nNode;
3737

3838
if (type === 'function' && isUrlFunc.test(value)) {
@@ -50,7 +50,7 @@ function walkUrls(parsed, callback) {
5050
if (type === 'string') {
5151
callback(nNode, value, true, true);
5252
}
53-
});
53+
}
5454

5555
// Do not traverse inside `image-set`
5656
// eslint-disable-next-line consistent-return
@@ -61,7 +61,9 @@ function walkUrls(parsed, callback) {
6161

6262
export default postcss.plugin(pluginName, (options) => (css, result) => {
6363
const importsMap = new Map();
64-
const replacersMap = new Map();
64+
const replacementsMap = new Map();
65+
66+
let hasHelper = false;
6567

6668
css.walkDecls((decl) => {
6769
if (!needParseDecl.test(decl.value)) {
@@ -100,6 +102,20 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
100102
importName = `___CSS_LOADER_URL_IMPORT_${importsMap.size}___`;
101103
importsMap.set(importKey, importName);
102104

105+
if (!hasHelper) {
106+
result.messages.push({
107+
pluginName,
108+
type: 'import',
109+
value: {
110+
type: 'url',
111+
importName: '___CSS_LOADER_GET_URL_IMPORT___',
112+
url: require.resolve('../runtime/getUrl.js'),
113+
},
114+
});
115+
116+
hasHelper = true;
117+
}
118+
103119
result.messages.push({
104120
pluginName,
105121
type: 'import',
@@ -111,25 +127,24 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
111127
});
112128
}
113129

114-
const replacerKey = JSON.stringify({ importKey, hash, needQuotes });
115-
116-
let replacerName = replacersMap.get(replacerKey);
130+
const replacementKey = JSON.stringify({ importKey, hash, needQuotes });
131+
let replacementName = replacementsMap.get(replacementKey);
117132

118-
if (!replacerName) {
119-
replacerName = `___CSS_LOADER_URL_REPLACEMENT_${replacersMap.size}___`;
120-
replacersMap.set(replacerKey, replacerName);
133+
if (!replacementName) {
134+
replacementName = `___CSS_LOADER_URL_REPLACEMENT_${replacementsMap.size}___`;
135+
replacementsMap.set(replacementKey, replacementName);
121136

122137
result.messages.push({
123138
pluginName,
124-
type: 'replacer',
125-
value: { type: 'url', replacerName, importName, hash, needQuotes },
139+
type: 'url-replacement',
140+
value: { replacementName, importName, hash, needQuotes },
126141
});
127142
}
128143

129144
// eslint-disable-next-line no-param-reassign
130145
node.type = 'word';
131146
// eslint-disable-next-line no-param-reassign
132-
node.value = replacerName;
147+
node.value = replacementName;
133148
});
134149

135150
// eslint-disable-next-line no-param-reassign

0 commit comments

Comments
 (0)
Please sign in to comment.