Skip to content

bundleConfigFile incorrectly resolves source map path under certain conditions #23238

Description

@Wakeful-Cloud

Describe the bug

The path.resolve call inside of the sourcemapPathTransform callback in bundleConfigFile fails to resolve the correct configuration file path under certain circumstances (e.g., VitePress) due to incorrectly treating the last path segment as a directory, rather than a file. This sometimes results in the source map containing an incorrect path to the source file, which breaks debugging functionality in the config, as well as any plugins the config imports.

VitePress Behavior

Below is a screenshot of bundleConfigFile when resolving a VitePress config file:

VitePress debug behavior

Note the double .vitepress in the path, which is incorrect (It should just be /home/wakeful-cloud/Downloads/test/.vitepress/config.mts).

When I decode the base64-encoded source map at the bottom of the compiled config file, I predictably get a sourcemap with an incorrect path:

{
  "version": 3,
  "file": "config.js",
  "names": [],
  "sources": [
    "/home/wakeful-cloud/Downloads/test/.vitepress/.vitepress/config.mts"
  ],
  "sourcesContent": [
    "import { defineConfig } from 'vitepress'\n\n// https://vitepress.dev/reference/site-config\nexport default defineConfig({\n  title: \"My Awesome Project\",\n  description: \"A VitePress Site\",\n  vite: {\n    plugins: [\n      {\n        name: \"test\",\n        configResolved: config => {\n          console.log(\"Vite config resolved:\", config);\n        }\n      }\n    ]\n  },\n  themeConfig: {\n    // https://vitepress.dev/reference/default-theme-config\n    nav: [\n      { text: 'Home', link: '/' },\n      { text: 'Examples', link: '/markdown-examples' }\n    ],\n\n    sidebar: [\n      {\n        text: 'Examples',\n        items: [\n          { text: 'Markdown Examples', link: '/markdown-examples' },\n          { text: 'Runtime API Examples', link: '/api-examples' }\n        ]\n      }\n    ],\n\n    socialLinks: [\n      { icon: 'github', link: 'https://github.com/vuejs/vitepress' }\n    ]\n  }\n})\n"
  ],
  "mappings": ";;AAGA,IAAA,iBAAe,aAAa;CAC1B,OAAO;CACP,aAAa;CACb,MAAM,EACJ,SAAS,CACP;EACE,MAAM;EACN,iBAAgB,WAAU;GACxB,QAAQ,IAAI,yBAAyB,MAAM;EAC7C;CACF,CACF,EACF;CACA,aAAa;EAEX,KAAK,CACH;GAAE,MAAM;GAAQ,MAAM;EAAI,GAC1B;GAAE,MAAM;GAAY,MAAM;EAAqB,CACjD;EAEA,SAAS,CACP;GACE,MAAM;GACN,OAAO,CACL;IAAE,MAAM;IAAqB,MAAM;GAAqB,GACxD;IAAE,MAAM;IAAwB,MAAM;GAAgB,CACxD;EACF,CACF;EAEA,aAAa,CACX;GAAE,MAAM;GAAU,MAAM;EAAqC,CAC/D;CACF;AACF,CAAC"
}

Vanilla Vite Behavior

Interestingly, vanilla (i.e., non-VitePress) Vite does not experience this bug by coincidence. Below is a screenshot of bundleConfigFile when resolving a vanilla Vite config file:

Vanilla Vite debug behavior

This time, when I decode the source map, the path is correct:

{
  "version": 3,
  "file": "vite.config.js",
  "names": [],
  "sources": [
    "/home/wakeful-cloud/Downloads/test2/vite.config.ts"
  ],
  "sourcesContent": [
    "import { defineConfig } from \"vite\";\nimport vue from \"@vitejs/plugin-vue\";\n\n// https://vite.dev/config/\nexport default defineConfig({\n  plugins: [\n    vue(),\n    {\n      name: \"test\",\n      configResolved: (config) => {\n        console.log(\"Vite config resolved:\", config);\n      },\n    },\n  ],\n});\n"
  ],
  "mappings": ";;;AAIA,IAAA,sBAAe,aAAa,EAC1B,SAAS,CACP,IAAI,GACJ;CACE,MAAM;CACN,iBAAiB,WAAW;EAC1B,QAAQ,IAAI,yBAAyB,MAAM;CAC7C;AACF,CACF,EACF,CAAC"
}

And, debugging works as expected.

Workaround

If using VS Code, you can use sourceMapPathOverrides option in the launch config to alias the incorrect path to the correct path.

Reproduction

https://github.com/vuejs/vitepress

Steps to reproduce

Setup a vanilla VitePress project with TypeScript (i.e., npx vitepress init). Then, run VitePress with a debugger. For example, if using VS Code, create a .vscode/launch.json file with the below content:

{
  "version": "0.2.0",
  "configurations": [
    {
      "name": "Run Dev",
      "request": "launch",
      "runtimeArgs": [
        "run-script",
        "docs:dev"
      ],
      "runtimeExecutable": "npm",
      "skipFiles": [
        "<node_internals>/**"
      ],
      "resolveSourceMapLocations": [
        "${workspaceFolder}/node_modules/.vite-temp/**/*.mjs",
      ],
      // Workaround
      // "sourceMapPathOverrides": {
      //   "${workspaceFolder}/.vitepress/*": "${workspaceFolder}/*"
      // },
      "type": "node"
    }
  ],
  "compounds": []
}

and run the Run Dev configuration. None of the breakpoints set in the VitePress config (.vitepress/config.mts), nor any TypeScript file imported by the VitePress config will bind.

System Info

System:
    OS: Linux 7.0 Ubuntu 26.04 LTS 26.04 LTS (Resolute Raccoon)
    CPU: (16) x64 AMD
    Memory: 4.32 GB / 17.88 GB
    Container: Yes
    Shell: 5.3.9 - /bin/bash
  Binaries:
    Node: 24.16.0 - /run/user/1000/fnm_multishells/129123_1786504999833/bin/node
    npm: 11.13.0 - /run/user/1000/fnm_multishells/129123_1786504999833/bin/npm
  npmPackages:
    @vitejs/plugin-vue: ^6.0.8 => 6.0.8 
    vite: ^8.2.0 => 8.2.0 

Used Package Manager

npm

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions