[Bug?]: Module level "use server" is not working anymore
Duplicates
- [x] I have searched the existing issues
Latest version
- [x] I have tested the latest version
Current behavior 😯
When you build a SolidStart app using npm run build, you receive the following warning:
Error when using sourcemap for reporting an error: Can't resolve original location of error.
Module level directives cause errors when bundled, "use server" in "src/hi.ts" was ignored.
Expected behavior 🤔
Either the module-level "use server" should work as it did before SolidStart v1.1.0, or the documentation should be updated:
https://docs.solidjs.com/solid-start/reference/server/use-server#use-server
If
"use server"is inserted as the first line in a file, the entire file will become server-only.
Steps to reproduce 🕹
Steps:
- Run
npm create solidwith the default selections to create a new project. - Create
src/hi.tswith the following content:'use server' export const hi = async () => { console.log('hi!') } - Add the following to
src/app.tsx:import { action } from "@solidjs/router"; import { hi } from "./hi"; const a = action(hi) - Run
npm run buildand observe the output:
Context 🔦
No response
Your environment 🌎
SolidStart v1.1.0
Vinxi v0.5.3
thanks for this issue (and for our chat on discord), @frenzzy
despite the warning, it seems that not using const still works.
@brenelz got a failing test in a PR and now we're digging on the issue.
The issue is still reproduced with @solidjs/[email protected] and @tanstack/[email protected]
FYI @atilafassina
With export function also does not work:
// src/hi.ts
'use server'
export async function hi() {
console.log('hi!')
}
Even tho that warning still shows up the actual code should work as expected
@frenzzy yes. The warning is still there. I added to the release notes that we're still digging on it. It's not exactly straightforward to remove that warning because I believe it's something between the sf-plugin and Vinxi configuration - because of the refactoring we have planned it may take a while before we know this is something that needs extra effort.
As @brenelz said, the code should work as expected. This means that we have some tests to make sure there is no leak of server logic to the client bundle. If you can find a case where it does, please open an issue and feel free to mention all of us - security is top priority. But at the moment I have no reason to consider this as a critical bug because all evidence I have points to it being safe to use in production.
I just upgraded to solidstart 1.1.3 (from 1.0.10) and I started running into this problem:
📦 Compiling client router...
vinxi building router client in client mode
vite v6.0.3 building for production...
src/lib/server.ts (1:0): Error when using sourcemap for reporting an error: Can't resolve original location of error.
src/lib/server.ts (1:0): Module level directives cause errors when bundled, "use server" in "src/lib/server.ts" was ignored.
[plugin:vite:resolve] [plugin vite:resolve] Module "fs" has been externalized for browser compatibility, imported by "/home/seph/src/quill/quill-metal/src/lib/server.ts". See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.
src/lib/db.ts (1:0): Error when using sourcemap for reporting an error: Can't resolve original location of error.
src/lib/db.ts (1:0): Module level directives cause errors when bundled, "use server" in "src/lib/db.ts" was ignored.
".prisma/client/index-browser" is imported by ".prisma/client/index-browser?commonjs-external", but could not be resolved – treating it as an external dependency.
virtual:$vinxi/handler/client (1:97): "default" is not exported by "src/entry-client.tsx", imported by "virtual:$vinxi/handler/client".
It is potentially a security problem - as vinxi is now trying to bundle my server-only code into my browser bundle. For example, I'm using prisma on the backend and the build process is now trying to bundle it for the browser:
I'm not sure why this issue has been closed as fixed. Its clearly not resolved - at least not in 1.1.3.
EDIT: I've forward this to the security email address. Please delete this comment if necessary.
I also encountered this issue with my project after updating to the latest, however I tested some solid-start examples (pnpm create solid) and they work fine. Strange.
EDIT1: bundling the "with-drizzle" project also shows a console warning for the use of "use server" but the build works fine.
EDIT2: I think I managed to isolate the issue to the usage of the router exports "cache", "revalidate", and/or "query", somehow it doesn't work with file(s) where these exports are used especially when using "use server". This used to work with previous versions just fine, but now this combination seems to break the logic somehow.
This is exactly the problem: it seems that functions imported into a "use server" file are no longer under the directive and it throws error in the client. This means that all files that export functions into files under the directive must also use that directive. Adding the directive to all files in the folder seems to solve the problem at least it works, but the yellow warning on build is still there.
I can go with that for now, hope it helps.
Any update on this issue? I reproduced this bug in @solidjs/[email protected] while trying to import a glob of MDX files exclusively server-side and render them into JSX before passing to client. Using query or server functions aren't a workable option here because they require the data passed back to be serializable, and JSX components aren't. So there are certainly cases where this issue does reduce functionality (anything relying on server-side dynamic imports, for example), not just security.
Although, correct me if I'm wrong here and there's another way of doing this properly without module-level "use server".
This still seems like a pretty major security issue too, as while "use server" functions are converted to RPC calls (thus not leaking server code to the client bundle), module-level code is still sent to the client, which can be sensitive. Global constants, containing a database key for example, would get leaked to the client, right?
I can confirm that the bug is still reproducible on @solidjs/[email protected]