Skip to content

Commit 431f620

Browse files
refactor: code (#1059)
1 parent 1b29b28 commit 431f620

15 files changed

+205
-98
lines changed

src/index.js

+12-15
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
MIT License http://www.opensource.org/licenses/mit-license.php
33
Author Tobias Koppers @sokra
44
*/
5-
import { getOptions, isUrlRequest } from 'loader-utils';
5+
import { getOptions, isUrlRequest, stringifyRequest } from 'loader-utils';
66
import postcss from 'postcss';
77
import postcssPkg from 'postcss/package.json';
88
import validateOptions from 'schema-utils';
@@ -13,6 +13,7 @@ import Warning from './Warning';
1313
import schema from './options.json';
1414
import { icssParser, importParser, urlParser } from './plugins';
1515
import {
16+
getPreRequester,
1617
getExportCode,
1718
getFilter,
1819
getImportCode,
@@ -38,13 +39,17 @@ export default function loader(content, map, meta) {
3839
}
3940

4041
const exportType = options.onlyLocals ? 'locals' : 'full';
42+
const preRequester = getPreRequester(this);
43+
const urlHandler = (url) =>
44+
stringifyRequest(this, preRequester(options.importLoaders) + url);
4145

42-
plugins.push(icssParser());
46+
plugins.push(icssParser({ urlHandler }));
4347

4448
if (options.import !== false && exportType === 'full') {
4549
plugins.push(
4650
importParser({
4751
filter: getFilter(options.import, this.resourcePath),
52+
urlHandler,
4853
})
4954
);
5055
}
@@ -55,6 +60,7 @@ export default function loader(content, map, meta) {
5560
filter: getFilter(options.url, this.resourcePath, (value) =>
5661
isUrlRequest(value)
5762
),
63+
urlHandler: (url) => stringifyRequest(this, url),
5864
})
5965
);
6066
}
@@ -118,30 +124,21 @@ export default function loader(content, map, meta) {
118124
}
119125
}
120126

121-
const { importLoaders, localsConvention } = options;
127+
const { localsConvention } = options;
122128
const esModule =
123129
typeof options.esModule !== 'undefined' ? options.esModule : false;
124130

125-
const importCode = getImportCode(
126-
this,
127-
imports,
128-
exportType,
129-
importLoaders,
130-
esModule
131-
);
131+
const importCode = getImportCode(this, exportType, imports, esModule);
132132
const moduleCode = getModuleCode(
133-
this,
134133
result,
135134
exportType,
136-
esModule,
137135
sourceMap,
138-
importLoaders,
139136
apiImports,
140137
urlReplacements,
141-
icssReplacements
138+
icssReplacements,
139+
esModule
142140
);
143141
const exportCode = getExportCode(
144-
this,
145142
exports,
146143
exportType,
147144
localsConvention,

src/options.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
"type": "boolean"
8484
},
8585
{
86-
"type": "number"
86+
"type": "integer"
8787
}
8888
]
8989
},

src/plugins/postcss-icss-parser.js

+46-40
Original file line numberDiff line numberDiff line change
@@ -28,50 +28,56 @@ function makeRequestableIcssImports(icssImports) {
2828
}, {});
2929
}
3030

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 },
31+
export default postcss.plugin(
32+
'postcss-icss-parser',
33+
(options) => (css, result) => {
34+
const importReplacements = Object.create(null);
35+
const extractedICSS = extractICSS(css);
36+
const icssImports = makeRequestableIcssImports(extractedICSS.icssImports);
37+
38+
for (const [importIndex, url] of Object.keys(icssImports).entries()) {
39+
const importName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}___`;
40+
41+
result.messages.push(
42+
{
43+
type: 'import',
44+
value: {
45+
importName,
46+
url: options.urlHandler ? options.urlHandler(url) : url,
47+
},
48+
},
49+
{
50+
type: 'api-import',
51+
value: { type: 'internal', importName, dedupe: true },
52+
}
53+
);
54+
55+
const tokenMap = icssImports[url];
56+
const tokens = Object.keys(tokenMap);
57+
58+
for (const [replacementIndex, token] of tokens.entries()) {
59+
const replacementName = `___CSS_LOADER_ICSS_IMPORT_${importIndex}_REPLACEMENT_${replacementIndex}___`;
60+
const localName = tokenMap[token];
61+
62+
importReplacements[token] = replacementName;
63+
64+
result.messages.push({
65+
type: 'icss-replacement',
66+
value: { replacementName, importName, localName },
67+
});
4768
}
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];
56-
57-
importReplacements[token] = replacementName;
58-
59-
result.messages.push({
60-
type: 'icss-replacement',
61-
value: { replacementName, importName, localName },
62-
});
6369
}
64-
}
6570

66-
if (Object.keys(importReplacements).length > 0) {
67-
replaceSymbols(css, importReplacements);
68-
}
71+
if (Object.keys(importReplacements).length > 0) {
72+
replaceSymbols(css, importReplacements);
73+
}
6974

70-
const { icssExports } = extractedICSS;
75+
const { icssExports } = extractedICSS;
7176

72-
for (const name of Object.keys(icssExports)) {
73-
const value = replaceValueSymbols(icssExports[name], importReplacements);
77+
for (const name of Object.keys(icssExports)) {
78+
const value = replaceValueSymbols(icssExports[name], importReplacements);
7479

75-
result.messages.push({ type: 'export', value: { name, value } });
80+
result.messages.push({ type: 'export', value: { name, value } });
81+
}
7682
}
77-
});
83+
);

src/plugins/postcss-import-parser.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,10 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
108108

109109
result.messages.push({
110110
type: 'import',
111-
value: { type: '@import', importName, url },
111+
value: {
112+
importName,
113+
url: options.urlHandler ? options.urlHandler(url) : url,
114+
},
112115
});
113116
}
114117

src/plugins/postcss-url-parser.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,8 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
7373
const parsed = valueParser(decl.value);
7474

7575
walkUrls(parsed, (node, url, needQuotes, isStringValue) => {
76-
if (url.trim().replace(/\\[\r\n]/g, '').length === 0) {
76+
// https://www.w3.org/TR/css-syntax-3/#typedef-url-token
77+
if (url.replace(/^[\s]+|[\s]+$/g, '').length === 0) {
7778
result.warn(
7879
`Unable to find uri in '${decl ? decl.toString() : decl.value}'`,
7980
{ node: decl }
@@ -103,13 +104,16 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
103104
importsMap.set(importKey, importName);
104105

105106
if (!hasHelper) {
107+
const urlToHelper = require.resolve('../runtime/getUrl.js');
108+
106109
result.messages.push({
107110
pluginName,
108111
type: 'import',
109112
value: {
110-
type: 'url',
111113
importName: '___CSS_LOADER_GET_URL_IMPORT___',
112-
url: require.resolve('../runtime/getUrl.js'),
114+
url: options.urlHandler
115+
? options.urlHandler(urlToHelper)
116+
: urlToHelper,
113117
},
114118
});
115119

@@ -120,9 +124,10 @@ export default postcss.plugin(pluginName, (options) => (css, result) => {
120124
pluginName,
121125
type: 'import',
122126
value: {
123-
type: 'url',
124127
importName,
125-
url: normalizedUrl,
128+
url: options.urlHandler
129+
? options.urlHandler(normalizedUrl)
130+
: normalizedUrl,
126131
},
127132
});
128133
}

src/utils.js

+28-33
Original file line numberDiff line numberDiff line change
@@ -178,30 +178,33 @@ function normalizeSourceMap(map) {
178178
return newMap;
179179
}
180180

181-
function getImportPrefix(loaderContext, importLoaders) {
182-
if (importLoaders === false) {
183-
return '';
184-
}
181+
function getPreRequester({ loaders, loaderIndex }) {
182+
const cache = Object.create(null);
185183

186-
const numberImportedLoaders = parseInt(importLoaders, 10) || 0;
187-
const loadersRequest = loaderContext.loaders
188-
.slice(
189-
loaderContext.loaderIndex,
190-
loaderContext.loaderIndex + 1 + numberImportedLoaders
191-
)
192-
.map((x) => x.request)
193-
.join('!');
184+
return (number) => {
185+
if (cache[number]) {
186+
return cache[number];
187+
}
194188

195-
return `-!${loadersRequest}!`;
189+
if (number === false) {
190+
cache[number] = '';
191+
} else {
192+
const loadersRequest = loaders
193+
.slice(
194+
loaderIndex,
195+
loaderIndex + 1 + (typeof number !== 'number' ? 0 : number)
196+
)
197+
.map((x) => x.request)
198+
.join('!');
199+
200+
cache[number] = `-!${loadersRequest}!`;
201+
}
202+
203+
return cache[number];
204+
};
196205
}
197206

198-
function getImportCode(
199-
loaderContext,
200-
imports,
201-
exportType,
202-
importLoaders,
203-
esModule
204-
) {
207+
function getImportCode(loaderContext, exportType, imports, esModule) {
205208
let code = '';
206209

207210
if (exportType === 'full') {
@@ -217,31 +220,23 @@ function getImportCode(
217220

218221
for (const item of imports) {
219222
const { importName, url } = item;
220-
const importUrl = stringifyRequest(
221-
loaderContext,
222-
item.type !== 'url'
223-
? getImportPrefix(loaderContext, importLoaders) + url
224-
: url
225-
);
226223

227224
code += esModule
228-
? `import ${importName} from ${importUrl};\n`
229-
: `var ${importName} = require(${importUrl});\n`;
225+
? `import ${importName} from ${url};\n`
226+
: `var ${importName} = require(${url});\n`;
230227
}
231228

232229
return code ? `// Imports\n${code}` : '';
233230
}
234231

235232
function getModuleCode(
236-
loaderContext,
237233
result,
238234
exportType,
239-
esModule,
240235
sourceMap,
241-
importLoaders,
242236
apiImports,
243237
urlReplacements,
244-
icssReplacements
238+
icssReplacements,
239+
esModule
245240
) {
246241
if (exportType !== 'full') {
247242
return '';
@@ -306,7 +301,6 @@ function dashesCamelCase(str) {
306301
}
307302

308303
function getExportCode(
309-
loaderContext,
310304
exports,
311305
exportType,
312306
localsConvention,
@@ -393,6 +387,7 @@ export {
393387
getFilter,
394388
getModulesPlugins,
395389
normalizeSourceMap,
390+
getPreRequester,
396391
getImportCode,
397392
getModuleCode,
398393
getExportCode,

0 commit comments

Comments
 (0)