-
-
Save mutoo/ad6dd6101535e82a44bcc2a051d7cb22 to your computer and use it in GitHub Desktop.
/** | |
* Why we need the soucemap path fixer? | |
* | |
* 1) postcss-loader + css-loader suck! | |
* https://github.com/postcss/postcss-loader/issues/390#issuecomment-417584816 | |
* | |
* 2) Don't insert absolute paths into the module code as they break hashing when the root for the project is moved. | |
* https://webpack.js.org/contribute/writing-a-loader/#absolute-paths | |
*/ | |
import {getOptions} from 'loader-utils'; | |
import validateOptions from 'schema-utils'; | |
const schema = { | |
type: 'object', | |
properties: { | |
sourceMap: { | |
type: 'boolean', | |
}, | |
}, | |
}; | |
const root = process.cwd().replace(/\\/g, '/'); | |
/** | |
* Fix the source map path | |
* | |
* @param {object} source | |
* @return {string} | |
*/ | |
export default function(source) { | |
// eslint-disable-next-line no-invalid-this | |
const options = getOptions(this); | |
validateOptions(schema, options, 'SourceMap fixer'); | |
// check if source map enabled | |
if (options.sourceMap) { | |
source = fixer(source); | |
} | |
return source; | |
} | |
/** | |
* Source Paths Fixer | |
* | |
* Find and replace the source path in the source data. | |
* The sources could look like following strings: | |
* | |
* "sources":[] | |
* "sources":["/path/to/source-1"] | |
* "sources":["/path/to/source-1","/path/to/source-2"] | |
* "sources":["/path/to/source-1",...,"/path/to/source-n"] | |
* | |
* @param {string} source - the raw data of source | |
* @return {string} | |
*/ | |
export function fixer(source) { | |
return source.replace(/"sources":\[((".+?",?)*)]/g, replacer); | |
} | |
/** | |
* Replace function | |
* | |
* To replace a path in the sources array to a webpack-internal path | |
* | |
* cwd = /path/to/project | |
* "sources":["/path/to/project/src/source-1"] | |
* => "sources":["webpack-internal:///./src/source-1"] | |
* | |
* cwd = C:/path/to/project | |
* "sources":["C:/path/to/project/src/source-2"] | |
* => "sources":["webpack-internal:///./src/source-2"] | |
* | |
* @param {string} $0 the capture 0 equals to whole capture | |
* @param {string} $1 the capture 1 equals the content in the sources array | |
* @return {string} | |
*/ | |
export function replacer($0, $1) { | |
if ($1) { | |
let paths = $1.split(/,\s?/).map((originalPath) => { | |
let path = originalPath.slice(1, | |
originalPath.length - 1); // strip quotes | |
let foundRoot = path.lastIndexOf(root); | |
if (foundRoot > -1) { | |
path = path.slice(foundRoot + root.length); | |
return `"webpack-internal:///.${path}"`; | |
} else { | |
return originalPath; | |
} | |
}).join(','); | |
return `"sources":[${paths}]`; | |
} | |
return $0; | |
} |
Could you please provide a before and after example, so it's easier follow what this loader exactly does ? e.g
before/map.json
{
sources: [
'absolute/path/to/source.ext'
]
}
after/map.json
{
sources: [
// ?
]
}
Also a quick screenshot of e.g the DevTool's panel (like I did here for e.g), basically proofing your solution works and a small repoduction repo would be awesome to have
On UNIX platforms sourcemaps currently seem to work with absolute file paths, but that might be by coincidence since UNIX File Paths and URL's have some similarities in common
hi Michael, I've left before and after example in the jsdoc above the replacer function.
* cwd = /path/to/project
* "sources":["/path/to/project/src/source-1"]
* => "sources":["webpack-internal:///./src/source-1"]
*
* cwd = C:/path/to/project
* "sources":["C:/path/to/project/src/source-2"]
* => "sources":["webpack-internal:///./src/source-2"]
On the windows it can even fixed the malformed path
* cwd = C:/path/to/project
* "sources":[" C:/path/to/project C:/path/to/projectC:/path/to/project/src/source-2"]
* => "sources":["webpack-internal:///./src/source-2"]
macOS
Windows
Also, I created a branch to demonstrate this loader:
https://github.com/mutoo/web-project-boilerplate/tree/sourcemap-path-fixer
after running yarn run dev
, the page will be available at http://localhost:9000/static
hi....how I can use this?
hi....how I can use this? it's a plugin for postcss?
basically, add this loader to your project and then use it as a loader in your rules
ref: https://webpack.js.org/contribute/writing-a-loader/
But as discussed in that thread, I believe this issue had been fixed already:
webpack-contrib/postcss-loader#390 (comment)
P.S. I didn't verify this, yet.
@mutoo thanks
read more discussion
webpack-contrib/postcss-loader#390 (comment)