vitest icon indicating copy to clipboard operation
vitest copied to clipboard

Rolldown CI Failures

Open sheremet-va opened this issue 2 months ago • 11 comments

Describe the bug

Rolldown fails on CI for some time. For the longest time it was an issue with source maps, but at one point something else broke too. This PR documents all the known issues.


Upstream issue https://github.com/vitest-dev/vitest/issues/8754#issuecomment-3587848757

https://github.com/vitest-dev/vitest/blob/c4485c6a028951971f77bef93e4dfcb5e89b069e/test/config/fixtures/fs-cached-check/basic.test.ts#L11

Rolldown does not resolve the id /dist/generated.js into a full file path and fails in loadAndTransform function. Looks like, it is stored with an incorrect file property in the module graph (perhaps, during the import analysis?) and then never updated. Note that this works correctly in Vite 7.


https://github.com/vitest-dev/vitest/blob/2827eabd62c2ca8039a98f283c3105f862d9a1ae/test/config/test/failures.test.ts#L361

Looks like SSR transform behaves differently because the coverage has no functions:

functions: { total: 0, covered: 0, skipped: 0, pct: 100 },

The module looks like this:

__vite_ssr_exportName__("uncovered", () => { try { return uncovered } catch {} });
function uncovered(condition) {
  return condition ? 1 : 0;
}

New issues will be added

Reproduction

https://github.com/vitest-dev/vitest

System Info

Any

Used Package Manager

pnpm

Validations

sheremet-va avatar Oct 21 '25 18:10 sheremet-va

https://github.com/vitest-dev/vitest/blob/c4485c6a028951971f77bef93e4dfcb5e89b069e/test/config/fixtures/fs-cached-check/basic.test.ts#L11 Rolldown does not resolve the id /dist/generated.js into a full file path and fails in loadAndTransform function. Looks like, it is stored with an incorrect file property in the module graph (perhaps, during the import analysis?) and then never updated. Note that this works correctly in Vite 7.

oxc-resolver caches the fs access by default; this is essentially a revert of #17807, which causes #17760 (though there was one bug https://github.com/vitejs/rolldown-vite/pull/463). This commit makes the test pass (https://github.com/sapphi-red/vitest/commit/0a8fefd49739cc3dae387c5c4697b6fe91a89d6d). The other approachs I can think of are:

  • add an option to disable the cache
  • add a way to clear the cache so that Vitest can call that before resolving the dynamic import (I guess this is the only place the cache is a problem)

sapphi-red avatar Oct 24 '25 05:10 sapphi-red

https://github.com/vitest-dev/vitest/blob/2827eabd62c2ca8039a98f283c3105f862d9a1ae/test/config/test/failures.test.ts#L361 Looks like SSR transform behaves differently because the coverage has no functions:

functions: { total: 0, covered: 0, skipped: 0, pct: 100 },

The module looks like this:

__vite_ssr_exportName__("uncovered", () => { try { return uncovered } catch {} });
function uncovered(condition) {
  return condition ? 1 : 0;
}

It seems this is coming from the source map difference. Vite has a mapping for the closing } of the function (sourcemap visualizer), but rolldown-vite does not have a mapping for it (sourcemap visualizer). @AriPerkkio Is this mapping needed? or is it possible to handle this on the coverage-v8 side?

sapphi-red avatar Oct 24 '25 06:10 sapphi-red

This commit makes the test pass (sapphi-red@0a8fefd).

I don't think having watch mode be enabled in run is a good idea. The test should also not be touched, if we ask users to way, we can ask them instead to disable the option in the config.

add an option to disable the cache

I think that could work.

add a way to clear the cache so that Vitest can call that before resolving the dynamic import (I guess this is the only place the cache is a problem)

I guess we could reset the cache before any dynamic import, true. Although if there are any other tests running in parallel, the performance impact might be the same as disabling it, unless this use case is common in someone's code base.

sheremet-va avatar Oct 24 '25 10:10 sheremet-va

It seems this is coming from the source map difference. Vite has a mapping for the closing } of the function (sourcemap visualizer), but rolldown-vite does not have a mapping for it (sourcemap visualizer). @AriPerkkio Is this mapping needed? or is it possible to handle this on the coverage-v8 side?

I haven't tested this myself yet, but missing end } should work fine.

https://github.com/AriPerkkio/ast-v8-to-istanbul/blob/adb80ab089073dde2b46b20e2dbfd230cc8efa42/src/location.ts#L87-L91

AriPerkkio avatar Oct 27 '25 11:10 AriPerkkio

It seems this is coming from the source map difference. Vite has a mapping for the closing } of the function (sourcemap visualizer), but rolldown-vite does not have a mapping for it (sourcemap visualizer). @AriPerkkio Is this mapping needed? or is it possible to handle this on the coverage-v8 side?

I haven't tested this myself yet, but missing end } should work fine.

https://github.com/AriPerkkio/ast-v8-to-istanbul/blob/adb80ab089073dde2b46b20e2dbfd230cc8efa42/src/location.ts#L87-L91

It worked when I add the mapping for } manually. So probably there's a bug around that. Perhaps it doesn't work if it's the last mapping?

sapphi-red avatar Oct 27 '25 13:10 sapphi-red

Before debugging V8 coverage it would be good to have basic Istanbul coverage working. For example the test/coverage-test/test/results-snapshot.test.ts is pretty good smoke-test for verifying source maps.

https://evanw.github.io/source-map-visualization/#NjAyNgBfX3ZpdGVfc3NyX2V4cG9ydE5hbWVfXygic3VtIiwgKCkgPT4geyB0cn

 FAIL   istanbul  test/results-snapshot.test.ts > coverage results matches snapshot
Error: Snapshot `coverage results matches snapshot 1` mismatched

- Expected
+ Received

  {
    "<process-cwd>/fixtures/src/even.ts": {
      "branches": "0/0 (100%)",
-     "functions": "1/2 (50%)",
+     "functions": "0/0 (100%)",
      "lines": "1/2 (50%)",
      "statements": "1/2 (50%)",
    },
    "<process-cwd>/fixtures/src/math.ts": {
      "branches": "0/0 (100%)",
-     "functions": "1/4 (25%)",
+     "functions": "0/0 (100%)",
      "lines": "1/4 (25%)",
      "statements": "1/4 (25%)",
    },
    "<process-cwd>/fixtures/src/untested-file.ts": {
-     "branches": "0/4 (0%)",
+     "branches": "0/0 (100%)",
-     "functions": "0/4 (0%)",
+     "functions": "0/0 (100%)",
-     "lines": "0/8 (0%)",
+     "lines": "0/6 (0%)",
-     "statements": "0/8 (0%)",
+     "statements": "0/6 (0%)",
    },
  }

AriPerkkio avatar Nov 10 '25 14:11 AriPerkkio

Oh, I didn't notice that failure. Probably because ecosystem-ci fails with @vitest/test-core and @vitest/test-coverage and after doesn't get run. I'll check that later.

sapphi-red avatar Nov 10 '25 15:11 sapphi-red

@AriPerkkio I've checked what's happening there. It seems @vitest/coverage-instanbul is not returning the expected source map (https://github.com/vitest-dev/vitest/issues/9001). I'm not sure why it worked with Vite though.

sapphi-red avatar Nov 11 '25 09:11 sapphi-red

When I override the internal combined sourcemap with the one returned from instrumenter.lastSourceMap, I get:

 FAIL   istanbul  test/results-snapshot.test.ts > coverage results matches snapshot
Error: Snapshot `coverage results matches snapshot 1` mismatched

- Expected
+ Received

  {
    "<process-cwd>/fixtures/src/even.ts": {
      "branches": "0/0 (100%)",
-     "functions": "1/2 (50%)",
+     "functions": "0/0 (100%)",
      "lines": "1/2 (50%)",
      "statements": "1/2 (50%)",
    },
    "<process-cwd>/fixtures/src/math.ts": {
      "branches": "0/0 (100%)",
-     "functions": "1/4 (25%)",
+     "functions": "0/0 (100%)",
      "lines": "1/4 (25%)",
      "statements": "1/4 (25%)",
    },
-   "<process-cwd>/fixtures/src/untested-file.ts": {
-     "branches": "0/4 (0%)",
-     "functions": "0/4 (0%)",
-     "lines": "0/8 (0%)",
-     "statements": "0/8 (0%)",
-   },
  }

which looks similar to the one happening with v8 coverage.

sapphi-red avatar Nov 11 '25 09:11 sapphi-red

oxc-resolver caches the fs access by default; this is essentially a revert of #17807, which causes #17760 (though there was one bug vitejs/rolldown-vite#463). This commit makes the test pass (sapphi-red@0a8fefd). The other approachs I can think of are:

  • add an option to disable the cache

@sapphi-red for this approach. where would we need to start add option? Is it all the way through oxc-resolver -> rolldown -> rolldown-vite?

hi-ogawa avatar Nov 28 '25 03:11 hi-ogawa

oxc-resolver caches the fs access by default; this is essentially a revert of #17807, which causes #17760 (though there was one bug vitejs/rolldown-vite#463). This commit makes the test pass (sapphi-red@0a8fefd). The other approachs I can think of are:

  • add an option to disable the cache

@sapphi-red for this approach. where would we need to start add option? Is it all the way through oxc-resolver -> rolldown -> rolldown-vite?

I add an option in Rolldown (https://github.com/rolldown/rolldown/pull/6763), and used that in rolldown-vite (https://github.com/vitejs/rolldown-vite/pull/471). But it's blocked by https://github.com/oxc-project/oxc-resolver/issues/872.

sapphi-red avatar Nov 28 '25 04:11 sapphi-red