Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vite 6 compatibility issue resolve.conditions #7070

Open
6 tasks done
thebanjomatic opened this issue Dec 11, 2024 · 10 comments · Fixed by #7071
Open
6 tasks done

Vite 6 compatibility issue resolve.conditions #7070

thebanjomatic opened this issue Dec 11, 2024 · 10 comments · Fixed by #7071
Labels
p2-to-be-discussed Enhancement under consideration (priority) p3-minor-bug An edge case that only affects very specific usage (priority) pending triage

Comments

@thebanjomatic
Copy link
Contributor

thebanjomatic commented Dec 11, 2024

Describe the bug

When using a browser-based evironment (happy-dom, jsdom, browser), vitest still passes conditions: ['node'] in the resolve config.

When using Vite 5, this doesn't really matter because it would infer that we were targetting a web environment and it would resolve in that context anyway. I'm not 100% sure on how this worked before, but tryNodeResolve was being passed a targetWeb boolean and the returned ID will match the browser / default import conditions instead of the node condition.

With Vite 6 a lot of this default environment magic was stripped out as part of the Environments api refactor, and now it's just using the resolve.conditions from the corresponding client/ssr configs. This results in a change in behavior where Vitest now uses the node condition for browser environments when using Vite 6.

Using the node condition instead of browser can result in test failures due to differences in behavior between browser and node implementations of a library, but I've also run into issues where esbuild as part of deps optimization generates invalid code where the module itself is "babel compatible" but tries to deconstruct the named exports from import_mod1.default instead of import_mod1.

These issues reproduce in the latest Vitest 2.1.8 using a resolution for Vite 6.0.3, as well as Vitest 3.0.0-beta.2.

Reproduction

I'm still working on creating a reproducer that I can share and should be able to do so by the end of the day.

In terms of the actual code changes, I think these two locations can be changed to use:

conditions: [testConfig.environment === 'node' ? 'node' : 'browser']

resolve: {
// by default Vite resolves `module` field, which not always a native ESM module
// setting this option can bypass that and fallback to cjs version
mainFields: [],
alias: testConfig.alias,
conditions: ['node'],
},

resolve: {
// by default Vite resolves `module` field, which not always a native ESM module
// setting this option can bypass that and fallback to cjs version
mainFields: [],
alias: testConfig.alias,
conditions: ['node'],
},

But it's also a little unclear to me if we should be clearing out the mainFields: [], for the browser-based environments also.

System Info

System:
    OS: Windows 11 10.0.22631
    CPU: (20) x64 12th Gen Intel(R) Core(TM) i7-12800H
    Memory: 11.40 GB / 31.64 GB
  Binaries:
    Node: 20.18.0 - ~\AppData\Local\fnm_multishells\18680_1733347780000\node.EXE
    Yarn: 4.5.3 - ~\AppData\Local\fnm_multishells\18680_1733347780000\yarn.CMD
    npm: 10.9.1 - D:\source\delete-me\test-vite6\node_modules\.bin\npm.CMD
    bun: 1.1.29 - ~\.bun\bin\bun.EXE
  Browsers:
    Edge: Chromium (127.0.2651.74)
    Internet Explorer: 11.0.22621.3527
  npmPackages:
    vite: ^6.0.0 => 6.0.3

Used Package Manager

yarn

Validations

@sheremet-va
Copy link
Member

There is no compatibility issue here. happy-dom and jsdom tests are running in Node.js with browser globals. There is no widespread decision on how the browser condition should be treated - some libraries expect imports to follow bundlers logic (don't use extensions) which breaks in Vitest when externalized, some just expect globals to be present. Vitest added these conditions for a reason and we are keeping them. The same can be said about the mainFields treatment - since Node.js can't resolve those, it's better to remove them altogether to avoid module hazard if the module is externalized.

When using a browser-based evironment (happy-dom, jsdom, browser)

The browser mode doesn't modify resolve conditions.

@sheremet-va
Copy link
Member

This results in a change in behavior where Vitest now uses the node condition for browser environments when using Vite 6.

I missed this part - we might need to inject default conditions now in the config, but we shouldn't remove the node condition.

@thebanjomatic
Copy link
Contributor Author

thebanjomatic commented Dec 11, 2024

Reproducer:
https://stackblitz.com/edit/vitest-dev-vitest-xzepei6n?file=package.json&view=editor

Vite 6.0.3:
image

Vite 5.4.9:
image

So, it does look like the node conditions were still used in the vite 5 case as that test case fails in both versions, but the tslib error when using optimized deps only reproduces in vite 6 since in vite 5, since the "vite:resolve" plugin was going down a different path (ssr: false implies targetWeb: true) and returning the browser condition instead of node.

This tslib issue is the failure that drove me down this path, and ultimately what is blocking my teams from adopting Vite 6 at this time. If that issue should be filed with the Vite repo instead, let me know.

@sheremet-va
Copy link
Member

Reproducer: stackblitz.com/edit/vitest-dev-vitest-xzepei6n?file=package.json&view=editor

I just want to note that "browser" here is the "happy-dom" environment, not the actual browser, the browser mode in Vitest uses a separate Vite server.

@thebanjomatic
Copy link
Contributor Author

thebanjomatic commented Dec 11, 2024

Yes that's correct. I probably should have been more clear in the naming of the project. I think that's fine and I mainly want things to continue working the same as they do in Vite 5. Since there is no intention of changing away from conditions: ["node"], I have updated the reproducer to reflect that and to instead only focus on the failure case:

https://stackblitz.com/edit/vitest-dev-vitest-xzepei6n?file=package.json

Vite 5:
image

Vite 6:
image

@thebanjomatic
Copy link
Contributor Author

From testing, it looks like adding back in the default conditions for vite >=6 fixes this issue. I'll submit a PR.

thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Dec 11, 2024
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Jan 15, 2025
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
thebanjomatic pushed a commit to thebanjomatic/vitest that referenced this issue Jan 15, 2025
Vite 6 no longer applies default conditions when you override resolve.conditions.
This PR adds them back conditionally based on the vite version.

Fixes vitest-dev#7070
@hi-ogawa
Copy link
Contributor

hi-ogawa commented Jan 17, 2025

Re-opening as PR is reverted #7271


This is reverted since we currently inject these conditions as Node runtime level:

const potentialConditions = new Set([
'production',
'development',
...ctx.vite.config.resolve.conditions,
])
const conditions = [...potentialConditions]
.filter((condition) => {
if (condition === 'production') {
return ctx.vite.config.isProduction
}
if (condition === 'development') {
return !ctx.vite.config.isProduction
}
return true
})
.flatMap(c => ['--conditions', c])

This made Node to pick up module exports from any external dependency (including require(..) calls). This wasn't the case before and it's expected to break many packages.
https://stackblitz.com/edit/vitest-dev-vitest-647kgoep?file=test%2Fbasic.test.ts

test('Basic test', () => {
  console.log("[execArgv]", process.execArgv);
})
DEV  v3.0.0 /home/projects/vitest-dev-vitest-647kgoep

stdout | simple.test.ts > Basic test
[execArgv] [
  '--conditions',
  'development',
  '--conditions',
  'module',
  '--conditions',
  'node',
  '--conditions',
  'development|production'
]

Also this is Vite 2.1.8 + Vite 5 https://stackblitz.com/edit/vitest-dev-vitest-bshsxjxv?file=package.json

 DEV  v2.1.8 /home/projects/vitest-dev-vitest-647kgoep

stdout | test/basic.test.ts > Basic test
[execArgv] [ '--conditions', 'development', '--conditions', 'node' ]

@hi-ogawa hi-ogawa reopened this Jan 17, 2025
@hi-ogawa hi-ogawa added the p2-to-be-discussed Enhancement under consideration (priority) label Jan 17, 2025
@hi-ogawa hi-ogawa moved this to P2 - 2 in Team Board Jan 17, 2025
@hi-ogawa hi-ogawa changed the title Vite 6 compatibility issue Vite 6 compatibility issue resolve.conditions Jan 17, 2025
@hi-ogawa
Copy link
Contributor

In the team meeting, we discussed that excluding module from conditions is considered as a fix to align with Node better. This wasn't previously possible in Vite 5 as Vite implicitly added module condition in Vite's resolveId API, but excluding it became finally possible on Vite 6. Also note that we already excluded module from mainFields for a long time and this is a desired direction.

I haven't checked the repro properly, but if there's an issue with a specific package tslib or optimizeDeps, then it's possible that there is a bug on package side or deps optimization resolution.

@vafanassieff
Copy link

Hey there,

In my monorepo, I used to be able with vite 5 and vitest 2 to use the development condition to not build my packages before running tests.

".": {
  "development": "./src/index.ts",
  "types": "./src/index.ts",
  "import": "./dist/index.js"
}

When using vitest 3.0.1 this is not the case anymore and adding the condition in Vite resolve.conditions or in execArgv does not work.

I think #7271 by fixing the require/import of cjs broked this behavior.

I patched vitest locally to add conditions: ["node", "development"]

Best

@hi-ogawa hi-ogawa added the p3-minor-bug An edge case that only affects very specific usage (priority) label Jan 18, 2025
@silverwind
Copy link
Contributor

silverwind commented Jan 18, 2025

Reproduction in #7277

I wouldn't classify something that breaks all tests as a "minor bug".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
p2-to-be-discussed Enhancement under consideration (priority) p3-minor-bug An edge case that only affects very specific usage (priority) pending triage
Projects
Status: P2 - 2
Development

Successfully merging a pull request may close this issue.

5 participants