oven-sh / bun

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

dev server tracking issue #14324

Open paperdave opened 4 days ago

paperdave commented 4 days ago

With #14258 merged, Bake can finally be tried out in canary builds (usage guide at end of issue). However, it is missing many features and testing that make it currently unsuitible for production-grade applications.

Remember this list is not in order, and that not every item on this list is strictly a blocker. I will edit it as the plan changes.

Contributions are appreciated. Please join #bake in the Bun Discord for questions relating to the architecture of the Dev Server, as well as if you are trying it out as a user or framework author.

I will update this as I think of more. These are just the steps that come to mind. Additionally, I will open another issue containing the plan for production builds, though I think some of this work waits on the API design.

Reliability

There are currently 3 unit tests in total for Bake. Given the size and scope of the dev server alone, much more testing and tooling is needed.

Performance

While I have done little testing on the performance, I am confident that large projects will show decent reloading speed, but there is significant cost placed on the first bundle task. I'm sure a lot of work can be done to profile and micro-optimize things, but here is a list of broader changes to the design:

Open-ended performance tasks:

Informal Usage Guide

The following is from the message I sent in the #bake channel on the Bun Discord

Bun Bake is an experimental API for building full-stack client-server web applications (this is the "Framework API [SOON]" item that has been greyed out on our docs for over a year). Today, our hot-reloading development server in is experimental beta. The purpose of this beta is to find bugs and gather feedback to shape the final API (we are thinking of, but still designing, a Bun.serve integration)

Bake provides first-class support for React server components, but using a generic interface that can be used by any framework.

To try Bake dev server today, upgrade to the latest canary build, bun upgrade --canary and create a file with:

import { wipDevServerExpectHugeBreakingChanges } from "bun";

wipDevServerExpectHugeBreakingChanges({
  // routes must be statically known so production
  // builds can prepare all required assets.
  routes: [
    { pattern: '/', entrypoint: './route.tsx' },
    { pattern: '/second', entrypoint: './second.tsx' },
  ],
  // for framework authors, attach your framework
  // via the interface described in `bake.d.ts`
  framework: 'react-server-components',
});

The built in react-server-components framework requires external dependencies, which can be installed with bun install

$ bun i react@experimental react-dom@experimental react-server-dom-webpack@experimental react-refresh@experimental
$ bun run index.ts
bndkt commented 2 days ago

@paperdave I just discovered this tracking issue and am really excited about it! I also saw react-server-dom-bun mentioned there. I had started working on this as part of building https://github.com/bndkt/kotekan (which I did abandon in favor of another approach which still heavily involves Bun and which will be at least partially obsolete once the things mentioned in this issue land). I'm happy to transfer https://www.npmjs.com/package/react-server-dom-bun to you, just ping me on https://x.com/bndkt.

paperdave commented 1 day ago

I'm happy to transfer [react-server-dom-bun] to you

Great. I had spotted this package existing and I was a little worried on the difficulty of getting the package. I don't fully know what the plan will be, but I think the react project itself publishes the -webpack and -turbopack versions of the react-server.

So far, I got server components to work using react-server-dom-webpack using the browser builds of both server and target (so i could use renderToReadableStream), but those have a dependency on __webpack_require__. I currently work around this by just defining __webpack_require__

// TODO: Remove this after `react-server-dom-bun` is uploaded
globalThis.__webpack_require__ = (id: string) => {
  if (side == "server" && config.separateSSRGraph && !id.startsWith("ssr:")) {
    return loadModule("ssr:" + id, LoadModuleType.UserDynamic).exports;
  } else {
    return loadModule(id, LoadModuleType.UserDynamic).exports;
  }
};

on the server, i noticed that react sort of just ignores the manifest when using the browser build. when using the node.js server build, it uses dynamic import for that module, which works a bit better (but no readable stream api).

so the bun version would basically work the same, but i would probably hold off doing it for a little bit longer in case some more bundler changes happen and there is a more optimal way to write the integration.