3h-serve 中文文档教程
3h-serve
一个简单但功能强大的服务器。
TOC
Introduction
3h-serve
是一个简单但功能强大的服务器,主要用于测试。
可以运行npm i -g 3h-serve
全局安装,执行3h-serve -h
查看帮助信息。
Features
Serverless Functions
开箱即用地支持无服务器功能。
例如,给定一个脚本文件 /api/helloWorld.js
:
module.exports = (request, response) => {
response.end('Hello, world!');
};
通过在根目录中运行 3h-serve --serverless "^/api/"
并访问 localhost:8080/api/helloWorld
在您的浏览器中,您应该得到 Hello, world!
作为结果。
更具体地说,将调用从与选项中给出的无服务器模式匹配的文件导出的函数来处理请求。 定义无服务器功能的文件应该是这样的:
/**
* @param {import('http').IncomingMessage} request The native request object
* @param {import('http').ServerResponse} response The native response object
* @param {import('3h-serve').lib} lib The lib object (See `Program Usage` section)
* @param {object} options Options passed to current handler
*/
module.exports = (request, response, lib, options) => {
// Do something with the request and respond to it...
};
SPA Home Page Routing
路由单页应用程序也受支持。 也就是说,使用此功能,给定目录中名为 200.html
(名称可以配置)的主页,对目录中不存在的文件的请求将以该页面响应。
Lucid Caching
3h-serve
有一个内置的缓存控制系统。 启用缓存后,所有响应都将具有以下缓存控制指令和一个 ETag
标识符,它告诉浏览器它们可以将任何资产存储一年,但它们必须在提供之前验证缓存的资产:
Cache-Control: public, max-age=31536000, no-cache
在此这样,所有资产都将被缓存,但不会提供过时的资产。
Clean URLs
干净的 URL 意味着您可以通过请求 /baz/index
甚至 /baz
来访问 /baz/index.html
,其中包括默认页面服务和默认扩展名匹配。 (默认:index.html
和 .html
)
Automatic Zipping
启用压缩后,如果相应的客户端声明支持它(通过使用请求标头 Accept-编码
)。 这包括 br
、gzip
和 deflate
压缩支持。
Custom Fallback Page
您还可以通过简单地将名为 404.html
(名称可以配置)的文件放在您网站的根目录中来自定义您网站的后备页面。
Debug Logging
3h-serve
提供详细的调试日志记录,以便您了解请求是如何解决的。 要启用日志记录,请将日志级别设置为 log
或 debug
。 将其设置为 log
会产生一些简短的请求和响应信息,而将其设置为 debug
将使路由进程日志记录也可用。
Command Line Usage
3h-serve <root> [options]
<root> Serving root
Default: .
-a, --absolute Indicate that the root path is absolute
-p, --port <port> The port to listen on
Default: 8080
--default-page <file> The default page to serve
Default: index.html
--no-default-page Disable default page
--default-ext <ext> Default file extension
Default: .html
--no-default-ext Disable default file extension
--spa <file> SPA home page
Default: 200.html
--no-spa Disable SPA routing
--forbidden Forbidden URL pattern
--fallback-page <file> Fallback page path
Default: 404.html
--no-fallback-page Disable fallback page
-s, --serverless Serverless file pattern
--serverless-ext <ext> Default serverless file extension
Default: .js
--no-serverless-ext Disable default serverless file extension
--no-cache Disable cache
--no-zip Disable zipping
-l, --log-level Log level
Options: "info"(default), "log", "debug"
--silent Disable log
--time-format Time format
Default: [YYYY-MM-DD HH:mm:SS.sss]
-h, --help Show help information
Program Usage
此处列出了导出的 API,可以通过将 3h-serve
安装为依赖项并从 3h-serve
导入它们来访问它们。 (请注意,lib
对象也可用作无服务器函数的第三个参数。)
/**
* @desc The default MIME type map
*/
const DEFAULT_TYPES: Map<string, string>;
/**
* @typedef ServeOptions
* @property {string} root The root directory (Default: .)
* @property {number} port The port to use (Default: 8080)
* @property {string} timeFormat Time format passing to `3h-log` (Default: [YYYY-MM-DD HH:mm:SS.sss])
* @property {boolean} cache Whether to enable cache (Default: true)
* @property {boolean} zip Whether to enable response zipping (Default: true)
* @property {'info' | 'log' | 'debug'} logLevel Log level (Default: info)
* @property {boolean} silent Whether to suppress any log (including basic info logging)
* @property {string | null} separator The separator between logs (Default: ----------)
* @property {Map<string, string>} types The MINE type map (Default: DEFAULT_TYPES)
* @property {RegExp | null} forbiddenPattern Pattern of forbidden URLs (Default: null)
* @property {RegExp | null} serverlessPattern Pattern of serverless files (Default: null)
* @property {string | null} serverlessExtension Default extension of serverless files (Default: .js)
* @property {string | null} spaPage SPA home page (Default: 200.html)
* @property {string | null} defaultPage The default page to serve (Default: index.html)
* @property {string | null} defaultExtension The default extension to match (Default: .html)
* @property {string | null} fallbackPage Fallback page (Default: 404.html)
*/
/**
* @desc Defaults for `serve`
*/
const DEFAULT_SERVE_OPTIONS: ServeOptions;
/**
* @desc Create a server that acts according to given options
*/
function serve(options?: ServeOptions): Server;
/**
* @desc The lib object provides some useful functionalities for dealing with requests
*/
namespace lib {
/**
* @desc Merge the defaults and options
*/
function merge<T>(defaults: T, options: Partial<T>): T;
/**
* @desc Tell whether the given path is a file
*/
function isFile(path: string): boolean;
/**
* @typedef RouteOptions
* @property {string | null} spaPage SPA home page
* @property {string | null} defaultPage The default page to serve
* @property {string | null} defaultExtension The default extension to match
* @property {boolean} acceptServerless Whether serverless files are acceptable
* @property {string | null} serverlessExtension Default serverless file extension
* @property {Logger | null} logger The logger to use
*/
/**
* @typedef RoutingResult
* @property {string} path The result path
* @property {boolean} serverless Whether the target is a serverless function
*/
/**
* @desc Route the given path and returns the result
*/
function route(path: string, options: RouteOptions): RoutingResult | null;
/**
* @desc Log the status code and its corresponding status phrase
*/
function logStatus(logger: Logger, statusCode: number): void;
/**
* @desc End the response with the given code and logs it if logger is provided
*/
function endWithCode(response: ServerResponse, code: number, logger?: Logger | null): void;
/**
* @typedef EndWithFileOptions
* @property {boolean} cache
* @property {boolean} zip
* @property {Map<string, string>} types
* @property {Logger | null} logger The logger to use
*/
/**
* @desc End the response with the file indicated by `path`
*/
function endWithFile(
request: IncomingMessage,
response: ServerResponse,
path: string,
options: EndWithFileOptions
): void;
/**
* @typedef SolveOptions
* @property {string} root The root path
* @property {boolean} cache Whether to enable cache
* @property {boolean} zip Whether to enable zipping
* @property {Map<string, string>} types The MIME map to use
* @property {RegExp | null} forbiddenPattern Pattern of forbidden URLs
* @property {RegExp | null} serverlessPattern Pattern of serverless files
* @property {string | null} serverlessExtension Default extension of serverless files
* @property {string | null} spaPage SPA home page
* @property {string | null} defaultPage The default page to serve
* @property {string | null} defaultExtension The default extension to match
* @property {string | null} fallbackPage Fallback page
* @property {Logger | null} logger The logger to use
*/
/**
* @desc Solve the request according to the given path
*/
function solve(
request: IncomingMessage,
response: ServerResponse,
path: string,
options: SolveOptions
): void;
}
3h-serve
A simple but powerful server.
TOC
Introduction
3h-serve
is a simple but powerful server which is mainly used for testing.
You can run npm i -g 3h-serve
to install it globally and check the help information by executing 3h-serve -h
.
Features
Serverless Functions
Serverless functions are supported out of the box.
For example, given a script file /api/helloWorld.js
:
module.exports = (request, response) => {
response.end('Hello, world!');
};
By running 3h-serve --serverless "^/api/"
in the root directory and visitting localhost:8080/api/helloWorld
in your browser, you should get Hello, world!
as the result.
More specifically speaking, a function exported from a file which matches the serverless pattern given in options will be invoked to handle the request. The file defining the serverless function should be like this:
/**
* @param {import('http').IncomingMessage} request The native request object
* @param {import('http').ServerResponse} response The native response object
* @param {import('3h-serve').lib} lib The lib object (See `Program Usage` section)
* @param {object} options Options passed to current handler
*/
module.exports = (request, response, lib, options) => {
// Do something with the request and respond to it...
};
SPA Home Page Routing
Routing single page applications is also supported. That is, with this feature, given a home page named 200.html
(the name can be configured) in a directory, requests to files in the directory which are not present will be responded with that page.
Lucid Caching
3h-serve
has a built-in cache control system. With cache enabled, all responses will have the following cache control directive and an ETag
identifier, which tells the browsers that they can store any assets for a year but they must validate cached assets before serving them:
Cache-Control: public, max-age=31536000, no-cache
In this way, all assets will be cached but no stale assets will be served.
Clean URLs
Clean URLs mean that you can visit /baz/index.html
by requesting /baz/index
or even /baz
, which includes default page serving and default extension matching. (Default: index.html
and .html
)
Automatic Zipping
With zipping enabled, all responses will be zipped if corresponding clients claim support of it (by using request header Accept-Encoding
). This includes br
, gzip
and deflate
zipping support.
Custom Fallback Page
You can also customize the fallback page of your site by just simpling put a file named 404.html
(the name can be configured) in the root directory of your site.
Debug Logging
3h-serve
provides detailed debug logging so that you can see how requests are solved. To enable logging, set log level to log
or debug
. Setting it to log
results in some brief request and response information, while setting it to debug
will make routing processes logging also available.
Command Line Usage
3h-serve <root> [options]
<root> Serving root
Default: .
-a, --absolute Indicate that the root path is absolute
-p, --port <port> The port to listen on
Default: 8080
--default-page <file> The default page to serve
Default: index.html
--no-default-page Disable default page
--default-ext <ext> Default file extension
Default: .html
--no-default-ext Disable default file extension
--spa <file> SPA home page
Default: 200.html
--no-spa Disable SPA routing
--forbidden Forbidden URL pattern
--fallback-page <file> Fallback page path
Default: 404.html
--no-fallback-page Disable fallback page
-s, --serverless Serverless file pattern
--serverless-ext <ext> Default serverless file extension
Default: .js
--no-serverless-ext Disable default serverless file extension
--no-cache Disable cache
--no-zip Disable zipping
-l, --log-level Log level
Options: "info"(default), "log", "debug"
--silent Disable log
--time-format Time format
Default: [YYYY-MM-DD HH:mm:SS.sss]
-h, --help Show help information
Program Usage
The exported APIs are listed here which can be accessed by installing 3h-serve
as a dependency and importing them from 3h-serve
. (Note that the lib
object is also available as the third parameter of serverless functions.)
/**
* @desc The default MIME type map
*/
const DEFAULT_TYPES: Map<string, string>;
/**
* @typedef ServeOptions
* @property {string} root The root directory (Default: .)
* @property {number} port The port to use (Default: 8080)
* @property {string} timeFormat Time format passing to `3h-log` (Default: [YYYY-MM-DD HH:mm:SS.sss])
* @property {boolean} cache Whether to enable cache (Default: true)
* @property {boolean} zip Whether to enable response zipping (Default: true)
* @property {'info' | 'log' | 'debug'} logLevel Log level (Default: info)
* @property {boolean} silent Whether to suppress any log (including basic info logging)
* @property {string | null} separator The separator between logs (Default: ----------)
* @property {Map<string, string>} types The MINE type map (Default: DEFAULT_TYPES)
* @property {RegExp | null} forbiddenPattern Pattern of forbidden URLs (Default: null)
* @property {RegExp | null} serverlessPattern Pattern of serverless files (Default: null)
* @property {string | null} serverlessExtension Default extension of serverless files (Default: .js)
* @property {string | null} spaPage SPA home page (Default: 200.html)
* @property {string | null} defaultPage The default page to serve (Default: index.html)
* @property {string | null} defaultExtension The default extension to match (Default: .html)
* @property {string | null} fallbackPage Fallback page (Default: 404.html)
*/
/**
* @desc Defaults for `serve`
*/
const DEFAULT_SERVE_OPTIONS: ServeOptions;
/**
* @desc Create a server that acts according to given options
*/
function serve(options?: ServeOptions): Server;
/**
* @desc The lib object provides some useful functionalities for dealing with requests
*/
namespace lib {
/**
* @desc Merge the defaults and options
*/
function merge<T>(defaults: T, options: Partial<T>): T;
/**
* @desc Tell whether the given path is a file
*/
function isFile(path: string): boolean;
/**
* @typedef RouteOptions
* @property {string | null} spaPage SPA home page
* @property {string | null} defaultPage The default page to serve
* @property {string | null} defaultExtension The default extension to match
* @property {boolean} acceptServerless Whether serverless files are acceptable
* @property {string | null} serverlessExtension Default serverless file extension
* @property {Logger | null} logger The logger to use
*/
/**
* @typedef RoutingResult
* @property {string} path The result path
* @property {boolean} serverless Whether the target is a serverless function
*/
/**
* @desc Route the given path and returns the result
*/
function route(path: string, options: RouteOptions): RoutingResult | null;
/**
* @desc Log the status code and its corresponding status phrase
*/
function logStatus(logger: Logger, statusCode: number): void;
/**
* @desc End the response with the given code and logs it if logger is provided
*/
function endWithCode(response: ServerResponse, code: number, logger?: Logger | null): void;
/**
* @typedef EndWithFileOptions
* @property {boolean} cache
* @property {boolean} zip
* @property {Map<string, string>} types
* @property {Logger | null} logger The logger to use
*/
/**
* @desc End the response with the file indicated by `path`
*/
function endWithFile(
request: IncomingMessage,
response: ServerResponse,
path: string,
options: EndWithFileOptions
): void;
/**
* @typedef SolveOptions
* @property {string} root The root path
* @property {boolean} cache Whether to enable cache
* @property {boolean} zip Whether to enable zipping
* @property {Map<string, string>} types The MIME map to use
* @property {RegExp | null} forbiddenPattern Pattern of forbidden URLs
* @property {RegExp | null} serverlessPattern Pattern of serverless files
* @property {string | null} serverlessExtension Default extension of serverless files
* @property {string | null} spaPage SPA home page
* @property {string | null} defaultPage The default page to serve
* @property {string | null} defaultExtension The default extension to match
* @property {string | null} fallbackPage Fallback page
* @property {Logger | null} logger The logger to use
*/
/**
* @desc Solve the request according to the given path
*/
function solve(
request: IncomingMessage,
response: ServerResponse,
path: string,
options: SolveOptions
): void;
}