Skip to content

Commit 96ce88d

Browse files
committed
Initial commit
0 parents  commit 96ce88d

15 files changed

+930
-0
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
*.log
2+
*.tgz
3+
.DS_Store
4+
dist
5+
node_modules

.prettierrc

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"printWidth": 80,
3+
"singleQuote": true,
4+
"trailingComma": "es5"
5+
}

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2022 - present Joel Arvidsson
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# esbuild-server
2+
3+
**⚡️ Fast, lightweight and powerful development server for esbuild ⚡️**
4+
5+
- Zero dependencies besides esbuild
6+
- API proxy support
7+
- Live reload
8+
- SPA support through History API fallback
9+
- Fully typed with TypeScript
10+
11+
## Installation
12+
13+
```bash
14+
npm install --save-dev esbuild esbuild-server
15+
```
16+
17+
## Usage
18+
19+
Create a new file for your dev server:
20+
21+
```js
22+
// dev-server.js
23+
require('esbuild-server')
24+
.createServer(
25+
{
26+
bundle: true,
27+
entryPoints: ['src/app.js'],
28+
},
29+
{
30+
static: 'public',
31+
}
32+
)
33+
.start();
34+
```
35+
36+
Assuming you have an `index.html` file in the `public` folder you can now run the server with `node dev-server.js`.
37+
38+
See `example` folder for examples.
39+
40+
## API
41+
42+
### createServer(esbuildOptions, serverOptions)
43+
44+
#### `esbuildOptions`
45+
46+
Options passed to [esbuild Build API](https://esbuild.github.io/api/#build-api). If not specified `watch` defaults to `true` to enable continous build and live reload, and similarly if no type of output option is specified `outdir` is set to a temporary directory.
47+
48+
#### `serverOptions`
49+
50+
| Option | Description | Default |
51+
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
52+
| **`static`** | Path to your static assets folder, should contain an `index.html` file. | _None_ |
53+
| **`port`** | Port number to listen for requests on. | `8080` |
54+
| **`historyApiFallback`** | For Single Page Apps using the HTML5 History API, the index.html page is served instead of 404 responses. | `false` |
55+
| **`injectLiveReload`** | Inject snippet to automatically reload the page when file changes are detected. | `true` |
56+
| **`open`** | Open the browser after server had been started. Set to a string to open a particular path. | `false` |
57+
| **`proxy`** | Proxy certain paths to a separate API backend when you want to serve API requests on the same domain. Pass a function for dynamic rewrites. | `{}` |
58+
| **`onProxyRewrite`** | Callback function when a proxy rewrite happens, useful for logging or altering the response. | _None_ |
59+
60+
## Proxying
61+
62+
### Static
63+
64+
```js
65+
{
66+
proxy: {
67+
'/api': 'http://localhost:3000'
68+
}
69+
}
70+
```
71+
72+
A request to `/api/users` will now proxy the request to `http://localhost:3000/api/users`. If you want to rewrite the base use dynamic approach instead:
73+
74+
### Dynamic
75+
76+
```js
77+
{
78+
proxy: (path) => {
79+
if (path.startsWith('/api')) {
80+
return path.replace(/^\/api/, 'http://localhost:3000');
81+
}
82+
};
83+
}
84+
```
85+
86+
A request to `/api/users` will now proxy the request to `http://localhost:3000/users`.
87+
88+
### Modifying the response
89+
90+
```js
91+
{
92+
onProxyRewrite: (proxyRes, localUrl, proxyUrl) => {
93+
console.log(`Proxying ${localUrl} to ${proxyUrl}`);
94+
proxyRes.headers['x-my-custom-header'] = 'yep';
95+
return proxyRes;
96+
};
97+
}
98+
```
99+
100+
## Live reload
101+
102+
If you want more control over where the live reload script is injected you can place it manually with:
103+
104+
```html
105+
<script src="/esbuild-livereload.js" async></script>
106+
```
107+
108+
## License
109+
110+
MIT © Joel Arvidsson 2022 – present

example/public/index.html

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>esbuild-server</title>
7+
</head>
8+
<body>
9+
<h1>Hello World</h1>
10+
<script src="app.js"></script>
11+
</body>
12+
</html>

example/server.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const { createServer } = require('..' /* esbuild-server */);
2+
const server = createServer(
3+
{
4+
bundle: true,
5+
entryPoints: ['src/app.ts'],
6+
},
7+
{
8+
static: 'public',
9+
proxy: {
10+
'/info.0.json': 'https://xkcd.com',
11+
},
12+
onProxyRewrite: (proxyRes, localUrl, proxyUrl) => {
13+
console.log(`Proxying ${localUrl} to ${proxyUrl}`);
14+
return proxyRes;
15+
},
16+
open: true,
17+
}
18+
);
19+
20+
const buildStart = Date.now();
21+
server.start().then((buildResult) => {
22+
if (buildResult.errors.length === 0) {
23+
console.log(`Build completed in ${Date.now() - buildStart}ms`);
24+
} else {
25+
console.error('Build failed');
26+
}
27+
});
28+
console.log(`Development server running at ${server.url}`);

example/src/api.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
type APIResponseData = {
2+
year: string;
3+
month: string;
4+
day: string;
5+
num: number;
6+
link: string;
7+
news: string;
8+
safe_title: string;
9+
transcript: string;
10+
alt: string;
11+
img: string;
12+
title: string;
13+
};
14+
15+
export async function fetchComic() {
16+
const response = await fetch('/info.0.json');
17+
if (!response.ok) {
18+
throw new Error('Request failed');
19+
}
20+
const data: APIResponseData = await response.json();
21+
return data;
22+
}

example/src/app.ts

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { fetchComic } from './api';
2+
3+
async function main() {
4+
try {
5+
const comic = await fetchComic();
6+
const img = document.createElement('img');
7+
img.src = comic.img;
8+
img.alt = comic.alt;
9+
document.body.appendChild(img);
10+
} catch (err) {
11+
console.error('Something went wrong fetching the comic');
12+
}
13+
}
14+
15+
main();

package.json

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "esbuild-server",
3+
"version": "0.1.0",
4+
"author": "Joel Arvidsson",
5+
"license": "MIT",
6+
"main": "./dist/index.js",
7+
"types": "./dist/index.d.ts",
8+
"scripts": {
9+
"build": "esbuild src/livereload.js --outdir=dist --target=es6 --minify --log-level=warning && tsc",
10+
"format": "prettier '{,src/,example/**/}*.{md,js,ts,json}' --write"
11+
},
12+
"engines": {
13+
"node": ">=14"
14+
},
15+
"files": [
16+
"browser/*",
17+
"dist/*"
18+
],
19+
"devDependencies": {
20+
"@tsconfig/node14": "^1.0.1",
21+
"@types/node": "14",
22+
"esbuild": "^0.14.27",
23+
"prettier": "^2.6.0",
24+
"typescript": "^4.6.2"
25+
},
26+
"peerDependencies": {
27+
"esbuild": ">=0.14.0"
28+
}
29+
}

0 commit comments

Comments
 (0)