npm package: @imhjh/server
Description: 简易 node 服务器
Author: imhjh
Latest version: 1.2.1

# @imhjh/server 文档

[源码](https://gitee.com/hjh925678208/server)

一个简易的 node web 框架。

## 安装

```bash
# npm
npm install @imhjh/server --save-dev
# yarn
yarn add @imhjh/server --save
```

## 使用

`createApp`实例通过中间件的形式实现请求解析和传参.

```js
import { createApp } from "@imhjh/server"

createApp()
  // 最后执行的中间件, 结束请求, 返回数据
  .use(({ response }) => {
    response.end()
  })
  // 开启设置监听
  .listen({ port: 8080 }, (server) => {
    console.log("启动成功")
  })
```

## API

### createApp

创建服务器

```ts
createApp(options: AppOptions): AppObject
```

#### `AppOptions`

```ts
declare interface RequestResult {
  statusCode?: number
  data: any
}
declare interface RouteHandler {
  // MiddlewareOptions: 经过中间件处理后的配置
  (options: MiddlewareOptions): RequestResult
}
declare interface RouteObject {
  path: string /** 本级路径片段 */
  handler: RouteHandler /** 对应路径的请求方法 */
  children?: RouteObject[] /** 子级路径列表 */
}
const routes: RouteObject[] = [
  {
    path: "/test",
    handler: () => ({ statusCode: 200, data: "" })
  }
]

declare interface AppOptions {
  routes?: RouteObject[] /** 路由配置 */
  strict?: boolean /** 是否启用路由严格配置，匹配 "/" 结尾 */
  serveOptions?: ServeOptions /** http.createServer 配置 */
  readDirname?: string /** 用于读取文件的目录 */
}
const options: AppOptions = {
  routes: routes,
  strict: false,
  serveOptions: {},
  readDirname: ""
}
```

#### `AppObject`

```ts
declare interface RequestLocation {
  /** 完整请求地址
   * @example http://127.0.0.1:80/path?query=params#hash */
  href: string
  /** 协议+主机+端口
   * @example http://127.0.0.1:80 */
  origin: string
  /** 协议
   * @example http */
  protocol: string
  /** 账号 */
  username: string
  /** 密码 */
  password: string
  /** 主机+端口
   * @example 127.0.0.1:80 */
  host: string
  /** 主机
   * @example 127.0.0.1 */
  hostname: string
  /** 端口
   * @example 80 */
  port: string
  /** 请求路径
   * @example /path */
  pathname: string
  /** 参数
   * @example ?query=params */
  search: string
  /** URLSearchParams对象 */
  searchParams: URLSearchParams
  /** hash参数
   * @example #hash */
  hash: string
}
declare interface RequestQuery {
  method?: string
  extname?: string
  query?: { [k: string]: any } // url携带参数
  postData?: { [k: string]: any } // 非get请求参数
}
// 通过内置中间件解析出来的配置
declare interface ExtraMiddlewareOptions {
  server: Server /** 服务器实例 */
  router: RouterObject /** 使用 defineRouter 解析出来的路由键值对 */
  strict: boolean /** 接口地址是否严格匹配 */
  requestLocation?: RequestLocation /** 请求地址解析 */
  requestQuery?: RequestQuery /** 请求参数解析 */
  requestResult?: RequestResult /** 请求返回结果 */
  readDirname?: string /** 用于读取文件的目录 */
}
declare interface MiddlewareOptions extends ExtraMiddlewareOptions {
  request: IncomingMessage /** request 对象 */
  response: ServerResponse /** response 对象 */
  [k: string]: any
}
declare interface MiddlewareFunction {
  (options: MiddlewareOptions, next: () => void): void
}
declare interface AppObject {
  server: Server /** http.createServer 服务器对象 */
  use: (middleware: MiddlewareFunction) => AppObject
  listen: (options: ListenOptions, listeningListener: (server: Server) => void) => void
}

const app: AppObject = createApp()

app
  .use((options, next) => {
    next() // 触发下一个中间件处理
  })
  .listen({ port: 8080 }, (server) => {
    // 启动监听后的回调
  })
```

### getDirname

用于 esm 环境获取 dirname

```js
// 通过 import.meta 获取当前目录的绝对地址
const dirname = getDirname(import.meta)
```

### useAddress

解析 server 获取监听的 http

```js
const app = createApp()

app.listen({ port: 8080 }, (server) => {
  const address = useAddress(server)
  // address.port: 8080
  // address.family: IPV4 | IPV6
  // address.hostname: 127.0.0.1
})
```

### readFile

同步读取文件

```js
const data = readFile(dirname, filename) // 内部通过 path.join 合并地址
```

### getMIME

根据后缀获取对应的媒体类型

```js
getMIME("html") // "text/html"
```