Skip to content

Commit

Permalink
fix: source maps generation (#1169)
Browse files Browse the repository at this point in the history
  • Loading branch information
cap-Bernardito committed Aug 21, 2020
1 parent 8353353 commit fb5c53d
Show file tree
Hide file tree
Showing 10 changed files with 1,229 additions and 686 deletions.
1,455 changes: 872 additions & 583 deletions package-lock.json

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -47,7 +47,6 @@
"cssesc": "^3.0.0",
"icss-utils": "^4.1.1",
"loader-utils": "^2.0.0",
"normalize-path": "^3.0.0",
"postcss": "^7.0.32",
"postcss-modules-extract-imports": "^2.0.0",
"postcss-modules-local-by-default": "^3.0.3",
Expand Down Expand Up @@ -76,6 +75,7 @@
"file-loader": "^6.0.0",
"husky": "^4.2.5",
"jest": "^26.1.0",
"less-loader": "^6.2.0",
"lint-staged": "^10.2.11",
"memfs": "^3.2.0",
"mini-css-extract-plugin": "^0.9.0",
Expand All @@ -88,6 +88,8 @@
"standard-version": "^8.0.2",
"strip-ansi": "^6.0.0",
"style-loader": "^1.2.1",
"stylus": "^0.54.8",
"stylus-loader": "^3.0.2",
"url-loader": "^4.1.0",
"webpack": "^4.44.0"
},
Expand Down
11 changes: 6 additions & 5 deletions src/index.js
Expand Up @@ -151,16 +151,17 @@ export default async function loader(content, map, meta) {
}
}

const { resourcePath } = this;

let result;

try {
result = await postcss(plugins).process(content, {
from: this.resourcePath,
to: this.resourcePath,
from: resourcePath,
to: resourcePath,
map: options.sourceMap
? {
// Some loaders (example `"postcss-loader": "1.x.x"`) always generates source map, we should remove it
prev: map ? normalizeSourceMap(map) : null,
prev: map ? normalizeSourceMap(map, resourcePath) : null,
inline: false,
annotation: false,
}
Expand Down Expand Up @@ -198,7 +199,7 @@ export default async function loader(content, map, meta) {
}

const importCode = getImportCode(imports, options);
const moduleCode = getModuleCode(result, api, replacements, options);
const moduleCode = getModuleCode(result, api, replacements, options, this);
const exportCode = getExportCode(exports, replacements, options);

callback(null, `${importCode}${moduleCode}${exportCode}`);
Expand Down
71 changes: 62 additions & 9 deletions src/utils.js
Expand Up @@ -6,7 +6,6 @@ import { fileURLToPath } from 'url';
import path from 'path';

import { urlToRequest, interpolateName } from 'loader-utils';
import normalizePath from 'normalize-path';
import cssesc from 'cssesc';
import modulesValues from 'postcss-modules-values';
import localByDefault from 'postcss-modules-local-by-default';
Expand Down Expand Up @@ -41,6 +40,10 @@ function unescape(str) {
});
}

function normalizePath(file) {
return path.sep === '\\' ? file.replace(/\\/g, '/') : file;
}

// eslint-disable-next-line no-control-regex
const filenameReservedRegex = /[<>:"/\\|?*]/g;
// eslint-disable-next-line no-control-regex
Expand Down Expand Up @@ -295,7 +298,7 @@ function getModulesPlugins(options, loaderContext) {
return plugins;
}

function normalizeSourceMap(map) {
function normalizeSourceMap(map, resourcePath) {
let newMap = map;

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

if (newMap.file) {
newMap.file = normalizePath(newMap.file);
delete newMap.file;
}

const { sourceRoot } = newMap;

if (newMap.sourceRoot) {
newMap.sourceRoot = normalizePath(newMap.sourceRoot);
delete newMap.sourceRoot;
}

if (newMap.sources) {
newMap.sources = newMap.sources.map((source) => normalizePath(source));
newMap.sources = newMap.sources.map((source) => {
if (source.indexOf('<') === 0) {
return source;
}

if (/^\w+:\/\//.test(source)) {
return source;
}

const absoluteSource = !sourceRoot
? source
: path.resolve(sourceRoot, source);

const resourceDirname = path.dirname(resourcePath);

return normalizePath(path.relative(resourceDirname, absoluteSource));
});
}

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

function getModuleCode(result, api, replacements, options) {
function normalizeSourceMapForRuntime(map, loaderContext) {
const resultMap = map ? map.toJSON() : null;

if (resultMap) {
if (typeof resultMap.file !== 'undefined') {
delete resultMap.file;
}

resultMap.sources = resultMap.sources.map((source) => {
if (source.indexOf('<') === 0) {
return source;
}

if (/^\w+:\/\//.test(source)) {
return source;
}

const resourceDirname = path.dirname(loaderContext.resourcePath);
const absoluteSource = path.resolve(resourceDirname, source);
const contextifyPath = normalizePath(
path.relative(loaderContext.rootContext, absoluteSource)
);

return `webpack:///${contextifyPath}`;
});
}

return JSON.stringify(resultMap);
}

function getModuleCode(result, api, replacements, options, loaderContext) {
if (options.modules.exportOnlyLocals === true) {
return '';
}

const { css, map } = result;
const sourceMapValue = options.sourceMap && map ? `,${map}` : '';
let code = JSON.stringify(css);
const sourceMapValue = options.sourceMap
? `,${normalizeSourceMapForRuntime(result.map, loaderContext)}`
: '';

let code = JSON.stringify(result.css);
let beforeCode = `var ___CSS_LOADER_EXPORT___ = ___CSS_LOADER_API_IMPORT___(${options.sourceMap});\n`;

for (const item of api) {
Expand Down

0 comments on commit fb5c53d

Please sign in to comment.