Closed penberg closed 11 months ago
Not all serverless environments should have a problem with this. Google Cloud Functions (one of the OG serverless products) will indeed run a full npm install
during deployment, runs in a true node environment at runtime, and should load native bits from node_modules.
it would be great to make a completely separate npm package, so I would not need to make forked lib for usage in cloudflare pages (workers) (i've tried vercel edge and netlify edge with same problems) with sveltekit/vite https://github.com/jansuchomel/libsql-client-ts.... the problem is that libsql depends on neon that uses quite a few node specific modules
I'm facing the same issue as jansuchomel.
Also facing the same issue,
web:deploy: > Using @sveltejs/adapter-cloudflare-workers
web:deploy: ✘ [ERROR] Could not resolve "child_process"
web:deploy:
web:deploy: ../../node_modules/detect-libc/lib/detect-libc.js:6:29:
web:deploy: 6 │ const childProcess = require('child_process');
web:deploy: ╵ ~~~~~~~~~~~~~~~
web:deploy:
web:deploy: The package "child_process" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
web:deploy:
web:deploy: ✘ [ERROR] Could not resolve "fs"
web:deploy:
web:deploy: ../../node_modules/detect-libc/lib/filesystem.js:6:19:
web:deploy: 6 │ const fs = require('fs');
web:deploy: ╵ ~~~~
web:deploy:
web:deploy: The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
web:deploy:
web:deploy: ✘ [ERROR] Could not resolve "path"
web:deploy:
web:deploy: ../../node_modules/@neon-rs/load/dist/index.js:27:34:
web:deploy: 27 │ const path = __importStar(require("path"));
web:deploy: ╵ ~~~~~~
web:deploy:
web:deploy: The package "path" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
web:deploy:
web:deploy: ✘ [ERROR] Could not resolve "fs"
web:deploy:
web:deploy: ../../node_modules/@neon-rs/load/dist/index.js:28:32:
web:deploy: 28 │ const fs = __importStar(require("fs"));
web:deploy: ╵ ~~~~
web:deploy:
web:deploy: The package "fs" wasn't found on the file system but is built into node. Are you trying to bundle for node? You can use "platform: 'node'" to do that, which will remove this error.
web:deploy:
Folks, do you happen to have a simple reproducer for this? We had one, but after a Drizzle update it doesn't reproduce anymore
Same, seems like it was an issue on drizzle's side
Drizzle is involved here, but we'd like to defend better against those issues by having a full serverless driver that doesn't even list the node symbols as dependencies (the current driver lists it as a dependency, because we build the non-serverless driver from the same source).
If anybody has a current reproducer, that will help a lot.
Hi, here is what I found about this.
Looks like the issue, in this case, is that the build
command is running in a node environment and drizzle is importing types from @libsql/client
, which breaks everything.
We know that Drizzle is involved as @glommer mentioned, because if you remove drizzle from the turso-cf-sveltekit
example, it works. Also, if you put the code below on src/routes/+page.server.ts
, it breaks too:
import { type Client } from '@libsql/client';
export const load = async () => {
return { hello: 'world' };
};
However, if you apply the same fix that Drizzle, it works:
import type { Client } from '@libsql/client';
export const load = async () => {
return { hello: 'world' };
};
How to fix this? Well, there's a way! If for any reason @libsql/client
is imported on a web browser environment, you can add a browser
entry as documented on the packages documentation.
"exports": {
".": {
"types": "./lib-esm/node.d.ts",
"import": {
"workerd": "./lib-esm/web.js",
"deno": "./lib-esm/web.js",
"edge-light": "./lib-esm/web.js",
"netlify": "./lib-esm/web.js",
"node": "./lib-esm/node.js",
"browser": "./lib-esm/web.js", <----- Add this line
"default": "./lib-esm/node.js"
},
"require": "./lib-cjs/node.js"
},
Please note that default must come last as specified here:
"default" - the generic fallback that always matches. Can be a CommonJS or ES module file. This condition should always come last.
To ~hackily~ test this fix, you can edit the package file directly from node_modules/.pnpm/@libsql+client@0.3.5/node_modules/@libsql/client/package.json
and run pnpm build
.
The suggested code fixes the issue that we had with Drizzle and acts as a safety net for future issues.
However, this also opens a new door of improvement: what if we just rely on @libsql/client
for all environments? With package.json exports, this is possible and actually looks like what I did should work. This way the docs just mention @libsql/client
and the runtime will choose the correct module to use.
This is probably out of the scope of this issue, but I want to leave this here for future discussions! There are extra things to investigate related to this. For example, would this work in all environments? I've been researching this for a day and I'll stop now, but I'm willing to investigate further if you're interested in following this path.
We already support this via the
@libsql/client/web
import, but people are not associating it with AWS Lambda or Vercel and instead tripping over@libsql/client
import pulling the native library. Let's do a@libsql/serverless
package that people can import instead.