esbuild-svelte: Invalid source map if using prepreprocessors

Hello,

I use esbuild with this plugin and I have found the following problem if I enable source map generation with css set to false in compileOptions

const esbuild_svelte = require("esbuild-svelte/configurable")({
    compileOptions: { css: false, hydratable: true },
    preprocessor: svelteConfig.preprocess,
}

I think the source of the problem is in your code at configurable/index.js line 44:

                    //if svelte emits css seperately, then store it in a map and import it from the js
                    if (!compileOptions.css && css.code) {
                        let cssPath = args.path.replace(".svelte", ".esbuild-svelte-fake-css").replace(/\\/g, "/");
                        cssCode.set(cssPath, css.code + `/*# sourceMappingURL=${css.map.toUrl()}*/`);
                        contents = `import "${cssPath}";\n` + contents;
                    }

If I remove the \n the source map line is ok:

...
                        contents = `import "${cssPath}";` + contents;
...

I don’t know if this will fix the problem completely. Possibly there is another way in esbuild to inject the css without modifying the contents.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 16 (11 by maintainers)

Commits related to this issue

Most upvoted comments

Currently I use:

const { typescript } = require("svelte-preprocess-esbuild")
const sveltePreprocess = require("svelte-preprocess")
module.exports = { 
    preprocess: [ // importing this to: preprocess attribute (esbuild-svelte) in other file
        typescript({
            sourcemap: true,
        }),
        sveltePreprocess({
            sourceMap: true,
            typescript: false,
            /* scss: {
                includePaths: ["src/theme"],
            }, */
        }),
    ],
}

I can use the current version of esbuild-svelte 0.5.4 without warnings or errors in my test project. I don’t know in which version it fixed my problem because I used an old version of esbuild-svelte in my other project. Now the only problem is still the referenced source in browser is after preprocessing.

See following test project:

Original:

<h1>{title}</h1>

<div use:links>
    <a href="/test1">1</a>
    <a href="/test2">2</a>
    <a href="/test3">3</a>
    <a href="/test4">4</a>
    <Router url="{url}">
        <Route path="/*path" let:params>
            <Content path="/{params.path}" />
        </Route>
    </Router>
</div>

<style lang="less">
    @import "./../css/main.less";
    h1 {
        color: red;
    }

</style>

<script lang="typescript">
    import { Router, Route, links } from "svelte-routing"
    import { scrollToTop } from "svelte-scrollto"
    import { title } from "../config"
    import { location } from "../store"
    import Content from "./Content.svelte"

    export let url = ""
    if (url) {
        // ssr
        let l = url.split("?")
        $location = {
            path: l[0],
            search: l.length > 1 ? l[1] : "",
            categoryPath: l[0].replace(/\/\d{4,99}[^\/]+$/, ""),
            push: false,
            pop: false,
        }
    }

    // scroll to top on new site
    location.subscribe((l) => {
        if (l.push) scrollToTop()
    })

    if (typeof window !== "undefined") console.log("App initialized")

</script>

Console.log says:

App initialized        App.svelte:41

and is referencing in browser to:

<h1>{title}</h1>

<div use:links>
    <a href="/test1">1</a>
    <a href="/test2">2</a>
    <a href="/test3">3</a>
    <a href="/test4">4</a>
    <Router url="{url}">
        <Route path="/*path" let:params>
            <Content path="/{params.path}" />
        </Route>
    </Router>
</div>

<style lang="less">h1 {
  color: red;
}
</style>

<script lang="typescript">import { Router, Route, links } from "svelte-routing";
import { scrollToTop } from "svelte-scrollto";
import { title } from "../config";
import { location } from "../store";
import Content from "./Content.svelte";
let url = "";
if (url) {
  let l = url.split("?");
  $location = {
    path: l[0],
    search: l.length > 1 ? l[1] : "",
    categoryPath: l[0].replace(/\/\d{4,99}[^\/]+$/, ""),
    push: false,
    pop: false
  };
}
location.subscribe((l) => {
  if (l.push)
    scrollToTop();
});
if (typeof window !== "undefined")
  console.log("App initialized");
export {
  url
};
</script>

I tested with the branch preprocessor-sourcemaps and there are the same errors. Not every js.map.sources has 2 items, but most of them.

Here ist my yarn list | egrep "svelte|esbuild" after yarn upgrade:

├─ @tsconfig/svelte@1.0.10
├─ esbuild-svelte@0.4.0
│  └─ svelte@^3.31.0
├─ esbuild@0.8.36
├─ prettier-plugin-svelte@1.4.2
├─ svelte-check@1.1.31
│  ├─ svelte-preprocess@^4.0.0
├─ svelte-hmr@0.11.6
├─ svelte-lazy@1.0.8
├─ svelte-loading-spinners@0.1.4
├─ svelte-material-icons@1.0.3
├─ svelte-materialify@0.3.4
├─ svelte-preprocess-esbuild@1.0.4
├─ svelte-preprocess@4.6.5
├─ svelte-routing@1.5.0
├─ svelte-scrollto@0.2.0
│  └─ svelte@3.x
├─ svelte@3.32.0

Later I will try it with a new project. Now I see no relation between the import statement and the output of one or two items in the js.map.sources array.

I think my current project is too complex for tests. Starting with a new small project hopefully I can discover when the duplication of files happen.