barely-a-dev-server
Advanced tools
Comparing version 0.2.1 to 0.2.2
{ | ||
"name": "barely-a-dev-server", | ||
"version": "0.2.1", | ||
"version": "0.2.2", | ||
"type": "module", | ||
@@ -5,0 +5,0 @@ "description": "", |
# `barely-a-dev-server` | ||
A thin, opinionated wrapper for `esbuild` as a `.ts` web server. Given a `entryRoot` folder, it: | ||
A thin, opinionated wrapper for `esbuild` as a `.ts` web server. Given an `entryRoot` folder, it: | ||
- finds all `.ts` file in `entryRoot` and uses them as entry files to run `esbuild` in `watch` mode, and | ||
- finds all `.ts` files under `entryRoot` and uses them as entry files to run `esbuild` in `watch` mode, and | ||
- serves the built `.js` files together with a fallback to `entryRoot` for static files. | ||
- Paths ending in `/` are mapped to `index.html` in the corresponding folder. | ||
When run with `"dev": false`, it writes these files to an output dir (`dist/` + the source root by default), ready to serve using your favorite static file server. | ||
When run with `"dev": false`, it writes these files to an output dir (`dist/` + the entry root by default), ready to serve using your favorite static file server. | ||
# Usage: | ||
# Example | ||
@@ -17,3 +18,3 @@ ```js | ||
barelyServe({ | ||
entryRoot: "src/sites", // the only required arg | ||
entryRoot: "src", // the only required arg | ||
dev: true, | ||
@@ -27,2 +28,4 @@ port: 3333, | ||
--- | ||
```html | ||
@@ -33,6 +36,4 @@ <!-- src/index.html --> | ||
(Note that `src` must reference the built `.js` file. You can use `href` to store a reference to the source that e.g. you can click in VSCode.) | ||
```ts | ||
// index.ts | ||
// src/index.ts | ||
const a: number = 4; | ||
@@ -42,5 +43,17 @@ console.log(a); | ||
# Assumptions | ||
(Note that `src` must reference the `.js` file, not `.ts`. The example shows a hack: you can use `href` to store a reference to the `.ts` source, which works with e.g. "Follow link" in VSCode.) | ||
- You're using only ESM code. | ||
- You have a build script to invoke this from. (TODO: [CLI](https://github.com/lgarron/barely-a-dev-server/issues/1)) | ||
# Why `barely-a-dev-server`? | ||
- Works just as well as fancy bundlers, if all your code is TypeScript. | ||
- No dependencies. | ||
- Less than 200 lines of source code (unminified). | ||
# Why not `barely-a-dev-server`? | ||
- Hardcoded to assume that you are only using TypeScript for your source and ESM for your output. | ||
- No CLI. | ||
- If you don't have a build script, you can do this: `node -e 'import("barely-a-dev-server").then(s => s.barelyServe({entryRoot: "src"}))'` | ||
- No automatic URL opening, no live refresh. | ||
These are mostly because it would make the codebase significantly larger to support them properly. |
import * as esbuild from "esbuild"; | ||
import { join } from "path"; | ||
import { listFilesWithSuffix } from "./ls.js"; | ||
import { listFiles } from "./ls.js"; | ||
@@ -17,7 +17,8 @@ let currentBuildResult = null; | ||
const entryPoints = await listFilesWithSuffix( | ||
join(process.cwd(), entryRootPath), | ||
".ts" | ||
); | ||
console.log(`Starting esbuild with ${entryPoints.length} entry points.`); | ||
const absoluteRootPath = join(process.cwd(), entryRootPath); | ||
const entryPoints = ( | ||
await listFiles(absoluteRootPath, (path) => path.endsWith(".ts")) | ||
).map((relativePath) => join(absoluteRootPath, relativePath)); | ||
console.log(`Starting esbuild with ${entryPoints.length} entry point(s).`); | ||
return (currentBuildResult = esbuild.build({ | ||
@@ -24,0 +25,0 @@ target: "es2020", |
@@ -10,3 +10,2 @@ import type { BuildOptions } from "esbuild"; | ||
port?: number; | ||
type?: "site" | "library"; | ||
}); |
@@ -1,4 +0,5 @@ | ||
import { cp } from "fs/promises"; | ||
import { join } from "path"; | ||
import { copyFileSync, mkdirSync } from "fs"; | ||
import { dirname, join } from "path"; | ||
import { restartEsbuild } from "./esbuild.js"; | ||
import { listFiles } from "./ls.js"; | ||
import { CustomServer } from "./server.js"; | ||
@@ -45,8 +46,7 @@ | ||
} | ||
debug ??= false; | ||
dev ??= true; | ||
esbuildOptions ??= {}; | ||
type ??= "site"; | ||
port ??= 1234; | ||
outDir ??= join(dev ? "dist/dev" : "dist", entryRoot); | ||
debug = debug ?? false; | ||
dev = dev ?? true; | ||
esbuildOptions = esbuildOptions ?? {}; | ||
port = port ?? 1234; | ||
outDir = outDir ?? join(dev ? "dist/dev" : "dist", entryRoot); | ||
@@ -60,6 +60,10 @@ await restartEsbuild(entryRoot, outDir, dev, esbuildOptions); | ||
}).start(); | ||
} else if (type === "site") { | ||
// TODO: filter out `.ts` if they don't work for source maps? | ||
await cp(entryRoot, outDir, { recursive: true }); | ||
} else { | ||
for (const relativePath of await listFiles(entryRoot, () => true)) { | ||
mkdirSync(dirname(join(outDir, relativePath)), { recursive: true }); | ||
copyFileSync(join(entryRoot, relativePath), join(outDir, relativePath)); | ||
} | ||
// TODO: Switch to this once `node` 16 is the default in Codespaces: | ||
// await fsPromises.cp(entryRoot, outDir, { recursive: true }); | ||
} | ||
} |
import { stat, readdir } from "fs/promises"; | ||
import { join } from "path"; | ||
export async function listFilesWithSuffix(folderPath, suffix) { | ||
let childNames = await readdir(folderPath); | ||
export async function listFiles(folderPath, filter, relativePath) { | ||
let childNames = await readdir( | ||
relativePath ? join(folderPath, relativePath) : folderPath | ||
); | ||
let ownMatches = []; | ||
let recursiveMatches = []; | ||
for (const childName of childNames) { | ||
const childPath = join(folderPath, childName); | ||
if ((await stat(childPath)).isDirectory()) { | ||
const newRelativePath = relativePath | ||
? join(relativePath, childName) | ||
: childName; | ||
if ((await stat(join(folderPath, newRelativePath))).isDirectory()) { | ||
recursiveMatches = recursiveMatches.concat( | ||
await listFilesWithSuffix(childPath, suffix), | ||
await listFiles(folderPath, filter, newRelativePath) | ||
); | ||
} else if (childPath.endsWith(suffix)) { | ||
ownMatches.push(childPath); | ||
} else if (filter(newRelativePath)) { | ||
ownMatches.push(newRelativePath); | ||
} | ||
@@ -19,0 +22,0 @@ } |
import { barelyServe } from "../src/index.js"; | ||
barelyServe({ | ||
srcRoot: "./test/root/", | ||
entryRoot: "./test/root/", | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11393
14
197
56