Skip to content

Commit

Permalink
v1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
aabccd021 committed Dec 5, 2024
1 parent c4076b3 commit dccf8f0
Show file tree
Hide file tree
Showing 11 changed files with 292 additions and 218 deletions.
3 changes: 0 additions & 3 deletions .envrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
if ! has nix_direnv_version || ! nix_direnv_version 2.1.1; then
source_url "https://raw.githubusercontent.com/nix-community/nix-direnv/2.1.1/direnvrc" "sha256-b6qJ4r34rbE23yWjMqbmu3ia2z4b2wIlZUksBke/ol0="
fi
use flake
layout node
27 changes: 27 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
on:
workflow_dispatch:
push:
branches-ignore:
- main

jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- uses: DeterminateSystems/nix-installer-action@main

- uses: HatsuneMiku3939/direnv-action@v1

- run: bun install

- run: bun run prettier-check

- run: bun run typescript-check

- run: bun test/reloads.ts

- uses: JS-DevTools/npm-publish@v3
with:
token: ${{ secrets.NPM_TOKEN }}
145 changes: 97 additions & 48 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,86 +2,135 @@

HTML live reload for Bun

## Installation
## Getting Started

```sh
bun add -d bun-html-live-reload
```

## Getting Started

```ts
// example.ts
import { withHtmlLiveReload } from "bun-html-live-reload";

export default withHtmlLiveReload({
fetch: () => {
Bun.serve({
fetch: withHtmlLiveReload(async (request) => {
return new Response("<div>hello world</div>", {
headers: { "Content-Type": "text/html" },
});
},
}),
});
```

- Wrap your regular [hot reloading Bun server](https://bun.sh/docs/runtime/hot#http-servers) with `withHtmlLiveReload`.
- Run the server with `bun --hot example.ts`, open browser, and try to edit the `hello world` part.
- The page should live reload as you edit!

## Response Header

This plugin relies on response header to identify html file,
so don't forget to add `{ headers: { "Content-Type": "text/html" }, }` to your `Response`.
- This plugin relies on response header to identify html response,
so don't forget to add `"Content-Type": "text/html"` header to your `Response`.

## Options

### `wsPath`
### `eventPath` and `scriptPath`

You can specify URL paths used for server-sent events and live reloader script.

URL path used for websocket connection.
```ts
Bun.serve({
fetch: withHtmlLiveReload(
async (request) => {
/* ... */
},
{
// SSE Path
// default: "/__dev__/reload"
eventPath: "/__reload",

// Live reload script path
// default: "/__dev__/reload.js"
scriptPath: "/__reload.js",
},
),
});
```

This library relies on websocket to live reload an HTML.
The path `wsPath` will be used to upgrade HTTP connection to websocket one.
## Manually reload clients

For example, the default `wsPath` value `__bun_live_reload_websocket__`,
will upgrade `http://localhost:3000/__bun_live_reload_websocket__`
to `ws://localhost:3000/__bun_live_reload_websocket__`.
You can manually reload clients (refresh tabs) by calling `reloadClients` function.

```ts
export default withHtmlLiveReload(
{
fetch: () => {
return new Response("<div>hello world</div>", {
headers: { "Content-Type": "text/html" },
});
},
},
{
wsPath: "your_ws_path",
}
);
import { withHtmlLiveReload, reloadClients } from "bun-html-live-reload";

Bun.serve({
fetch: withHtmlLiveReload(async (request) => {
/* ... */
}),
});

// reload clients every second
setInterval(() => {
reloadClients();
}, 1000);
```

### React HMR: `watchPath`, `buildConfig`, and `onChange`
# Changes from v0.1

The `watchPath` is the file or folder path that should be watched to trigger the reloads. This could be used to reload html files on changing files in other folders like `src` for react projects.
- Messages are sent through SSE (HTTP streaming) instead of Websocket.
- Wraps only `fetch` function instead of the whole server.
- Exposes `reloadClients` function to manually reload clients.
- Uses separate javascript file instead of inline script to comply with strict CSP.
- Supports multiple clients (tabs).
- Added tests

The `buildConfig` is used for running the `Bun.build()` command when the files in the `watchPath` change. The `Bun.build()` command will always be run once before starting the server.
# Migration from v0.1

The `onChange` is a function which runs before `Bun.build()` when using `buildConfig` when the files in `watchPath` change. This command does not run at start.
## v0.1

```ts
export default withHtmlLiveReload(
{
...
},
{
watchPath: path.resolve(import.meta.dir, "src"),
buildConfig: {
entrypoints: ["./src/index.tsx"],
outdir: "./build"
import { withHtmlLiveReload } from "bun-html-live-reload";
import { $ } from "bun";

export default Bun.serve(
withHtmlLiveReload(
{
fetch: (request) => {
/* ... */
},
},
{
watchPath: path.resolve(import.meta.dir, "src"),
buildConfig: {
entrypoints: ["./src/index.tsx"],
outdir: "./build",
},
onChange: async () => {
await $`rm -r ./dist`;
},
},
onChange: async () => {
await $`rm -r ./dist`
}
}
),
);
```

## v1.0

```ts
import { withHtmlLiveReload, reloadClients } from "bun-html-live-reload";
import { FSWatcher, watch } from "fs";
import { $ } from "bun";

const buildConfig = {
entrypoints: ["./src/index.tsx"],
outdir: "./build",
};

Bun.build(buildConfig);

watch(path.resolve(import.meta.url, "src")).on("change", async () => {
await $`rm -r ./dist`;
await Bun.build(buildConfig);
reloadClients();
});

Bun.serve({
fetch: withHtmlLiveReload(async (request) => {
/* ... */
}),
});
```
Binary file modified bun.lockb
Binary file not shown.
21 changes: 8 additions & 13 deletions example.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
import { withHtmlLiveReload } from "./index.js";
import { withHtmlLiveReload } from "./index.ts";

export default withHtmlLiveReload(
{
fetch: () => {
return new Response("<div>hello world</div>", {
headers: { "Content-Type": "text/html" },
});
},
},
{
wsPath: "your_ws_path",
}
);
Bun.serve({
fetch: withHtmlLiveReload(async () => {
return new Response("<div>Init</div>", {
headers: { "Content-Type": "text/html" },
});
}),
});
6 changes: 3 additions & 3 deletions flake.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 13 additions & 3 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,21 @@
nixpkgs.url = "github:nixos/nixpkgs/nixpkgs-unstable";
};

outputs = { self, nixpkgs }: with nixpkgs.legacyPackages.x86_64-linux; {
devShell.x86_64-linux = mkShellNoCC {
outputs = { nixpkgs, ... }:
let
pkgs = nixpkgs.legacyPackages.x86_64-linux;

in
{

devShells.x86_64-linux.default = pkgs.mkShellNoCC {
shellHook = ''
export PLAYWRIGHT_BROWSERS_PATH=${pkgs.playwright-driver.browsers-chromium}
'';
buildInputs = [
bun
pkgs.bun
];
};

};
}
Loading

0 comments on commit dccf8f0

Please sign in to comment.