Skip to content

fix: convert paths to relative for vitePreprocess sourcemap sources #570

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/eight-keys-hug.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@sveltejs/vite-plugin-svelte': patch
---

fix(vitePreprocess): use relative paths in sourcemap sources"
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,9 @@ exports[`raw > Dummy.svelte?raw&svelte&type=all&sourcemap 1`] = `
\\"dependencies\\": [],
\\"map\\": {
\\"version\\": 3,
\\"mappings\\": \\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CCCT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;ADCd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",
\\"mappings\\": \\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CACT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;AACd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",
\\"names\\": [],
\\"sources\\": [
\\"Dummy.svelte\\",
\\"Dummy.svelte\\"
]
}
Expand Down Expand Up @@ -840,7 +839,7 @@ export const dependencies=[]
export const js={\\"code\\":\\"/* src/Dummy.svelte generated by Svelte vXXX */\\\\nimport {\\\\n\\\\tSvelteComponent as SvelteComponent$,\\\\n\\\\tappend as append$,\\\\n\\\\tattr as attr$,\\\\n\\\\tdetach as detach$,\\\\n\\\\telement as element$,\\\\n\\\\tinit as init$,\\\\n\\\\tinsert as insert$,\\\\n\\\\tlisten as listen$,\\\\n\\\\tnoop as noop$,\\\\n\\\\tsafe_not_equal as safe_not_equal$,\\\\n\\\\tset_data as set_data$,\\\\n\\\\ttext as text$\\\\n} from \\\\\\"svelte/internal\\\\\\";\\\\n\\\\nfunction create_fragment(ctx) {\\\\n\\\\tlet button$;\\\\n\\\\tlet t0$;\\\\n\\\\tlet t1$;\\\\n\\\\tlet t2$;\\\\n\\\\tlet mounted;\\\\n\\\\tlet dispose;\\\\n\\\\n\\\\treturn {\\\\n\\\\t\\\\tc() {\\\\n\\\\t\\\\t\\\\tbutton$ = element$(\\\\\\"button\\\\\\");\\\\n\\\\t\\\\t\\\\tt0$ = text$(/*name*/ ctx[0]);\\\\n\\\\t\\\\t\\\\tt1$ = text$(\\\\\\" clicks: \\\\\\");\\\\n\\\\t\\\\t\\\\tt2$ = text$(/*clicks*/ ctx[1]);\\\\n\\\\t\\\\t\\\\tattr$(button$, \\\\\\"class\\\\\\", \\\\\\"svelte-d8vj6a\\\\\\");\\\\n\\\\t\\\\t},\\\\n\\\\t\\\\tm(target, anchor) {\\\\n\\\\t\\\\t\\\\tinsert$(target, button$, anchor);\\\\n\\\\t\\\\t\\\\tappend$(button$, t0$);\\\\n\\\\t\\\\t\\\\tappend$(button$, t1$);\\\\n\\\\t\\\\t\\\\tappend$(button$, t2$);\\\\n\\\\n\\\\t\\\\t\\\\tif (!mounted) {\\\\n\\\\t\\\\t\\\\t\\\\tdispose = listen$(button$, \\\\\\"click\\\\\\", /*click_handler$*/ ctx[2]);\\\\n\\\\t\\\\t\\\\t\\\\tmounted = true;\\\\n\\\\t\\\\t\\\\t}\\\\n\\\\t\\\\t},\\\\n\\\\t\\\\tp(ctx, [dirty]) {\\\\n\\\\t\\\\t\\\\tif (dirty & /*name*/ 1) set_data$(t0$, /*name*/ ctx[0]);\\\\n\\\\t\\\\t\\\\tif (dirty & /*clicks*/ 2) set_data$(t2$, /*clicks*/ ctx[1]);\\\\n\\\\t\\\\t},\\\\n\\\\t\\\\ti: noop$,\\\\n\\\\t\\\\to: noop$,\\\\n\\\\t\\\\td(detaching) {\\\\n\\\\t\\\\t\\\\tif (detaching) detach$(button$);\\\\n\\\\t\\\\t\\\\tmounted = false;\\\\n\\\\t\\\\t\\\\tdispose();\\\\n\\\\t\\\\t}\\\\n\\\\t};\\\\n}\\\\n\\\\nfunction instance$($$self, $$props, $$invalidate) {\\\\n\\\\tlet { name } = $$props;\\\\n\\\\tlet clicks = 0;\\\\n\\\\n\\\\tconst click_handler$ = () => {\\\\n\\\\t\\\\t$$invalidate(1, clicks++, clicks);\\\\n\\\\t};\\\\n\\\\n\\\\t$$self.$$set = $$props => {\\\\n\\\\t\\\\tif ('name' in $$props) $$invalidate(0, name = $$props.name);\\\\n\\\\t};\\\\n\\\\n\\\\treturn [name, clicks, click_handler$];\\\\n}\\\\n\\\\nclass Dummy$ extends SvelteComponent$ {\\\\n\\\\tconstructor(options) {\\\\n\\\\t\\\\tsuper();\\\\n\\\\t\\\\tinit$(this, options, instance$, create_fragment, safe_not_equal$, { name: 0 });\\\\n\\\\t}\\\\n}\\\\n\\\\nexport default Dummy$;\\",\\"map\\":null,\\"dependencies\\":[]}
export const lang=\\"ts\\"
export const normalizedFilename=\\"/src/Dummy.svelte\\"
export const preprocessed={\\"code\\":\\"<script lang=\\\\\\"ts\\\\\\">export let name;\\\\nlet clicks = 0;\\\\n</script>\\\\n\\\\n<button\\\\n\\\\ton:click={() => {\\\\n\\\\t\\\\tclicks++;\\\\n\\\\t}}>{name} clicks: {clicks}</button\\\\n>\\\\n\\\\n<style lang=\\\\\\"scss\\\\\\">button {\\\\n color: #000099;\\\\n}</style>\\\\n\\",\\"dependencies\\":[],\\"map\\":{\\"version\\":3,\\"mappings\\":\\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CCCT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;ADCd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",\\"names\\":[],\\"sources\\":[\\"Dummy.svelte\\",\\"Dummy.svelte\\"]}}
export const preprocessed={\\"code\\":\\"<script lang=\\\\\\"ts\\\\\\">export let name;\\\\nlet clicks = 0;\\\\n</script>\\\\n\\\\n<button\\\\n\\\\ton:click={() => {\\\\n\\\\t\\\\tclicks++;\\\\n\\\\t}}>{name} clicks: {clicks}</button\\\\n>\\\\n\\\\n<style lang=\\\\\\"scss\\\\\\">button {\\\\n color: #000099;\\\\n}</style>\\\\n\\",\\"dependencies\\":[],\\"map\\":{\\"version\\":3,\\"mappings\\":\\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CACT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;AACd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",\\"names\\":[],\\"sources\\":[\\"Dummy.svelte\\"]}}
export const source=\\"<script lang=\\\\\\"ts\\\\\\">\\\\n\\\\texport let name: string;\\\\n\\\\tlet clicks = 0;\\\\n</script>\\\\n\\\\n<button\\\\n\\\\ton:click={() => {\\\\n\\\\t\\\\tclicks++;\\\\n\\\\t}}>{name} clicks: {clicks}</button\\\\n>\\\\n\\\\n<style lang=\\\\\\"scss\\\\\\">\\\\n\\\\t$blue: blue;\\\\n\\\\tbutton {\\\\n\\\\t\\\\tcolor: darken($blue, 20);\\\\n\\\\t}\\\\n</style>\\\\n\\"
export const ssr=false
export const stats={\\"timings\\":{\\"total\\":0.123456789,\\"parse\\":{\\"total\\":0.123456789},\\"create component\\":{\\"total\\":0.123456789}}}
Expand All @@ -852,7 +851,7 @@ export const warnings=[]
exports[`raw > mixed exports > Dummy.svelte?raw&svelte&type=preprocessed 1`] = `
"export const code=\\"<script lang=\\\\\\"ts\\\\\\">export let name;\\\\nlet clicks = 0;\\\\n</script>\\\\n\\\\n<button\\\\n\\\\ton:click={() => {\\\\n\\\\t\\\\tclicks++;\\\\n\\\\t}}>{name} clicks: {clicks}</button\\\\n>\\\\n\\\\n<style lang=\\\\\\"scss\\\\\\">button {\\\\n color: #000099;\\\\n}</style>\\\\n\\"
export const dependencies=[]
export const map={\\"version\\":3,\\"mappings\\":\\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CCCT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;ADCd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",\\"names\\":[],\\"sources\\":[\\"Dummy.svelte\\",\\"Dummy.svelte\\"]}
export const map={\\"version\\":3,\\"mappings\\":\\"AAAA,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CACT,MAAA,CAAA,GAAA,CAAI,IAAA;AACX,GAAA,CAAI,MAAA,CAAA,CAAA,CAAS,CAAA;AACd,CAAC,CAAC,MAAM;;AAER,CAAC;AACD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjB,EAAE,MAAM,CAAC,CAAC;AACV,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;AAC7B;;AAEA,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;;CAKlB,CAAC,CAAC,KAAK;\\",\\"names\\":[],\\"sources\\":[\\"Dummy.svelte\\"]}
export default code
"
`;
Expand Down
24 changes: 13 additions & 11 deletions packages/vite-plugin-svelte/src/preprocess.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import path from 'path';
import { preprocessCSS, resolveConfig, transformWithEsbuild } from 'vite';
import type { ESBuildOptions, InlineConfig, ResolvedConfig } from 'vite';
// eslint-disable-next-line node/no-missing-import
import type { Preprocessor, PreprocessorGroup } from 'svelte/types/compiler/preprocess';
import { mapSourcesToRelative } from './utils/sourcemaps';

const supportedStyleLangs = ['css', 'less', 'sass', 'scss', 'styl', 'stylus', 'postcss', 'sss'];
const supportedScriptLangs = ['ts'];
Expand All @@ -27,7 +27,7 @@ function viteScript(): { script: Preprocessor } {
async script({ attributes, content, filename = '' }) {
const lang = attributes.lang as string;
if (!supportedScriptLangs.includes(lang)) return;
const transformResult = await transformWithEsbuild(content, filename, {
const { code, map } = await transformWithEsbuild(content, filename, {
loader: lang as ESBuildOptions['loader'],
target: 'esnext',
tsconfigRaw: {
Expand All @@ -38,9 +38,12 @@ function viteScript(): { script: Preprocessor } {
}
}
});

mapSourcesToRelative(map, filename);

return {
code: transformResult.code,
map: transformResult.map
code,
map
};
}
};
Expand Down Expand Up @@ -70,14 +73,13 @@ function viteStyle(config: InlineConfig | ResolvedConfig = {}): {
transform = getCssTransformFn(resolvedConfig);
}
const moduleId = `${filename}.${lang}`;
const result = await transform(content, moduleId);
// patch sourcemap source to point back to original filename
if (result.map?.sources?.[0] === moduleId) {
result.map.sources[0] = path.basename(filename);
}
const { code, map } = await transform(content, moduleId);

mapSourcesToRelative(map, moduleId);

return {
code: result.code,
map: result.map ?? undefined
code,
map: map ?? undefined
};
};
// @ts-expect-error tag so can be found by v-p-s
Expand Down
19 changes: 1 addition & 18 deletions packages/vite-plugin-svelte/src/utils/compile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,12 @@ import { StatCollection } from './vite-plugin-svelte-stats';
//eslint-disable-next-line node/no-missing-import
import type { Processed } from 'svelte/types/compiler/preprocess';
import { createInjectScopeEverythingRulePreprocessorGroup } from './preprocess';
import path from 'path';
import { mapSourcesToRelative } from './sourcemaps';

const scriptLangRE = /<script [^>]*lang=["']?([^"' >]+)["']?[^>]*>/;

export type CompileSvelte = ReturnType<typeof _createCompileSvelte>;

function mapSourcesToRelative(map: { sources?: string[] }, filename: string) {
// sourcemap sources are relative to the sourcemap itself
// assume the sourcemap location is the same as filename and turn absolute paths to relative
// to avoid leaking fs information like vite root
if (map?.sources) {
map.sources = map.sources.map((s) => {
if (path.isAbsolute(s)) {
const relative = path.relative(filename, s);
// empty string a source is not allowed, use simple filename
return relative === '' ? path.basename(filename) : relative;
} else {
return s;
}
});
}
}

const _createCompileSvelte = (makeHot: Function) => {
let stats: StatCollection | undefined;
const devStylePreprocessor = createInjectScopeEverythingRulePreprocessorGroup();
Expand Down
20 changes: 20 additions & 0 deletions packages/vite-plugin-svelte/src/utils/sourcemaps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import path from 'path';

/**
* sourcemap sources are relative to the sourcemap itself
* assume the sourcemap location is the same as filename and turn absolute paths to relative
* to avoid leaking fs information like vite root
*/
export function mapSourcesToRelative(map: { sources?: string[] }, filename: string) {
if (map?.sources) {
map.sources = map.sources.map((s) => {
if (path.isAbsolute(s)) {
const relative = path.relative(filename, s);
// empty string as a source is not allowed, use simple filename
return relative === '' ? path.basename(filename) : relative;
} else {
return s;
}
});
}
}