File: readme.md
serve helps you serve a static site, single page application or just a static file (no matter if on your device or on the local network). It also provides a neat interface for listing the directory's contents:
Once it's time to push your site to production, we recommend using Vercel.
Usage
servev14 onwards requires Node v14 to run. Please useservev13 if you cannot upgrade to Node v14.
The quickest way to get started is to just run npx serve in your project's directory.
If you prefer, you can also install the package globally (you'll need at least Node LTS):
> npm install --global serveOnce that's done, you can run this command inside your project's directory...
> serve...or specify which folder you want to serve:
> serve folder-name/Finally, run this command to see a list of all available options:
> serve --helpNow you understand how the package works! :tada:
Configuration
To customize serve's behavior, create a serve.json file in the public folder and insert any of these properties.
API
The core of serve is serve-handler, which can be used as middleware in existing HTTP servers:
const handler = require('serve-handler');
const http = require('http');
const server = http.createServer((request, response) => {
// You pass two more arguments for config and middleware
// More details here: https://github.com/vercel/serve-handler#options
return handler(request, response);
});
server.listen(3000, () => {
console.log('Running at http://localhost:3000');
});You can also replace
http.createServerwithmicro.
Issues and Contributing
If you want a feature to be added, or wish to report a bug, please open an issue here.
If you wish to contribute to the project, please read the contributing guide first.
Credits
This project used to be called list and micro-list. But thanks to TJ Holowaychuk handing us the new name, it's now called serve (which is much more definite).
Author
Leo Lamprecht (@leo)
File: CHANGELOG.md
serve
14.2.6
Patch Changes
- 7fcb924: Bump ajv to 8.18.0
- b3888f9: Update
serve-handlerto6.1.7to fix ReDoS vulnerabilities
14.2.5
Patch Changes
- f4b6fbd: Update compression to v1.8.1
File: contributing.md
Contributing Guide
Thanks for your interest in contributing to serve! This guide will
show you how to set up your environment and contribute to this library.
Set Up
First, you need to install and be familiar the following:
git: Here is a great guide by GitHub on
installing and getting started with Git.nodeandpnpm:
This guide will help you
install Node and this one will help you install PNPM. The
recommended method is using thenversion manager if you are on MacOS or Linux. Make sure
you are using thecurrentversion of
Node.
Once you have installed the above, follow
these instructions
tofork
and clone the repository
(vercel/serve).
Once you have forked and cloned the repository, you can
pick out an issue
you want to fix/implement!
Making Changes
Once you have cloned the repository to your computer (say, in~/code/serve) and picked the issue you want to tackle, create a
branch:
> git switch --create branch-nameWhile naming your branch, try to follow the below guidelines:
- Prefix the branch name with the type of change being made:
fix: For a bug fix.feat: For a new feature.test: For any change related to tests.perf: For a performance related change.build: For changes related to the build process.ci: For all changes to the CI files.refc: For any refactoring work.docs: For any documentation related changes.
- Make the branch name short but self-explanatory.
Once you have created a branch, you can start coding!
The CLI is written in
Typescript and uses thecurrent version of Node.
The code is structured as follows:
serve
โโโ config
โ โโโ husky
โ โโโ _
โ โโโ pre-commit
โโโ media
โ โโโ banner.png
โ โโโ listing-ui.png
โโโ source
โ โโโ utilities
โ โ โโโ cli.ts
โ โ โโโ config.ts
โ โ โโโ http.ts
โ โ โโโ logger.ts
โ โ โโโ promise.ts
โ โ โโโ server.ts
โ โโโ main.ts
โ โโโ types.ts
โโโ contributing.md
โโโ license.md
โโโ package.json
โโโ pnpm-lock.yaml
โโโ readme.md
โโโ tsconfig.jsonMost files have a little description of what they do at the top.
`./`
package.json: Node package manifest. This file contains the name, version,
description, dependencies, scripts and package configuration of the project.pnpm-lock.yaml: PNPM lock file, please do not modify it manually. Runpnpm installto update it if you add/remove a dependency to/frompackage.jsonmanually.tsconfig.json: The Typescript configuration for this project.contributing.md: The file you are reading. It helps contributors get
started.license.md: Tells people how they can use the code.readme.md: The file everyone should read before running the server. Contains
installation and usage instructions.
`config/husky/`
pre-commit: This file is a script that runs before Git commits code.
`source/utilities/`
utilities/config.ts: Searches and parses the configuration for the CLI.utilities/http.ts: Defines and exports helper functions for the server.utilities/server.ts: Exports a function used to start the server with a
given configuration on a certain port.utilities/promise.ts: Exports utility functions and wrappers that help
resolvePromises.utilities/cli.ts: Exports functions that help with CLI-related stuff, e.g.,
parsing arguments and printing help text.utilities/logger.ts: A barebones logger.
`source/`
main.ts: Entrypoint for the CLI.types.ts: Typescript types used in the project.
When adding a new feature/fixing a bug, please add/update the readme. Also make
sure your code has been linted and that existing tests pass. You can run the linter
using pnpm lint, the tests using pnpm test and try to automatically fix most lint
issues using pnpm lint --fix.
You can run the CLI tool using pnpm develop, which will re-run the CLI everytime you
save changes made to the code.
Once you have made changes to the code, you will want tocommit (basically, Git's version
of save) the changes. To commit the changes you have made locally:
> git add this/folder that/file
> git commit --message 'commit-message'While writing the commit-message, try to follow the below guidelines:
- Prefix the message with
type:, wheretypeis one of the following
dependending on what the commit does:fix: Introduces a bug fix.feat: Adds a new feature.test: Any change related to tests.perf: Any performance related change.build: For changes related to the build process.ci: For all changes to the CI files.refc: Any refactoring work.docs: Any documentation related changes.
- Keep the first line brief, and less than 60 characters.
- Try describing the change in detail in a new paragraph (double newline after
the first line).
Contributing Changes
Once you have committed your changes, you will want topush (basically, publish your
changes to GitHub) your commits. To push your changes to your fork:
> git push -u origin branch-nameIf there are changes made to the main branch of thevercel/serve repository, you may wish torebase
your branch to include those changes. To rebase, or include the changes from themain branch of the vercel/serve repository:
> git fetch upstream main
> git rebase upstream/mainThis will automatically add the changes from main branch of thevercel/serve repository to the current branch. If you encounter
any merge conflicts, follow
this guide
to resolve them.
Once you have pushed your changes to your fork, follow
these instructions
to open apull request:
Once you have submitted a pull request, the maintainers of the repository will
review your pull requests. Whenever a maintainer reviews a pull request they may
request changes. These may be small, such as fixing a typo, or may involve
substantive changes. Such requests are intended to be helpful, but at times may
come across as abrupt or unhelpful, especially if they do not include concrete
suggestions on how to change them. Try not to be discouraged. If you feel that a
review is unfair, say so or seek the input of another project contributor. Often
such comments are the result of a reviewer having taken insufficient time to
review and are not ill-intended. Such difficulties can often be resolved with a
bit of patience. That said, reviewers should be expected to provide helpful
feedback.
In order to land, a pull request needs to be reviewed and approved by at least
one maintainer and pass CI. After that, if there are no objections from other
contributors, the pull request can be merged.
Congratulations and thanks for your contribution!
File: license.md
The MIT License (MIT)
Copyright (c) 2023 Vercel, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
File: package.json
{
"name": "serve",
"version": "14.2.6",
"description": "Static file serving and directory listing",
"keywords": [
"vercel",
"serve",
"micro",
"http-server"
],
"repository": "vercel/serve",
"license": "MIT",
"type": "module",
"bin": {
"serve": "./build/main.js"
},
"files": [
"build/"
],
"engines": {
"node": ">= 14"
},
"scripts": {
"develop": "tsx watch ./source/main.ts",
"start": "node ./build/main.js",
"compile": "tsup ./source/main.ts",
"test:tsc": "tsc --project tsconfig.json",
"test:unit": "vitest run --config config/vitest.ts",
"test:watch": "vitest watch --config config/vitest.ts",
"test": "pnpm test:tsc && pnpm test:unit",
"lint:code": "eslint --max-warnings 0 source//.ts",
"lint:style": "prettier --check --ignore-path .gitignore .",
"lint": "pnpm lint:code && pnpm lint:style",
"format": "prettier --write --ignore-path .gitignore .",
"prepare": "husky install config/husky && pnpm compile",
"changeset": "changeset",
"version-packages": "changeset version",
"release": "pnpm compile && changeset publish"
},
"dependencies": {
"@zeit/schemas": "2.36.0",
"ajv": "8.18.0",
"arg": "5.0.2",
"boxen": "7.0.0",
"chalk": "5.0.1",
"chalk-template": "0.4.0",
"compression": "1.8.1",
"is-port-reachable": "4.0.0",
"serve-handler": "6.1.7",
"tinyclip": "^0.1.12",
"update-check": "1.5.4"
},
"devDependencies": {
"@changesets/cli": "2.29.6",
"@types/compression": "1.7.2",
"@types/serve-handler": "6.1.1",
"@vercel/style-guide": "3.0.0",
"@vitest/coverage-v8": "2.1.3",
"eslint": "8.19.0",
"got": "12.1.0",
"husky": "8.0.1",
"lint-staged": "13.0.3",
"prettier": "2.7.1",
"tsup": "8.3.0",
"tsx": "4.19.1",
"typescript": "5.6.3",
"vitest": "2.1.3"
},
"tsup": {
"target": "esnext",
"format": [
"esm"
],
"outDir": "./build/"
},
"prettier": "@vercel/style-guide/prettier",
"eslintConfig": {
"extends": [
"./node_modules/@vercel/style-guide/eslint/node.js",
"./node_modules/@vercel/style-guide/eslint/typescript.js"
],
"parserOptions": {
"project": "tsconfig.json"
}
},
"lint-staged": {
"": [
"prettier --ignore-unknown --write"
],
"source//*.ts": [
"eslint --max-warnings 0 --fix",
"vitest related --run"
],
"tests": [
"vitest --run"
]
},
"packageManager": "[email protected]+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
}
File: pnpm-workspace.yaml
allowBuilds:
core-js-pure: true
esbuild: true
minimumReleaseAge: 2880
File: tsconfig.json
{
"extends": "@vercel/style-guide/typescript",
"compilerOptions": {
"lib": ["es2020"],
"target": "es2020",
"module": "esnext",
"moduleResolution": "node",
"noEmit": true,
"resolveJsonModule": true
},
"include": ["source/"]
}
File: tests/__fixtures__/config/custom/config.json
{
"public": "app/",
"renderSingle": true
}
File: tests/__fixtures__/config/deprecated/package.json
{
"static": {
"public": "app/"
}
}
File: tests/__fixtures__/config/invalid/serve.json
{
"symlink": ["app/"]
}
File: tests/__fixtures__/config/valid/serve.json
{
"public": "app/",
"renderSingle": true
}
File: tests/__fixtures__/server/serve.json
{
"public": "app/",
"renderSingle": true
}
File: tests/__fixtures__/server/ssl/serve.json
{
"public": "app/",
"renderSingle": true
}
File: .changeset/clipboardy-to-tinyclip.md
'serve': patch
Replace clipboardy with tinyclip
File: .changeset/config.json
{
"$schema": "https://unpkg.com/@changesets/[email protected]/schema.json",
"changelog": "@changesets/cli/changelog",
"commit": false,
"fixed": [],
"linked": [],
"access": "public",
"baseBranch": "main",
"updateInternalDependencies": "patch",
"ignore": [],
"snapshot": {
"useCalculatedVersion": true
}
}
File: .github/ISSUE_TEMPLATE/bug_report.yaml
name: Report a bug
labels: [bug]
body:
- type: markdown
attributes:
value: |
# Thanks for reporting this bug!
Help us replicate and find a fix for the issue by filling in this form. - type: textarea
attributes:
label: Description
Describe the issue and how to replicate it. If possible, please include
a minimal example to reproduce the issue.
validations:
required: true - type: input
attributes:
label: Library version
Output of theserve --versioncommand
validations:
required: true - type: input
attributes:
label: Node version
validations:
required: true
File: .github/ISSUE_TEMPLATE/feature_request.yaml
name: Suggest an improvement or new feature
labels: [enhancement]
body:
- type: markdown
attributes:
value: |
# Thanks for filing this feature request!
Help us understanding this feature and the need for it better by filling in this form. - type: textarea
attributes:
label: Description
validations:
required: true - type: textarea
attributes:
label: Why
validations:
required: true - type: textarea
attributes:
label: Alternatives
validations:
required: true
File: .github/PULL_REQUEST_TEMPLATE/default.md
Related Issues
Description
Added
Changed
Removed
Caveats/Problems/Issues
Checklist
- The issues that this PR fixes/closes have been mentioned above.
- What this PR adds/changes/removes has been explained.
- All tests (
pnpm test) pass. - The linter (
pnpm lint) does not throw an errors. - All added/modified code has been commented, and
methods/classes/constants/types have been annotated with TSDoc comments.
File: .github/workflows/ci.yaml
.github/workflows/ci.yaml
Lints and tests the server every time a commit is pushed to the remote
repository.
name: CI
on: [push, pull_request]
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Setup PNPM
uses: pnpm/action-setup@v4
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org/'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Check for errors in code/formatting
run: pnpm lint
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Setup PNPM
uses: pnpm/action-setup@v4
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org/'
cache: 'pnpm'
- name: Install dependencies
run: pnpm install
- name: Run all tests
run: pnpm test
File: .github/workflows/release-snapshot.yaml
name: Release Snapshot
env:
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
on:
workflow_dispatch:
jobs:
release-snapshot:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Setup PNPM
uses: pnpm/action-setup@v4
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org/'
cache: 'pnpm'
- name: Add npm auth token to pnpm
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN_ELEVATED}"
env:
NPM_TOKEN_ELEVATED: ${{secrets.NPM_TOKEN_ELEVATED}}
- name: Install dependencies
run: pnpm install
- name: Add SHORT_SHA env property with commit short sha
run: echo "SHORT_SHA=echo ${{ github.sha }} | cut -c1-8" >> $GITHUB_ENV
- name: Version Packages
run: pnpm changeset version --snapshot ${SHORT_SHA}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}
- name: Compile
run: pnpm compile
- name: Publish Snapshot Release
run: pnpm changeset publish --no-git-tag --tag snapshot
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}
File: .github/workflows/release.yaml
name: Release
on:
push:
branches:
- main
concurrency: ${{ github.workflow }}-${{ github.ref }}
jobs:
release:
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout the repository
uses: actions/checkout@v4
- name: Setup PNPM
uses: pnpm/action-setup@v4
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: 22
registry-url: 'https://registry.npmjs.org/'
cache: 'pnpm'
- name: Add npm auth token to pnpm
run: pnpm config set '//registry.npmjs.org/:_authToken' "${NPM_TOKEN_ELEVATED}"
env:
NPM_TOKEN_ELEVATED: ${{secrets.NPM_TOKEN_ELEVATED}}
- name: Install dependencies
run: pnpm install
- name: Compile
run: pnpm compile
- name: Run all tests
run: pnpm test
- name: Create Release Pull Request or Publish to npm
id: changesets
uses: changesets/action@v1
with:
publish: pnpm release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}