oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.17k stars 2.77k forks source link

Vite Rollup fails on "bun:sqlite" import even when it is marked as external #6738

Open joshdchang opened 1 year ago

joshdchang commented 1 year ago

What version of Bun is running?

1.0.7+b0393fba6200d8573f3433fb0af258a0e33ac157

What platform is your computer?

Darwin 23.0.0 arm64 arm

What steps can reproduce the bug?

When importing bun:sqlite in a Vite/Rollup project, it causes an error on build.

import { Database } from "bun:sqlite";

I marked bun:sqlite as an external dependency (external: ["bun:sqlite"] in Rollup config), so it should be ignored but it isn't.

What is the expected behavior?

I expected the build to compile while allowing bun:sqlite to be external. The Vite dev server works as expected, this is just on build.

What do you see instead?

I'm getting the following error: Error [PLUGIN_ERROR]: Only URLs with a scheme in: file, data, and node are supported by the default ESM loader. Received protocol 'bun:'

Additional information

I am submitting this as an issue to Bun because I think it may be useful for cases like this to have a way to reference the bun:sqlite module without using the :, such as having bun/sqlite as an alias or just including it as part of the Bun object.

Electroid commented 1 year ago

We'll need to submit PRs to Rollup and Vite to consider fixing this. /cc @colinhacks

joshdchang commented 1 year ago

Should I submit an issue to Rollup?

SlavenIvanov commented 7 months ago

Is there a workaround available for this?

keisanng commented 6 months ago

Is there any solution @bun team?

zackify commented 5 months ago

The only workaround I found, is using better-sqlite3 in dev. And marking it external works but only for production builds.

This sucks but works in the meantime.

Jarred-Sumner commented 5 months ago

If marking bun:sqlite as external in Rollup doesn't work in Rollup, then it's hard for us (Bun) to do anything about that.

Can you file an issue in Rollup's repository and link to it here?

zackify commented 5 months ago

Oh yeah, I know it’s on them. I actually have it on my list tomorrow to find where the problem is, vite or esbuild and patch it. I’ll respond here with what I find.

zackify commented 5 months ago

Alright, I found out the issue. Hopefully this helps someone.

let me know and I can update this guide because remix is different under vite https://bun.sh/guides/ecosystem/remix

Vite will work, but you have to be running fully under bun.

I had remix setup like this:

remix vite:dev

I had to change this to

bun run --bun vite

same with the build command:

bunx --bun remix vite:build

This will resolve bun deps without extra config options in vite.

For anyone interested, here's how I run my vite / remix app in prod:

NODE_ENV=production bun --bun run ./server.ts

and the server.ts file:

import type { ServerBuild } from "@remix-run/server-runtime";
import { createRequestHandler } from "@remix-run/server-runtime";
import { resolve } from "node:path";
import { type Serve } from "bun";

// in test mode this may not exist yet and tsc complains
//eslint-disable-next-line
//@ts-ignore
const build = await import("./build/server/index.js");

const remix = createRequestHandler(
  build as unknown as ServerBuild,
  Bun.env.NODE_ENV
);

export default {
  port: Bun.env.PORT || 3000,
  async fetch(request) {
    // First we need to send handle static files
    const { pathname } = new URL(request.url);

    if (pathname === "/health") {
      return new Response("OK", { status: 200 });
    }

    if (pathname.startsWith("/assets") || pathname.startsWith("/public")) {
      const file = Bun.file(
        resolve(__dirname, "./build/client/", `.${pathname}`)
      );
      if (await file.exists())
        return new Response(file, {
          headers: new Headers([["Cache-Control", "public, max-age=31536000"]]),
        });
    }

    // Only if a file its not a static file we will send it to remix
    return remix(request);
  },
} satisfies Serve;

and my entry.server.ts is using react 19 beta:

import type { EntryContext } from "@remix-run/node";
import { RemixServer } from "@remix-run/react";
//eslint-disable-next-line
//@ts-ignore
import { renderToReadableStream } from "react-dom/server.bun";
import "../shared/sentry/server";

export default async function handleRequest(
  request: Request,
  responseStatusCode: number,
  responseHeaders: Headers,
  remixContext: EntryContext
) {
  const stream = await renderToReadableStream(
    <RemixServer context={remixContext} url={request.url} />
  );

  const headers = new Headers(responseHeaders);

  headers.set("Content-Type", "text/html");
  return new Response(stream, {
    status: responseStatusCode,
    headers,
  });
}