oven-sh / bun

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

Support `watch: true` in `Bun.build()` #5866

Open robobun opened 11 months ago

robobun commented 11 months ago

Like the title says, i wanted to run the bundler in watch mode using a js file containing

await Bun.build({
    entrypoints: ["./test.ts"],
    outdir: ["./dist"],
    sourcemap: "external"
})

And the error logging example copy pasted. I also tried import Bun from "bun", but the same behaviour as described below.

I ran bun --watch run bun.js in cli and expected it to work like bun build ./tests.ts --outdir ./dist -- watch. When running the first command, it compiles the code correctly, but the watch mode only affects bun.js, not the files in entrypoints. Is this expected behaviour? Is there another way to activate watch mode? Or am i just misinterpreting the documentation

Originally reported on Discord: Watch mode using bundler and not using cli not working as expected

MatrixAge commented 11 months ago

+1, this will be helpful for replacing like webpack or rspack.

anabelle2001 commented 11 months ago

+1. This feature is already supported in the command line; it's not clear to me why it can't be called from a method.

lucasfarias2 commented 8 months ago

+1. This feature is already supported in the command line; it's not clear to me why it can't be called from a method.

I think it's clear, I haven't read the code but it must need to create a file watcher somewhere and call a new Build everytime file changes.

I needed something similar because I wanted a separate bun server to open a websocket to fast refresh/hot reload html in the browser without refreshing the page.

I did this as a temporary solution based on Bun's documentation:

builder.ts

const srcWatcher = watch(
  `${import.meta.dir}/src`,
  { recursive: true },
  (event, filename) => {
    Bun.build({
      entrypoints: ["./src/entry.ts"],
      outdir: "./dist",
    });

    console.log(`Detected ${event} in ${filename} (src)`);
  }
);

process.on("SIGINT", () => {
  srcWatcher.close();
  process.exit(0);
});

console.log("Running dev server on port 4321");

you can run that with bun builder.ts

silvenon commented 8 months ago

I think it's clear, I haven't read the code but it must need to create a file watcher somewhere and call a new Build everytime file changes.

Creating a file watcher with a dependency-unaware tool would only rebuild if the file itself changes, not its dependencies. If watching the directory is good enough for your use case that's fine, but the watch option is definitely missing from Bun.build, especially because it supports multiple entry points.

I also haven't read how --watch works, but it would be better to have --watch and the missing watch options do their magic and become better over time behind the scenes.

b1lly commented 7 months ago
const srcWatcher = watch(
  `${import.meta.dir}/src`,
  { recursive: true },
  (event, filename) => {
    Bun.build({
      entrypoints: ["./src/entry.ts"],
      outdir: "./dist",
    });

    console.log(`Detected ${event} in ${filename} (src)`);
  }
);

process.on("SIGINT", () => {
  srcWatcher.close();
  process.exit(0);
});

Has there been a resolution to this? I have noticed this issue with my current environment. Using a script file, does not watch the proper directories. Instead, it's watching the actual script directory, and not the entry points of the build commands.

b1lly commented 7 months ago

Like the title says, i wanted to run the bundler in watch mode using a js file containing

await Bun.build({
    entrypoints: ["./test.ts"],
    outdir: ["./dist"],
    sourcemap: "external"
})

And the error logging example copy pasted. I also tried import Bun from "bun", but the same behaviour as described below.

I ran bun --watch run bun.js in cli and expected it to work like bun build ./tests.ts --outdir ./dist -- watch. When running the first command, it compiles the code correctly, but the watch mode only affects bun.js, not the files in entrypoints. Is this expected behaviour? Is there another way to activate watch mode? Or am i just misinterpreting the documentation

Originally reported on Discord: Watch mode using bundler and not using cli not working as expected

This is an issue for my setup too. I'm using a mono repo, with multiple apps so I have a few build targets. For that, i'm using custom build scripts.

Setup:

  1. The build scripts, are in their own directory ./.bun/*scripts
  2. The packages are in their own directory packages, and apps are in apps
  3. When I use the build script, bun --watch ./.bun/script.js, the file watching is on the script being provided as input, and not the actual entry points of the Bun.build entrypoint or targets.
melishev commented 5 months ago

I agree, this functionality is very necessary, now it is impossible to run any build that should use plugins in watch mode

gutenye commented 4 months ago

Really needs this

For now, I use

npm install -g chokidar-cli
chokidar 'src/**/*.{js,ts}' -c 'bun run build.ts' --initial
denis-ilchishin commented 3 months ago

If you have one entrypoint (with declarations/exports only, like a library for example), you can import that file in build script and run with bun run --watch build.ts:

// build.ts
import './index'

await Bun.build({
  entrypoints: './index.ts',
  // ...
})
elad-yosifon commented 2 months ago

+1 really needs this one

mifopen commented 1 month ago

This is very unfortunate that the flag is not exposed. It is very hard to support plugin preloading via bunfig.toml for us and we have to use programmatic API. And the lack of ability to watch changes makes it very inconvenient to work fast.

flexchar commented 1 month ago

This would be such a huge life changer. I am already in love with bun bundler.

In the mean time I am using [watchexec](https://github.com/watchexec/watchexec?tab=readme-ov-file]