vitejs / vite

Next generation frontend tooling. It's fast!
http://vitejs.dev
MIT License
67.09k stars 6.03k forks source link

CSS sourcemaps #2830

Open Rich-Harris opened 3 years ago

Rich-Harris commented 3 years ago

Clear and concise description of the problem

CSS sourcemaps aren't currently supported, which can make it difficult to track down where a particular style was authored. It would be cool if they were preserved in both build (<link>) and dev (<style>) mode.

You can see this with a vanilla app (npm init @vitejs/app and choose 'vanilla'), and inspecting the #app styles in both dev and serve. In dev:

image

In serve:

image

Ideally the top right would say 'style.css' in both cases.

Suggested solution

I don't pretend to know exactly what would be involved, but elsewhere in the codebase magic-string is used for a similar purpose. Presumably the relevant plugin is https://github.com/vitejs/vite/blob/main/packages/vite/src/node/plugins/css.ts. I could take a run at it if someone gave me a pointer or two.

dominikg commented 3 years ago

I think I stumbled into this a while back 😔 https://github.com/vitejs/vite/blob/fa8574921195dd03b539c150a2ae5f97121a0aea/packages/vite/src/node/plugins/css.ts#L211

the map could be available from the compileCss result a few lines above

dominikg commented 2 years ago

Spent some time on this recently and here's what i found.

Figuring out how to pass on the sourcemaps is different for dev and build, both coming with their own set of challenges. During dev, css is served from special js modules managing style nodes on the fly. So i think the easiest shot at this would be to add inline sourcemaps to that.

For build it's a lot more difficult as css gets bundled too and sourcemaps have to be updated to reflect that and on top esbuild css minification needs to be accounted for too.

One Idea i had about this is to keep the css sourcemap inline as long as possible to avoid having to change any api where currently only code is passed on, extracting them to .map at the last second if it's configured for external.

Building all of this at once could prove challanging and hard to review, so i suggest to split it into smaller goals, which can be described in more detail separately and implemented on top of each other, for example

1) add inline sourcemap for dev - which seems to be the easiest to implement and most helpful for users 2) add build support for inline sourcemaps 3) extend build support to cover external sourcemap options

and also state which compromises can be made, eg

Would love some more :eyes: on this.

-- links [1] https://github.com/vitejs/vite/issues/649 [2] https://github.com/vitejs/vite/pull/4880 [3] https://github.com/vitejs/vite/pull/4939 [4] https://github.com/vitejs/vite/pull/4951

benmccann commented 2 years ago

I see there's a build.sourcemap option. Should that option be split into two? If there's an issue the in CSS sourcemap handling (which seems potentially likely for the first couple releases after it's added) it'd be nice to potentially be able to disable just it and leave the JS sourcemap support on.

jez9999 commented 2 years ago

Just come across this issue myself. It sure would be useful if Vite could at least bundle sourcemaps during development (on production, perhaps could be lower priority as sourcemaps usually aren't used anyway).

It would actually be better right now if Vite just returned the plain css file and the plain sourcemap file. Some CSS is unlikely to change and doesn't really need to be hot content anyway.

jez9999 commented 1 year ago

I noticed in the docs there is a css.devSourcemap option, but when I enabled it, it didn't seem to change anything. Chrome dev tools still didn't recognize my CSS styling as coming from Bootstrap's .scss files, like it does in React's Webpack dev server output.

rodsotdia commented 1 year ago

@jez9999 I have used the config you mentioned and for me is working well, generating the source maps and see the .scss files corresponding to every styling in dev tools:

css: {
    devSourcemap: true,
},
piotr-cz commented 1 year ago

With css: {devSourcemap: true} the DevTools warning comes away, however mappings do not include paths from within node_modules (clicking on source file name results Could not load content ...)

Here's my take on fixing it in dev mode:

// packages/rollup-plugin-fix-css-sourcemaps/index.mjs

/**
 * Fix css source maps in 3p packages on dev server in vite
 * Css files use relative paths to point to source maps but when running dev server these are inlined
 *
 * @param {string} base
 * @return {RollupPlugin}
 *
 * @example
 * ```js
 * // vite.config.js
 * export default defineConfig(({ command }) => ({
 *   plugins: [
 *     command === 'serve' && fixCssSourcemapsPlugin(),
 *   ],
 * })
 * ```
 */
export default function fixCssSourcemaps(base = '/') {
  const filter = createFilter('node_modules/**/*.css')
  const root = process.cwd()
  const sourceMapRegExp = new RegExp('/\\*# sourceMappingURL=([^\\s]*) \\*/')

  return {
    name: 'rollup-plugin-fix-css-sourcemaps',

    transform(src, id) {
      if (!filter(id) || !sourceMapRegExp.test(src)) {
        return
      }

      // Resolve relative directory from id (ie. /node_modules/@ionic/react/css)
      const relativeDir = base + id.slice(root.length + 1, id.lastIndexOf('/'))

      return {
        code: prependDir(src, relativeDir),
        map: null,
      }
    },
  }

  /**
   * Prepend relative directory to source map pointer
   * @param {string} src
   * @param {string} dir
   * @return {string}
   */
  function prependDir(src, dir) {
    return src.replace(
      sourceMapRegExp,
      `/*# sourceMappingURL=${dir}/$1 */`
    )
  }
}
bmeurer commented 1 year ago

I'm wondering about the status here. I'd like to have better support for Vite in Chrome DevTools, since we have some issues on our end that we can certainly improve upon. One of the interesting questions however is CSS sourcemaps with Svelte and Vue.

Currently with a trivial Svelte hello world, it seems that Vite generates different App.svelte paths in the CSS vs. JS sourcemaps (in the JS case it puts the folder in front, in the CSS case it's just the filename).

Also what's blocking css.devSourcemap from being on by default?

robozb commented 1 year ago

There isn't any effects of this in my case: css: { devSourcemap: true, } Should I see any css map file in the dist folder?

minzdrav commented 1 year ago

Hi Vite Team Please implement css sourcemap for production builds. This is important feature for our web app. We can't finish migration from vue-cli without this feature.

Chameleon2die4 commented 1 year ago

There isn't any effects of this in my case: css: { devSourcemap: true, } Should I see any css map file in the dist folder?

I can't get Vite to generate css.map files either. Is there any progress on this issue?

mahanandyadav commented 1 year ago

@jez9999 I have used the config you mentioned and for me is working well, generating the source maps and see the .scss files corresponding to every styling in dev tools:

css: {
    devSourcemap: true,
},

This worked for me i am using vite4 with react 18

silverwind commented 1 year ago

In case anyone is wondering whether prod source maps work with lightningcss minifier, I can confirm it doesn't work with such a config:

{
  cssMinify: "lightningcss",
  css: {
    lightningcss: {
      sourceMap: true,
    },
  },
}
snake-py commented 1 year ago

So I also come across this today. Since we are using vite I always were wondering why my dev tools stopped properly working. We are using a huge css files. So basically this means I cannot change any style inside the dev tools without breaking the whole application. I am using vite-plugin-ssr (Vike), which luckily injects link tags with my styles. I can fix my dev tools if I remove the vite injected styles, but this solution seems rather hacky and I would like to avoid this. Is there no way to tell vite to inject the parsed css into css files for dev? Wouldn't this also solve the source map issue. I am unsure how vite-plugin-ssr injects the style tags, but maybe it would be worth to look at it? https://github.com/brillout/vite-plugin-ssr/discussions/1003#discussioncomment-6371377

imike57 commented 1 month ago

Any news? I tested vite 5.3.4, and the problem still seems to persist...

Especially since the "sourcemap" property is present and allows generating source maps for JS. There is no reason for CSS to be ignored in this process.

Locally, the sourcemaps are present with the devSourcemap: true option. (It seems strange. In development, source maps should be enabled by default...)

However, in our case, we need these CSS source maps during the build to enable debugging in other usage contexts, not just in local development.

Essential feature..