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

ssr.resolve.dedupe not fully resolve all the (cjs) packages #19463

Open
7 tasks done
Jinjiang opened this issue Feb 18, 2025 · 2 comments
Open
7 tasks done

ssr.resolve.dedupe not fully resolve all the (cjs) packages #19463

Jinjiang opened this issue Feb 18, 2025 · 2 comments

Comments

@Jinjiang
Copy link
Contributor

Describe the bug

Some CJS packages won't be deduped in SSR env. Here just provide a minimized reproduction. The actual case happened in a complex project.

Reproduction

https://github.com/Jinjiang/reproductions/tree/try-vite-ssr-20250219

Steps to reproduce

How to reproduce:

pnpm install
pnpm dev

Open http://localhost:3000 in browser.

Expected in both browser console and terminal:

{
  foo: 'foo v1.0.0',
  barCjs: 'bar-cjs v1.0.0, requires foo v1.0.0',
  barEsm: 'bar-esm v1.0.0, requires foo v1.0.0'
}

Actual in terminal:

{
  foo: 'foo v1.0.0',
  barCjs: 'bar-cjs v1.0.0, requires foo v2.0.0',
  barEsm: 'bar-esm v1.0.0, requires foo v1.0.0'
}

System Info

System:
    OS: macOS 15.3.1
    CPU: (8) arm64 Apple M1
    Memory: 88.69 MB / 8.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 20.17.0 - ~/.local/share/mise/installs/node/20/bin/node
    Yarn: 1.22.18 - ~/.yarn/bin/yarn
    npm: 11.0.0 - ~/.local/share/mise/installs/node/20/bin/npm
    pnpm: 9.15.4 - ~/Library/pnpm/pnpm
    bun: 1.1.36 - ~/.local/share/mise/installs/bun/latest/bin/bun
  Browsers:
    Safari: 18.3
  npmPackages:
    @vitejs/plugin-react: ^4.3.4 => 4.3.4 
    vite: ^6.1.0 => 6.1.0

Used Package Manager

pnpm

Logs

Expected in both browser console and terminal:

{
  foo: 'foo v1.0.0',
  barCjs: 'bar-cjs v1.0.0, requires foo v1.0.0',
  barEsm: 'bar-esm v1.0.0, requires foo v1.0.0'
}

Actual in terminal:

{
  foo: 'foo v1.0.0',
  barCjs: 'bar-cjs v1.0.0, requires foo v2.0.0',
  barEsm: 'bar-esm v1.0.0, requires foo v1.0.0'
}

Validations

@hi-ogawa
Copy link
Collaborator

Since bar-cjs is cjs, it needs to be ssr external and require is not intercepted by Vite. require('foo-cjs') is executed by NodeJs and resolve.dedupe cannot influence the resolution. To make it similar to browser, optimizeDeps is needed for ssr like following:

    ssr: {
      optimizeDeps: {
        include: ['foo-cjs', 'bar-cjs'],
      },
      resolve: {
        dedupe: [
          'foo-cjs',
        ],
        noExternal: ['foo-cjs', 'bar-cjs', 'bar-esm'],
      }
    },

@Jinjiang
Copy link
Contributor Author

Thanks for the explanation. And same question to #19461 (comment) it would be great if we can document the detail that CJS packages in SSR should be marked as external.

And another question about alias/dedupe, somehow these 2 options solve the same problem if people want singleton in a certain package like react or react-dom. But why alias is supported only in global config but not per environment like dedupe? Is there any special reason we keep alias global always?

  • Just in case we need a quick server-only hack. The per env alias sometimes really helps.
  • And if people want to dedupe a package to a particular version (like between node_modules/.pnpm/[email protected]/node_modules/react or node_modules/.pnpm/[email protected]/node_modules/react), the current dedupe is not enough and meanwhile I don't know how to do it for SSR via alias since it becomes non-external.

🙏

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

2 participants