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: server build errors when importing from *.client.ts with re-exports #8427

Closed
jakubmazanec opened this issue Jan 3, 2024 · 5 comments
Closed

Comments

@jakubmazanec
Copy link

Reproduction

Repo with reproduction: https://github.com/jakubmazanec/remix-server-build-bug

  1. Clone
  2. Run npm install
  3. Run npm run build
  4. Build fails.

System Info

System:
    OS: Windows 11 10.0.22621
    CPU: (16) x64 AMD Ryzen 7 5825U with Radeon Graphics
    Memory: 14.49 GB / 31.35 GB
  Binaries:
    Node: 20.8.1 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - ~\AppData\Roaming\npm\yarn.CMD
    npm: 10.1.0 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: Chromium (120.0.2210.91)
    Internet Explorer: 11.0.22621.1
  npmPackages:
    @remix-run/dev: ^2.4.1 => 2.4.1
    @remix-run/node: ^2.4.1 => 2.4.1
    @remix-run/react: ^2.4.1 => 2.4.1
    @remix-run/serve: ^2.4.1 => 2.4.1
    vite: ^5.0.0 => 5.0.10

Used Package Manager

npm

Expected Behavior

Builds without an error.

Actual Behavior

Build fails with error: "foo" is not exported by "app/foo.client.ts", imported by "app/routes/_index.tsx".

If I remove the re-export from app/foo.client.ts and put foo directly into this file

-export * from './stuff/foo';
+export const foo = 'Foo!';

then the build is ok.

@jakubmazanec
Copy link
Author

Related #7972?

@hi-ogawa
Copy link
Contributor

hi-ogawa commented Jan 4, 2024

Thanks for providing a concise repro.

Indeed #7972 is related and fixed by #8200, however re-exports by * are not handled since currently es-module-lexer is used to extract the list of exports to create dummy js file (something like export const foo = {}) for server build, which is not possible for export * from "..." case.

I was somewhat aware of this issue but I haven't explicitly mentioned this since the limitation of es-module-lexer export extraction technique also exists in other place of Remix Vite (for example, I think currently it's not possible to export loader from other file via export * from "./other-file-which-has-loader-export").

I think supporting this use case might be technically difficult, but maybe Remix team has a different idea.

Not sure if this workaround is acceptable for your use case, but es-module-lexer can work out export { ... } from "...", so this might be an easier workaround to employ compared to completely eliminating re-exports. I updated your repro to illustrate this:

https://stackblitz.com/edit/github-lnx7sg?file=app%2Ffoo.client.ts

//// in foo.client.ts
// export * from './stuff/foo';
export { foo } from './stuff/foo';

On a related note, Vite ecosystem in general is against "re-export barrel file" https://vitejs.dev/guide/performance.html#avoid-barrel-files, so maybe it's better to avoid re-exports anyway... (at least for new code)

@jakubmazanec
Copy link
Author

Thank you for the detailed explanation, I'll try the workaround.

@jakubmazanec
Copy link
Author

supporting this use case might be technically difficult

The workaround is enough for me (thanks again for the quick reply), and I don't need Remix to support this particular use case, so I guess this issue can be closed as far I'm concerned. Or maybe these limitations should be mentioned in the documentation.

@pcattori
Copy link
Contributor

Additionally, you can use vite-env-only to mark expressions as client-only with clientOnly$ instead of only relying on .client modules. Though .client modules seem sufficient for most use-cases.

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

4 participants