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

Conditional exports can't be active when key is browser #18012

Closed
7 tasks done
NWYLZW opened this issue Sep 3, 2024 · 4 comments
Closed
7 tasks done

Conditional exports can't be active when key is browser #18012

NWYLZW opened this issue Sep 3, 2024 · 4 comments

Comments

@NWYLZW
Copy link

NWYLZW commented Sep 3, 2024

Describe the bug

When I use 'browser' as an optional condition for exporting, I cannot correctly import the module.

Reproduction

https://github.com/NWYLZW/issue-vite-conditional-exports

Steps to reproduce

Run pnpm install followed by pnpm run test

System Info

npx envinfo --system --npmPackages '{vite,@vitejs/*,rollup}' --binaries --browsers

  System:
    OS: macOS 14.1.1
    CPU: (10) arm64 Apple M1 Pro
    Memory: 154.44 MB / 32.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 18.20.4 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.7.0 - /usr/local/bin/npm
    pnpm: 8.12.1 - ~/Library/pnpm/pnpm
  Browsers:
    Safari: 17.1

Used Package Manager

pnpm

Logs

Click to expand!
~/codes/projects/issue-vite-conditional-exports git:[master]
pnpm run test

> issue-vite-conditional-exports@1.0.0 test /Users/yijie/codes/projects/issue-vite-conditional-exports
> vitest


The CJS build of Vite's Node API is deprecated. See https://vitejs.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
[ 'browser' ]

 DEV  v2.0.5 /Users/yijie/codes/projects/issue-vite-conditional-exports

 ❯ tests/index.spec.ts (1)
   ❯ foo (1)
     × should be true

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ Failed Tests 1 ⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯

 FAIL  tests/index.spec.ts > foo > should be true
AssertionError: expected 'foo.node' to be 'foo.browser' // Object.is equality

Expected: "foo.browser"
Received: "foo.node"

 ❯ tests/index.spec.ts:7:15
      5|   it('should be true', () => {
      6|     const f = foo()
      7|     expect(f).toBe('foo.browser')
       |               ^
      8|     expectTypeOf(f).toEqualTypeOf<'foo.browser'>()
      9|     expectTypeOf(f).not.toEqualTypeOf<'foo.node'>()

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/1]⎯

 Test Files  1 failed (1)
      Tests  1 failed (1)
   Start at  18:23:27
   Duration  175ms (transform 20ms, setup 0ms, collect 14ms, tests 5ms, environment 0ms, prepare 38ms)


 FAIL  Tests failed. Watching for file changes...

Validations

@NWYLZW
Copy link
Author

NWYLZW commented Sep 3, 2024

The example for reproduction uses Vitest, but in reality, it is not closely related to Vitest; the main issue lies with vite-node.

const targetWeb = !ssr || ssrTarget === 'webworker'

browser: targetWeb && !additionalConditions.has('node'),

Based on my debugging results, the handling here seems a bit too tightly coupled with SSR. For other users encountering this issue, you can try setting the ssrTarget parameter to 'webworker'. However, I believe this area should take into account that the user has already actively declared the conditional.

@NWYLZW NWYLZW changed the title Conditional exports can't active when key is browser Conditional exports can't be active when key is browser Sep 3, 2024
@hi-ogawa
Copy link
Collaborator

hi-ogawa commented Sep 12, 2024

While I agree Vitest's resolution is confusing at times (other issue I remember is module condition cannot be disabled on Vitest #16631), is it possible that the exports entries should have browser before node for this specific case? something like:

  "exports": {
    "./foo": {
      "browser": "./src/foo.browser.ts",
      "node": "./src/foo.node.ts"
    }
  },

With this, resolve.exports picks up browser instead of node since internally they set up conditions = ["default", "browser", "import", "node"] and it can match browser entry first https://github.com/lukeed/resolve.exports/blob/294192309b7276bc0913f65a7ee73721611ae383/src/utils.ts#L15-L20

Vitest/Vite automatically adding node condition doesn't seem entirely wrong since it's guarded for ssr usage as you pointed out. The behavior is probably similar to how node --conditions browser -e 'import("issue-vite-conditional-exports/foo")' would resolve exports.

@NWYLZW
Copy link
Author

NWYLZW commented Sep 12, 2024

With this, resolve.exports picks up browser instead of node since internally they set up conditions = ["default", "browser", "import", "node"] and it can match browser entry first https://github.com/lukeed/resolve.exports/blob/294192309b7276bc0913f65a7ee73721611ae383/src/utils.ts#L15-L20

I also noticed this point, and it was precisely because of this that I made some modifications to the corresponding browser condition and initiated the related PR.

However, based on the latest code, it seems that the issue here has been exacerbated, as users need a configuration that is used in more places to disable this logic.

@sapphi-red
Copy link
Member

This should be now possible since #18395 (Vite 6.0.0-beta.8+) (at least on the Vite side).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants