Skip to content

Commit fb5c53d

Browse files
fix: source maps generation (#1169)
1 parent 8353353 commit fb5c53d

10 files changed

+1229
-686
lines changed

package-lock.json

+872-583
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"cssesc": "^3.0.0",
4848
"icss-utils": "^4.1.1",
4949
"loader-utils": "^2.0.0",
50-
"normalize-path": "^3.0.0",
5150
"postcss": "^7.0.32",
5251
"postcss-modules-extract-imports": "^2.0.0",
5352
"postcss-modules-local-by-default": "^3.0.3",
@@ -76,6 +75,7 @@
7675
"file-loader": "^6.0.0",
7776
"husky": "^4.2.5",
7877
"jest": "^26.1.0",
78+
"less-loader": "^6.2.0",
7979
"lint-staged": "^10.2.11",
8080
"memfs": "^3.2.0",
8181
"mini-css-extract-plugin": "^0.9.0",
@@ -88,6 +88,8 @@
8888
"standard-version": "^8.0.2",
8989
"strip-ansi": "^6.0.0",
9090
"style-loader": "^1.2.1",
91+
"stylus": "^0.54.8",
92+
"stylus-loader": "^3.0.2",
9193
"url-loader": "^4.1.0",
9294
"webpack": "^4.44.0"
9395
},

src/index.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -151,16 +151,17 @@ export default async function loader(content, map, meta) {
151151
}
152152
}
153153

154+
const { resourcePath } = this;
155+
154156
let result;
155157

156158
try {
157159
result = await postcss(plugins).process(content, {
158-
from: this.resourcePath,
159-
to: this.resourcePath,
160+
from: resourcePath,
161+
to: resourcePath,
160162
map: options.sourceMap
161163
? {
162-
// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
163-
prev: map ? normalizeSourceMap(map) : null,
164+
prev: map ? normalizeSourceMap(map, resourcePath) : null,
164165
inline: false,
165166
annotation: false,
166167
}
@@ -198,7 +199,7 @@ export default async function loader(content, map, meta) {
198199
}
199200

200201
const importCode = getImportCode(imports, options);
201-
const moduleCode = getModuleCode(result, api, replacements, options);
202+
const moduleCode = getModuleCode(result, api, replacements, options, this);
202203
const exportCode = getExportCode(exports, replacements, options);
203204

204205
callback(null, `${importCode}${moduleCode}${exportCode}`);

src/utils.js

+62-9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import { fileURLToPath } from 'url';
66
import path from 'path';
77

88
import { urlToRequest, interpolateName } from 'loader-utils';
9-
import normalizePath from 'normalize-path';
109
import cssesc from 'cssesc';
1110
import modulesValues from 'postcss-modules-values';
1211
import localByDefault from 'postcss-modules-local-by-default';
@@ -41,6 +40,10 @@ function unescape(str) {
4140
});
4241
}
4342

43+
function normalizePath(file) {
44+
return path.sep === '\\' ? file.replace(/\\/g, '/') : file;
45+
}
46+
4447
// eslint-disable-next-line no-control-regex
4548
const filenameReservedRegex = /[<>:"/\\|?*]/g;
4649
// eslint-disable-next-line no-control-regex
@@ -295,7 +298,7 @@ function getModulesPlugins(options, loaderContext) {
295298
return plugins;
296299
}
297300

298-
function normalizeSourceMap(map) {
301+
function normalizeSourceMap(map, resourcePath) {
299302
let newMap = map;
300303

301304
// Some loader emit source map as string
@@ -308,15 +311,33 @@ function normalizeSourceMap(map) {
308311
// We should normalize path because previous loaders like `sass-loader` using backslash when generate source map
309312

310313
if (newMap.file) {
311-
newMap.file = normalizePath(newMap.file);
314+
delete newMap.file;
312315
}
313316

317+
const { sourceRoot } = newMap;
318+
314319
if (newMap.sourceRoot) {
315-
newMap.sourceRoot = normalizePath(newMap.sourceRoot);
320+
delete newMap.sourceRoot;
316321
}
317322

318323
if (newMap.sources) {
319-
newMap.sources = newMap.sources.map((source) => normalizePath(source));
324+
newMap.sources = newMap.sources.map((source) => {
325+
if (source.indexOf('<') === 0) {
326+
return source;
327+
}
328+
329+
if (/^\w+:\/\//.test(source)) {
330+
return source;
331+
}
332+
333+
const absoluteSource = !sourceRoot
334+
? source
335+
: path.resolve(sourceRoot, source);
336+
337+
const resourceDirname = path.dirname(resourcePath);
338+
339+
return normalizePath(path.relative(resourceDirname, absoluteSource));
340+
});
320341
}
321342

322343
return newMap;
@@ -370,14 +391,46 @@ function getImportCode(imports, options) {
370391
return code ? `// Imports\n${code}` : '';
371392
}
372393

373-
function getModuleCode(result, api, replacements, options) {
394+
function normalizeSourceMapForRuntime(map, loaderContext) {
395+
const resultMap = map ? map.toJSON() : null;
396+
397+
if (resultMap) {
398+
if (typeof resultMap.file !== 'undefined') {
399+
delete resultMap.file;
400+
}
401+
402+
resultMap.sources = resultMap.sources.map((source) => {
403+
if (source.indexOf('<') === 0) {
404+
return source;
405+
}
406+
407+
if (/^\w+:\/\//.test(source)) {
408+
return source;
409+
}
410+
411+
const resourceDirname = path.dirname(loaderContext.resourcePath);
412+
const absoluteSource = path.resolve(resourceDirname, source);
413+
const contextifyPath = normalizePath(
414+
path.relative(loaderContext.rootContext, absoluteSource)
415+
);
416+
417+
return `webpack:///${contextifyPath}`;
418+
});
419+
}
420+
421+
return JSON.stringify(resultMap);
422+
}
423+
424+
function getModuleCode(result, api, replacements, options, loaderContext) {
374425
if (options.modules.exportOnlyLocals === true) {
375426
return '';
376427
}
377428

378-
const { css, map } = result;
379-
const sourceMapValue = options.sourceMap && map ? `,${map}` : '';
380-
let code = JSON.stringify(css);
429+
const sourceMapValue = options.sourceMap
430+
? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}`
431+
: '';
432+
433+
let code = JSON.stringify(result.css);
381434
let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap});\n`;
382435

383436
for (const item of api) {

0 commit comments

Comments
 (0)