vite icon indicating copy to clipboard operation
vite copied to clipboard

Support reading pre existing external source maps

Open segevfiner opened this issue 2 years ago • 8 comments

Description

I found myself having to use https://github.com/maxdavidson/rollup-plugin-sourcemaps quite often so that Vite libraries in our monorepo have proper source maps, as Rollup doesn't load external source maps by default. Considering how common this feels to be for me, it might make sense to add this as builtin functionality in Vite, especially since that plugin doesn't seem to be receiving much maintenance and has a few open issues ATM.

Suggested solution

Vite will support reading in and merging external pre existing source maps, so that you are able to debug library code that has source maps.

Alternative

Keep using the plugin, considering to fork it to fix some issues.

Additional context

Basically, imagine a Vite library project and multiple Vite apps that use it and you want to be able to debug the library code with proper source maps in the apps, both during development and in production.

Validations

segevfiner avatar Jan 19 '23 00:01 segevfiner

@segevfiner Do you have a vite.config example how to support external source maps with vite and that rollup plugin?

PSanetra avatar Jun 20 '23 13:06 PSanetra

I need this feature as well as I have a mono-repo with the following structure:

  • apps
    • main-app
  • packages
    • library-a
    • library-b

where main-app depends on library-a which depends on library-b. Without this, when running dev from main-app you can step into library-a but not into library-b, instead you get the minified version in the dist directory.

@segevfiner Do you have a vite.config example how to support external source maps with vite and that rollup plugin?

import { defineConfig } from 'vite';
import sourcemaps from 'rollup-plugin-sourcemaps';

export default defineConfig({
  build: {
    rollupOptions: {
      plugins: [sourcemaps()],
      output: {
        sourcemap: true,
      },
    },
    lib: {
      entry: 'src/index.ts',
      name: 'LibraryA',
      fileName: 'lib-a',
    },
  },
});

mrshannon avatar Jun 23 '23 04:06 mrshannon

It would be really awesome to have this feature added to Vite!

@mrshannon, thanks for sharing your example! It's been super helpful in tackling the issue with external source maps. I made a small tweak to the code by using build.sourcemap instead of rollupOptions.output:

import { defineConfig } from 'vite';
import sourcemaps from 'rollup-plugin-sourcemaps';

export default defineConfig({
  build: {
    rollupOptions: {
      plugins: [sourcemaps()],
    },

    sourcemap: true, // <----------

    lib: {
      entry: 'src/index.ts',
      name: 'LibraryA',
      fileName: 'lib-a',
    },
  },
});

I found out that it works better, at least in my project. Hope that helps you out!

tommyiaco avatar Jul 14 '23 10:07 tommyiaco

Hey there, I wanted to check what the status of this issue is?

We are experiencing the same problem. We split our projtects in 2 parts. First part is, we are building a framework which is then build as library. Second part is that we are building clients based on our framework. When we export our vite client, all sourcemaps for the client code are generated correctly. But the sourcemaps from our framework are missing.

When running the dev server, all sourcemaps seem to work. But when building the application and deploying it on a server, only the client sourcemaps are working and not the framework sourcemaps.

Is there a way to bundle external library sourcemaps somehow? I have tried quite a lot already but it all didn't seem to work.

EDIT Ok. I tried the rollup sourcemaps plugin which seemed to fix the issue. Our framework now also has proper sourcemaps. Would be still great to not rely on a thirdparty plugin to integrate external sourcemaps.

aesau85 avatar Feb 09 '24 09:02 aesau85

I thought that Vite doesn't support sourcemaps via rollup anymore. At least according to this warning message:

Vite does not support "rollupOptions.output.sourcemap". Please use "build.sourcemap" instead.

I'm currently running into a similar issue because vite-plugin-singlefile makes that some of the sourcemaps are not working even with build.sourcemap = 'inline'. Has anyone found another way to workaround this? I'm looking for a similar solution to rollup-plugin-sourcemaps where it transpiles, sourcemaps it, and then build it into a singlefile...

lvn921 avatar Mar 22 '24 23:03 lvn921

Hey there, I wanted to check what the status of this issue is?

We are experiencing the same problem. We split our projtects in 2 parts. First part is, we are building a framework which is then build as library. Second part is that we are building clients based on our framework. When we export our vite client, all sourcemaps for the client code are generated correctly. But the sourcemaps from our framework are missing.

When running the dev server, all sourcemaps seem to work. But when building the application and deploying it on a server, only the client sourcemaps are working and not the framework sourcemaps.

Is there a way to bundle external library sourcemaps somehow? I have tried quite a lot already but it all didn't seem to work.

EDIT Ok. I tried the rollup sourcemaps plugin which seemed to fix the issue. Our framework now also has proper sourcemaps. Would be still great to not rely on a thirdparty plugin to integrate external sourcemaps.

Can you share your vite.config. in my case sourcemaps don't work even for the dev server

life-engineered avatar Sep 17 '24 22:09 life-engineered

There's a few layers to this.

First, vite can create sourcemaps, though it does not read existing sourcemaps from external dependencies. To enable sourcemaps, you have to enable it with the build.sourcemap option.

To enable sourcemaps for code in the primary project, change your vite config to add the build.sourcemap setting:

import {defineConfig} from 'vite';

export default defineConfig({
  build: {
    sourcemap: true,
  },
});

Second, the rollup-plugin-sourcemaps can import sourcemaps from external dependencies and allow vite to export them alongside the bundled assets exports.

This is what this issue was created to request.

To re-export sourcemaps for package dependencies, install the plugin and update your config:

import {defineConfig} from 'vite';
import sourceMaps from 'rollup-plugin-sourcemaps';

export default defineConfig({
  build: {
    sourcemap: true,
    rollupOptions: {
      plugins: [sourceMaps()],
    },
  },
});

Lastly, there are two other settings that will ignore sourcemaps in the chrome devtools if you have enabled the feature. By default, this is anything in node_modules folder so if your dependency is in a monorepo, this should not affect you. For the dev server, this is server.ignoresourcemaps and in production it is build.rollupOptions.output.sourcemapIgnoreList. For more info on how this works, visit the chrome developer docs.

lachieh avatar Sep 18 '24 01:09 lachieh

@lachieh Thanks for your detailed answer, The rollup-plugin-sourcemaps actually did the trick!

aesau85 avatar Sep 24 '24 06:09 aesau85

When using the rollup-plugin-sourcemaps, my vite build --watch only reloads once and then stops detecting changes. Is anybody experiencing similar issues?

demastr avatar Oct 24 '24 09:10 demastr

When using the rollup-plugin-sourcemaps, my vite build --watch only reloads once and then stops detecting changes. Is anybody experiencing similar issues?

Yes, we encountered the same issue. Our solution was to exclude rollup-plugin-sourcemaps when running vite build --watch.

You can check for the --watch flag using the following code: const isWatchMode = process.argv.includes('--watch');

Then, you can conditionally add sourcemaps() to rollupOptions.plugin.

I understand this isn't a perfect solution, but it worked for us. We just run vite build whenever sourcemaps are needed.

tommyiaco avatar Oct 24 '24 12:10 tommyiaco

I want to say great "Thank you!" for all participants of this discussion and leave note about @2wce who keeps rollup-plugin-sourcemaps up to date in his rollup-plugin-sourcemaps2 fork

But I have an issue, as suggested workaround works for dev mode, but not for production. Any suggestions why?

asvishnyakov avatar Dec 23 '24 19:12 asvishnyakov

Unfortunately, after adding the rollup-plugin-sourcemaps2: Image Only some parts of my pre-existing source maps are being preserved after the build. Here's the component's file structure in the dist: Image However, after the build, everything but the nested SideNotes/NoteItem/... is missing: Image

oleksandr-danylchenko avatar Feb 18 '25 16:02 oleksandr-danylchenko

@oleksandr-danylchenko if you are keen can you please create an issue with a minimal reproducible example on the my fork so I can push a fix for you? otherwise i can try to do this based on the above thread but it will probably take longer

2wce avatar Feb 19 '25 15:02 2wce

@2wce, I've been working on creating a clear reproduction example for a few hours already. But, unfortunately, I cannot outline an exact offender that keeps yielding incomplete sourcemaps yet ;(.

oleksandr-danylchenko avatar Feb 19 '25 15:02 oleksandr-danylchenko

Let's imagine the following structure:

  • App 1 (Vite)
    • Dependency 1 (Vite + Lib mode)
      • Dependency 2 (Vite + Lib mode)

@2wce, do I understand correctly that if I want to have the source maps from the transitive Dependency 2 present in the consuming App 1 I need to include the sourcemaps() plugin both into the App 1 AND the Dependency 1?


I made an example repo - https://github.com/oleksandr-danylchenko/vite-annotator-sourcemap-test (App 1). It includes a single dependency - @recogito/text-annotator-js (Dependency 1) with a transitive dep - @annotorious/core (Dependency 2). In the App 1 I initialize the Dep 1 using a few imports:

import { createTextAnnotator, HighlightStyleExpression } from '@recogito/text-annotator';
import '@recogito/text-annotator/dist/text-annotator.css';

Then, even when I run the app with the dev server, I see that the @recogito/text-annotator source maps are present for the files that include at least one JS entry (a variable, function, etc.), but not for the exports-only files. Which is expected I suppose...

`@recogito/text-annotator-js` structure comparison

@recogito/text-annotator-js node_modules/@recogito/text-annotator-js
i i2

However, there's no source map present for the nested @annotorious/core:

`@annotorious/core` in the dev tools

structure


UPD: I found that missing source maps in dev can be caused by the Vite's pre-bundling. If I exclude the packages that I want to see the source maps for - they appear in the dev tools!

UPD2: Unfortunately, excluding deps from the optimization list is still pretty inconsistent and problematic if they have a bunch of non-ESM transitive dependencies. So config may vary significantly from project to project and makes the consumer dependent on the dependency's structure ☠

oleksandr-danylchenko avatar Feb 19 '25 16:02 oleksandr-danylchenko