[Bug?]: Client bundle including imports from "use server" functions
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
Vinxi and Vite are bundling dependencies that are only used in "use server"; functions. For example:
import { Resource } from 'sst';
export function getPublicResources() {
"use server";
return {
apiUrl: Resource.APIRouter.url
} satisfies PublicResources;
}
Vite throws this error during client bundle:
[8:36:13 PM] ERROR ../../node_modules/sst/dist/resource.js (1:9): "env" is not exported by "__vite-browser-external", imported by "../../node_modules/sst/dist/resource.js".
file: .../Code/revelationsai/node_modules/sst/dist/resource.js:1:9
1: import { env } from "node:process";
^
2: const raw = {
3: // @ts-expect-error,
Here is my app.config.ts:
import { defineConfig } from '@solidjs/start/config';
import { searchForWorkspaceRoot } from 'vite';
import { cjsInterop } from 'vite-plugin-cjs-interop';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
middleware: './src/middleware.ts',
server: {
preset: 'aws-lambda'
},
vite: {
plugins: [
tsconfigPaths(),
cjsInterop({
dependencies: ['@clerk/clerk-js']
})
],
server: {
fs: {
allow: [searchForWorkspaceRoot(process.cwd())]
}
}
}
});
Workaround
I can get it to bundle successfully by moving the server function to a separate file and put "use server"; at the top.
Expected behavior 🤔
"use server"; dependencies should only be included in ssr and server bundles
Steps to reproduce 🕹
Steps:
- In app.tsx create a server function that imports a server-only module like node:async_hooks
- Try to build the app
Context 🔦
This is completely blocking my project. I cannot have all my server code sectioned off with my desired design.
Your environment 🌎
No response
So I have narrowed it down to if I use "verbatimModuleSyntax": true that is causing the problem. As soon as I change it to false, my project builds with "use server" imports not being shipped to the client
Reproduction: https://stackblitz.com/edit/github-fk8exj-eru4op?file=src%2Fapp.tsx
verbatimModuleSyntax as explained by esbuild tells esbuild to not drop unused import statements, which is probably causing the server-only imports to not be removed from the ~~client~~ build.
~~I don't think rollup respects verbatimModuleSyntax so this seems to just be a dev-only problem.~~
Happens in build too, nevermind
tldr; use dynamic imports so that build tools can analyze and tree-shake correctly dropping this here to spread awareness
@mdynnl on top of that, if a package/module has side-effects, the bundler can potentially fail to remove the unused import.
We have changed the server-function tree-shaking heuristics with the new plugin. It should be way more aggressive and I'm pretty sure this doesn't happen anymore (we have a few tests as well, feel free to check them and perhaps PR a broken test if you think there's more work around treeshaking that we should do!)