Skip to content

Latest commit

 

History

History
136 lines (108 loc) · 2.75 KB

README.md

File metadata and controls

136 lines (108 loc) · 2.75 KB

bun-html-live-reload

HTML live reload for Bun

Getting Started

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

Bun.serve({
  fetch: withHtmlLiveReload(async (request) => {
    return new Response("<div>hello world</div>", {
      headers: { "Content-Type": "text/html" },
    });
  }),
});
  • 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!
  • 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

eventPath and scriptPath

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

Bun.serve({
  fetch: withHtmlLiveReload(
    async (request) => {
      /* ... */
    },
    {
      // SSE Path
      // default: "/__dev__/reload"
      eventPath: "/__reload",

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

Manually reload clients

You can manually reload clients (refresh tabs) by calling reloadClients function.

import { withHtmlLiveReload, reloadClients } from "bun-html-live-reload";

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

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

Changes from v0.1

  • 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

Migration from v0.1

v0.1

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`;
      },
    },
  ),
);

v1.0

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) => {
    /* ... */
  }),
});