Skip to content

Commit

Permalink
feat: custom hot reload query param
Browse files Browse the repository at this point in the history
to be omitted by default with a fallback to `location.reload()`
  • Loading branch information
davidenke committed Dec 8, 2023
1 parent 7ea7281 commit fb2c588
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 28 deletions.
18 changes: 4 additions & 14 deletions esbuild.run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,26 +143,16 @@ ${Object.entries(BREAKPOINTS).reduce((acc, [key, value]) => `${acc} ${key}: ${v
};

if (watch) {
const reloadBanner = `
// reload page on file change
if (typeof EventSource !== 'undefined') {
new EventSource('/wcp').addEventListener('message', ({ data }) => {
// console.log('[wcp] manifest updated', JSON.parse(data));
// window.location.reload(true);
const url = new URL(window.location.href);
url.searchParams.set('reload', '');
window.location.href = url.toString();
});
}
`;

// start dev server in watch mode
const internalPort = 28487;
const server = createServer(internalPort);
const manifestPath = resolve(options.outdir!, 'custom-elements.json');

// prepare context and start watching
const ctx = await context({ ...options, banner: { js: `${reloadBanner}\n${options.banner?.js ?? ''}` } });
const ctx = await context({
...options,
banner: { js: `${server.reloadBanner('wcp-hot-reload')}\n${options.banner?.js ?? ''}` },
});
await ctx.watch();
await ctx.serve({ servedir: options.outdir, port: internalPort });

Expand Down
30 changes: 29 additions & 1 deletion esbuild.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
import http, { type ServerResponse, type Server } from 'node:http';

type DevServer = Server & { respond(data: unknown): void };
type DevServer = Server & {
/**
* To be used as banner for the client script.
* Reloads the page if the dev server sends a message.
* @param reloadQueryParam - query parameter to be added to the URL
*/
reloadBanner(reloadQueryParam?: string): string;

/**
* Sends a message to the client using Server-Sent Events.
* @param data - arbitrary data to be send to the client that can be stringified to JSON
*/
respond(data: unknown): void;
};

export function createServer(port: number): DevServer {
let stream: ServerResponse;
Expand Down Expand Up @@ -40,5 +53,20 @@ export function createServer(port: number): DevServer {
}
};

server.reloadBanner = (reloadQueryParam) => `
// reload page on file change
if (typeof EventSource !== 'undefined') {
new EventSource('/wcp').addEventListener('message', () => {
${
!reloadQueryParam
? `window.location.reload();`
: `const redirect = new URL(window.location.href);
redirect.searchParams.set('${reloadQueryParam}', '');
window.location.href = redirect.toString();`
}
});
}
`;

return server;
}
15 changes: 8 additions & 7 deletions src/components/root/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

## Properties

| Property | Attribute | Modifiers | Type | Default | Description |
|-----------------|----------------|-----------|-----------------------|---------|--------------------------------------------------|
| `configUrl` | `config-url` | | `string \| undefined` | | Allows to set a url to load a config file from. |
| `hideSplash` | `hide-splash` | | `boolean` | false | Allows hiding the splash screen. |
| `inline` | `inline` | | `boolean` | false | Flags the component to be displayed inline and not standalone. Requires the surrounding<br />layout to provide the necessary styles like for any other block element. |
| `manifestUrl` | `manifest-url` | | `string` | | Defines the location of the custom element manifest file. |
| `navigationRef` | | readonly | `RootNavigation` | | |
| Property | Attribute | Modifiers | Type | Default | Description |
|--------------------|----------------------|-----------|-----------------------|---------|--------------------------------------------------|
| `configUrl` | `config-url` | | `string \| undefined` | | Allows to set a url to load a config file from. |
| `hideSplash` | `hide-splash` | | `boolean` | false | Allows hiding the splash screen. |
| `inline` | `inline` | | `boolean` | false | Flags the component to be displayed inline and not standalone. Requires the surrounding<br />layout to provide the necessary styles like for any other block element. |
| `manifestUrl` | `manifest-url` | | `string` | | Defines the location of the custom element manifest file. |
| `navigationRef` | | readonly | `RootNavigation` | | |
| `reloadQueryParam` | `reload-query-param` | | `string \| undefined` | | An optional reload query param to be removed after initial load.<br />Will prevent the splash screen to be shown on reload. |

## Methods

Expand Down
21 changes: 16 additions & 5 deletions src/components/root/root.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ export class Root extends LitElement {
@property({ type: Boolean, reflect: true, attribute: 'hide-splash' })
hideSplash = false;

/**
* An optional reload query param to be removed after initial load.
* Will prevent the splash screen to be shown on reload.
*/
@property({ type: String, reflect: true, attribute: 'reload-query-param' })
reloadQueryParam?: string;

/**
* Allows to set a url to load a config file from.
*/
Expand Down Expand Up @@ -92,8 +99,10 @@ export class Root extends LitElement {
super.connectedCallback();

// check for the reload query param
const params = new URLSearchParams(window.location.search);
if (params.has('reload')) this.hideSplash = true;
if (this.reloadQueryParam) {
const params = new URLSearchParams(window.location.search);
if (params.has(this.reloadQueryParam)) this.hideSplash = true;
}

// once connected, load the config and the manifest
const config = await loadConfig(this.configUrl);
Expand All @@ -113,9 +122,11 @@ export class Root extends LitElement {
this.ready = true;

// remove reload query param
const url = new URL(window.location.href);
url.searchParams.delete('reload');
window.history.replaceState({}, '', url.toString());
if (this.reloadQueryParam) {
const url = new URL(window.location.href);
url.searchParams.delete(this.reloadQueryParam);
window.history.replaceState({}, '', url.toString());
}
}

override disconnectedCallback() {
Expand Down
2 changes: 1 addition & 1 deletion src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
</head>

<body>
<wcp-root config-url="config.json" manifest-url="custom-elements.json"></wcp-root>
<wcp-root config-url="config.json" manifest-url="custom-elements.json" reload-query-param="wcp-hot-reload"></wcp-root>
<script type="module" src="index.js"></script>
</body>

0 comments on commit fb2c588

Please sign in to comment.