modular-forms
modular-forms copied to clipboard
formAction$ appears not to bundle correctly
Found this issue when trying to integrate drizzle using the following guide.
The problem is when using the database connection within a formAction$ like in the following example
formAction$<LoginForm>(() => {
const sql = postgres("postgresql://postgres:[email protected]:5432/cupon");
const db = drizzle(sql);
}, valiForm$(LoginSchema));
One will get this error (Full log can be found here). It is my understanding from the documentation that formAction$ is executed on the server. Note that executing the same function within a server$, for an example will not lead to any issues. The error will also only occur when building the qwik app.
file: C:/Users/root/Documents/GitHub/cupon-app/node_modules/postgres/src/connection.js:5:9
3: import crypto from 'crypto'
4: import Stream from 'stream'
5: import { performance } from 'perf_hooks'
^
6:
7: import { stringify, handleValue, arrayParser, arraySerializer } from './types.js'
at getRollupError (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/parseAst.js:392:41)
at error (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/parseAst.js:388:42)
at Module.error (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:14844:16)
at Module.traceVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:15291:29)
at ModuleScope.findVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:13192:39)
at FunctionScope.findVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:5221:38)
at FunctionBodyScope.findVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:5221:38)
at FunctionScope.findVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:5221:38)
at FunctionBodyScope.findVariable (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:5221:38)
at MemberExpression.bind (file:///C:/Users/root/Documents/GitHub/cupon-app/node_modules/rollup/dist/es/shared/node-entry.js:6860:49)
A temporary solution I've found is simply using the server$, and passing it as the function for the formAction$, but this will make TypeScript pretty mad.
export const myFunction = server$(async (args: any) => {
const sql = postgres("postgresql://postgres:[email protected]:5432/cupon");
const db = drizzle(sql);
})
// @ts-ignore typescript get very mad 😢
export const useFormAction = formAction$<LoginForm>(myFunction, valiForm$(LoginSchema));
This is a known issue that I plan to address in the coming months. See this issue. As a workaround, I recommend wrapping all of your formAction$ code in isServer:
formAction$<LoginForm>(() => {
if (isServer) {
const sql = postgres("postgresql://postgres:[email protected]:5432/cupon");
const db = drizzle(sql);
}
}, valiForm$(LoginSchema));
After hours of debugging, I found this issue to be the root cause of too much being bundled for the client in my application. Would love to see this solved.
The workaround works. I prefer the early return pattern, though:
formAction$<LoginForm>(() => {
if (isBrowser) return;
// ...
}, valiForm$(LoginSchema));
With this workaround I still get a warning that node:async_hooks has been externalized for browser compatibility. But this does not seem to impact the application.
Hello, here is a repo with simple reproduction: https://github.com/rafalfigura/qwik-bundles-pg-in-client-dist
The method with isServer/isBrowser works as expected but still there is one warning with node:async_hooks like @svi3c pointed
I've also tried to migrate from pg to mysql2 and it still had the same issue.
I am very sorry about this problem. I still plan to submit a PR to Qwik and fix this. I hope to have time to do this by the end of the year.
Thanks for sharing solutions, this worked for me in the meantime:
if (isBrowser) throw new Error('...')
Any progress on this? I stumbled on this issue with prisma.
Here is my minimal reproduction repo:
https://github.com/vsDizzy/qwik-prisma
I believe two things should be changed in docs about Modular Forms integration:
- Modular Forms should be installed as a dev dependency:
-pnpm install @modular-forms/qwik
+pnpm install @modular-forms/qwik -D
- isBrowser should be used to mark server code:
export const useFormAction = formAction$<LoginForm>((values) => {
+ if (isBrowser) throw new Error()
// Runs on server
}, valiForm$(LoginSchema));