Skip to content

Commit 255c0f0

Browse files
authoredNov 30, 2018
Refactor code (#826)
* refactor: `loader-utils` * refactor: variable names * refactor: code
1 parent ee409c5 commit 255c0f0

File tree

2 files changed

+113
-132
lines changed

2 files changed

+113
-132
lines changed
 

‎lib/loader.js

+90-83
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,19 @@ const localByDefault = require('postcss-modules-local-by-default');
77
const extractImports = require('postcss-modules-extract-imports');
88
const modulesScope = require('postcss-modules-scope');
99
const modulesValues = require('postcss-modules-values');
10-
const loaderUtils = require('loader-utils');
10+
const {
11+
getOptions,
12+
isUrlRequest,
13+
urlToRequest,
14+
getRemainingRequest,
15+
getCurrentRequest,
16+
stringifyRequest,
17+
} = require('loader-utils');
1118

1219
const { importParser, icssParser, urlParser } = require('./plugins');
1320
const {
1421
getLocalIdent,
1522
getImportPrefix,
16-
placeholderImportItemReplacer,
1723
compileExports,
1824
placholderRegExps,
1925
} = require('./utils');
@@ -22,7 +28,7 @@ const CssSyntaxError = require('./CssSyntaxError');
2228

2329
module.exports = function loader(content, map) {
2430
const callback = this.async();
25-
const options = loaderUtils.getOptions(this) || {};
31+
const options = getOptions(this) || {};
2632
const sourceMap = options.sourceMap || false;
2733

2834
/* eslint-disable no-param-reassign */
@@ -43,40 +49,38 @@ module.exports = function loader(content, map) {
4349
}
4450
/* eslint-enable no-param-reassign */
4551

52+
const parserOptions = {};
53+
const resolveImport = options.import !== false;
54+
const resolveUrl = options.url !== false;
4655
const loaderContext = this;
47-
const localIdentName = options.localIdentName || '[hash:base64]';
48-
const customGetLocalIdent = options.getLocalIdent || getLocalIdent;
49-
50-
const parserOptions = {
51-
url: options.url !== false,
52-
import: options.import !== false,
53-
};
5456

5557
const plugins = [
5658
modulesValues,
5759
localByDefault({
5860
mode: options.modules ? 'local' : 'global',
5961
rewriteUrl(global, url) {
60-
if (parserOptions.url) {
62+
if (resolveUrl) {
6163
// eslint-disable-next-line no-param-reassign
6264
url = url.trim();
6365

64-
if (
65-
!url.replace(/\s/g, '').length ||
66-
!loaderUtils.isUrlRequest(url)
67-
) {
66+
if (!url.replace(/\s/g, '').length || !isUrlRequest(url)) {
6867
return url;
6968
}
69+
7070
if (global) {
71-
return loaderUtils.urlToRequest(url);
71+
return urlToRequest(url);
7272
}
7373
}
74+
7475
return url;
7576
},
7677
}),
7778
extractImports(),
7879
modulesScope({
7980
generateScopedName: function generateScopedName(exportName) {
81+
const localIdentName = options.localIdentName || '[hash:base64]';
82+
const customGetLocalIdent = options.getLocalIdent || getLocalIdent;
83+
8084
return customGetLocalIdent(loaderContext, localIdentName, exportName, {
8185
regExp: options.localIdentRegExp,
8286
hashPrefix: options.hashPrefix || '',
@@ -86,11 +90,11 @@ module.exports = function loader(content, map) {
8690
}),
8791
];
8892

89-
if (options.import !== false) {
93+
if (resolveImport) {
9094
plugins.push(importParser(parserOptions));
9195
}
9296

93-
if (options.url !== false) {
97+
if (resolveUrl) {
9498
plugins.push(urlParser(parserOptions));
9599
}
96100

@@ -99,12 +103,10 @@ module.exports = function loader(content, map) {
99103
postcss(plugins)
100104
.process(content, {
101105
// we need a prefix to avoid path rewriting of PostCSS
102-
from: `/css-loader!${loaderUtils
103-
.getRemainingRequest(this)
106+
from: `/css-loader!${getRemainingRequest(this)
104107
.split('!')
105108
.pop()}`,
106-
to: loaderUtils
107-
.getCurrentRequest(this)
109+
to: getCurrentRequest(this)
108110
.split('!')
109111
.pop(),
110112
map: options.sourceMap
@@ -121,78 +123,83 @@ module.exports = function loader(content, map) {
121123
.warnings()
122124
.forEach((warning) => this.emitWarning(new Warning(warning)));
123125

124-
// for importing CSS
125-
const importUrlPrefix = getImportPrefix(this, options);
126+
const { camelCase, exportOnlyLocals, importLoaders } = options;
127+
const { importItems, urlItems, exports } = parserOptions;
128+
// Run other loader (`postcss-loader`, `sass-loader` and etc) for importing CSS
129+
const importUrlPrefix = getImportPrefix(this, importLoaders);
130+
// Prepare replacer to change from `___CSS_LOADER_IMPORT___INDEX___` to `require('./file.css').locals`
131+
const importItemReplacer = (item) => {
132+
const match = placholderRegExps.importItem.exec(item);
133+
const idx = +match[1];
134+
const importItem = importItems[idx];
135+
const importUrl = importUrlPrefix + importItem.url;
136+
137+
if (exportOnlyLocals) {
138+
return `" + require(${stringifyRequest(
139+
this,
140+
importUrl
141+
)})[${JSON.stringify(importItem.export)}] + "`;
142+
}
126143

127-
let exportJs = compileExports(
128-
parserOptions.exports,
129-
placeholderImportItemReplacer(
144+
return `" + require(${stringifyRequest(
130145
this,
131-
parserOptions.importItems,
132-
importUrlPrefix,
133-
options.exportOnlyLocals
134-
),
135-
options.camelCase
136-
);
146+
importUrl
147+
)}).locals[${JSON.stringify(importItem.export)}] + "`;
148+
};
137149

138-
if (options.exportOnlyLocals) {
139-
if (exportJs) {
140-
exportJs = `module.exports = ${exportJs};`;
141-
}
150+
let exportCode = compileExports(exports, camelCase, (valueAsString) =>
151+
valueAsString.replace(placholderRegExps.importItemG, importItemReplacer)
152+
);
142153

143-
return callback(null, exportJs);
154+
if (exportOnlyLocals) {
155+
return callback(
156+
null,
157+
exportCode ? `module.exports = ${exportCode};` : exportCode
158+
);
144159
}
145160

146-
let cssAsString = JSON.stringify(result.css);
147-
148161
const alreadyImported = {};
149-
const importJs = parserOptions.importItems
162+
const importCode = importItems
150163
.filter((imp) => {
151164
if (!imp.media) {
152165
if (alreadyImported[imp.url]) {
153166
return false;
154167
}
168+
155169
alreadyImported[imp.url] = true;
156170
}
171+
157172
return true;
158173
})
159174
.map((imp) => {
160175
const { url } = imp;
161176
const media = imp.media || '';
162177

163-
if (!loaderUtils.isUrlRequest(url)) {
178+
if (!isUrlRequest(url)) {
164179
return `exports.push([module.id, ${JSON.stringify(
165180
`@import url(${url});`
166181
)}, ${JSON.stringify(media)}]);`;
167182
}
168183

169184
const importUrl = importUrlPrefix + url;
170185

171-
return `exports.i(require(${loaderUtils.stringifyRequest(
186+
return `exports.i(require(${stringifyRequest(
172187
this,
173188
importUrl
174189
)}), ${JSON.stringify(media)});`;
175190
}, this)
176191
.join('\n');
177192

178-
cssAsString = cssAsString.replace(
193+
let cssAsString = JSON.stringify(result.css).replace(
179194
placholderRegExps.importItemG,
180-
placeholderImportItemReplacer(
181-
this,
182-
parserOptions.importItems,
183-
importUrlPrefix
184-
)
195+
importItemReplacer
185196
);
186197

187198
// helper for ensuring valid CSS strings from requires
188-
let urlEscapeHelper = '';
189-
190-
if (
191-
options.url !== false &&
192-
parserOptions.urlItems &&
193-
parserOptions.urlItems.length > 0
194-
) {
195-
urlEscapeHelper = `var escape = require(${loaderUtils.stringifyRequest(
199+
let urlEscapeHelperCode = '';
200+
201+
if (resolveUrl && urlItems && urlItems.length > 0) {
202+
urlEscapeHelperCode = `var escape = require(${stringifyRequest(
196203
this,
197204
require.resolve('./runtime/escape.js')
198205
)});\n`;
@@ -202,7 +209,7 @@ module.exports = function loader(content, map) {
202209
(item) => {
203210
const match = placholderRegExps.urlItem.exec(item);
204211
let idx = +match[1];
205-
const urlItem = parserOptions.urlItems[idx];
212+
const urlItem = urlItems[idx];
206213
const { url } = urlItem;
207214

208215
idx = url.indexOf('?#');
@@ -217,66 +224,66 @@ module.exports = function loader(content, map) {
217224
// idx === 0 is catched by isUrlRequest
218225
// in cases like url('webfont.eot?#iefix')
219226
urlRequest = url.substr(0, idx);
220-
return `" + escape(require(${loaderUtils.stringifyRequest(
227+
return `" + escape(require(${stringifyRequest(
221228
this,
222229
urlRequest
223230
)}) + "${url.substr(idx)}") + "`;
224231
}
225232

226233
urlRequest = url;
227234

228-
return `" + escape(require(${loaderUtils.stringifyRequest(
235+
return `" + escape(require(${stringifyRequest(
229236
this,
230237
urlRequest
231238
)})) + "`;
232239
}
233240
);
234241
}
235242

236-
if (exportJs) {
237-
exportJs = `exports.locals = ${exportJs};`;
243+
if (exportCode) {
244+
exportCode = `exports.locals = ${exportCode};`;
238245
}
239246

240-
let moduleJs;
241-
if (sourceMap && result.map) {
242-
/* eslint-disable no-param-reassign */
247+
let newMap = result.map;
248+
249+
if (sourceMap && newMap) {
243250
// Add a SourceMap
244-
map = result.map.toJSON();
251+
newMap = newMap.toJSON();
245252

246-
if (map.sources) {
247-
map.sources = map.sources.map(
253+
if (newMap.sources) {
254+
newMap.sources = newMap.sources.map(
248255
(source) =>
249256
source
250257
.split('!')
251258
.pop()
252259
.replace(/\\/g, '/'),
253260
this
254261
);
255-
map.sourceRoot = '';
262+
newMap.sourceRoot = '';
256263
}
257264

258-
map.file = map.file
265+
newMap.file = newMap.file
259266
.split('!')
260267
.pop()
261268
.replace(/\\/g, '/');
262-
map = JSON.stringify(map);
263-
/* eslint-enable no-param-reassign */
264-
265-
moduleJs = `exports.push([module.id, ${cssAsString}, "", ${map}]);`;
266-
} else {
267-
moduleJs = `exports.push([module.id, ${cssAsString}, ""]);`;
269+
newMap = JSON.stringify(newMap);
268270
}
269271

272+
const runtimeCode = `exports = module.exports = require(${stringifyRequest(
273+
this,
274+
require.resolve('./runtime/api')
275+
)})(${!!sourceMap});`;
276+
const moduleCode = `exports.push([module.id, ${cssAsString}, ""${
277+
newMap ? `,${newMap}` : ''
278+
}]);`;
279+
270280
// Embed runtime
271281
return callback(
272282
null,
273-
`${urlEscapeHelper}exports = module.exports = require(${loaderUtils.stringifyRequest(
274-
this,
275-
require.resolve('./runtime/api.js')
276-
)})(${sourceMap});\n` +
277-
`// imports\n${importJs}\n\n` +
278-
`// module\n${moduleJs}\n\n` +
279-
`// exports\n${exportJs}`
283+
`${urlEscapeHelperCode}${runtimeCode}\n` +
284+
`// imports\n${importCode}\n\n` +
285+
`// module\n${moduleCode}\n\n` +
286+
`// exports\n${exportCode}`
280287
);
281288
})
282289
.catch((error) => {

0 commit comments

Comments
 (0)