1.2.9 • Published 4 years ago

semo-plugin-serve v1.2.9

Weekly downloads
-
License
MIT
Repository
-
Last release
4 years ago

semo-plugin-serve

一个简易的 HTTP Server 工具,类似的工具有很多,包括但不限于:

还有一些工具,比如 hexo,本来是个博客工具,也自带了 HTTP Server 的功能,umi,本来是个前端开发脚手架,也自带了启动 HTTP Server 的功能,当然,还有大名鼎鼎的 create-react-app 等等,而且 node 本身写一个简单的Web服务器也不是很复杂,那为什么还要去做一个新的轮子呢?

为什么造这个轮子

其中一个原因是看到了一个项目 osgood,其实现了基于命令行工具快速定义路由和控制器的思路。另外,由于 Semo 做为一个命令行开发框架,其价值就是按需封装各种各样的命令行工具,而且其命令,脚本都有相对统一的模块风格,那就是基于约定导出固定变量用于固定用途的约定大于配置的思路。将二者结合就形成了这个新的 HTTP Server 工具,其 Web Server 部分基于 koa 及其中间件实现,定制性较强,这个轮子主要就是制定规则,提供相关语法糖。

感谢 Koa 的简洁和灵活,我们可以按需定制所需要的特性,本程序使用 Koa 来实现 Web 服务以及各种扩展功能

特性

  • 同时支持静态资源服务和后端接口服务,
  • 后端服务,目录结构就是路由结构
  • 后端服务路由可以灵活配置,内置了参数验证机制
  • 后端服务可以引入全局中间件和单个路由中间件,也可以禁用内置中间件
  • 支持一些个性化选项,个性化选项也都可以在配置文件(.semorc.yml)中设置
  • 支持端口占用自动检测
  • 支持和SPA模式和404模式

安装

npm i -g @semo/cli semo-plugin-serve

使用

semo serve [publicDir]

simple server tool

选项:
  --port, -p                                    server port                                              [默认值: false]
  --list, -l                                    list routes
  --init-koa, -i                                initial koa application                                  [默认值: false]
  --api-prefix                                  prefix all routes                                       [默认值: "/api"]
  --spa                                         fallback to index.html
  --gzip                                        enable gzip
  --routeDir                                    routes location
  --publicDir                                   static files location
  --file-index                                  index file name                                   [默认值: "index.html"]
  --file-404                                    index file name                                          [默认值: false]
  --disable-internal-middleware-custom-error    disable internal middleware custom error
  --disable-internal-middleware-custom-static   disable internal middleware custom static
  --disable-internal-middleware-custom-router   disable internal middleware custom router
  --disable-internal-middleware-koa-logger      disable internal middleware koa-logger
  --disable-internal-middleware-koa-bodyparser  disable internal middleware koa-bodyparser
  --disable-internal-middleware-koa-kcors       disable internal middleware kcors

命令行使用说明

路由代码生成器

借助于 Semo 提供的统一的代码生成入口和扩展性,我们实现了一个简单的路由代码生成器

semo make route a/b/c

查看声明的路由地址

semo serve --list

启动服务

semo serve [publicDir]
semo serve # 默认当前目录

watch 模式

借助 nodemon 模块

npm i -g nodemon
nodemon --exec 'semo serve'

路由系统说明

一个路由的样子

完整版

export const name = 'signup' // 给路由起个名字
export const method = 'post' // 支持各种 HTTP 请求方法
export const path = 'abc' // 自动添加到路径路由的后面
export const middleware = [] // 为单个路由指定前置中间件
export const validate = { // 请求参数验证
  username: 'required'
}
export const handler = async ctx => {} // 路由回调

简单版

export = async ctx => {}

ctx 的约定用法

关闭默认的 json 响应格式

ctx.json = false

自定义错误码

这里要注意的是抛出的错误码必须经过定义

ctx.errors[10001] = '自定义错误消息'
// 或
ctx.error(10001, '自定义错误消息', 405)

throw new ctx.Exception(10001, '重写错误消息')

Mock 数据

命令内置了 mockjs 库,只需要通过 ctx.Mockctx.mock 就能访问,ctx.mock === ctx.Mock.mock

gzip 压缩

当选项 --gzip 设置为 true 以后,默认凡是内容类型包含 text 的响应都会进行 gzip 压缩,如果想关闭可以在路由响应函数里进行如下操作:

module.export = async ctx => {
  ctx.compress = false
  // 或
  ctx.gzip = false
}

路由前缀

我们默认的路由前缀是 /api,因为默认的使用场景是前端静态目录和后端动态接口都支持,如果仅仅是使用后端功能,可以改写前缀,或者清空前缀。

特殊的路由

index 文件名的路由在我们对路由的理解里有特殊含义,因为我们一般不需要一个路由这样访问:/api/a/b/index,而只需要是 /api/a/b,所以如果我们不是将路由实现在 b.js里,而是b/index.js,效果是一样的。

SPA模式和404模式

只要在启动时加上 --spa 选项,不存在的路径就会指向默认的 index.html,需要注意的是 --api-prefix 选项指定的 API前缀下的路由即使找不到也只是会抛出路由不存在的异常响应,而不会指向 index.html,这么做的目的是为了同时支持前后端的使用场景。

如果不使用SPA模式,并且配置了 --file-404 选项,比如404.html,则所有不存在的404静态资源都会使用这个配置的静态页面进行输出,如果设置为 false 关闭了这个选项,则会输出为 Not found 字符串。

中间件的禁用和扩展

通过工具提供的选项可以看出,所有内置的中间件都可以禁用,而且可以通过 --init-app 的选项注入一个模块来添加更多的中间件,两个特性一起使用的话,可以完全自定义 koa 所需要的所有的中间件,当然如果是这么做的话,那本工具也就没必要使用了。

// init-app.js
// semo serve --init-app init-app.js
module.exports = (app) => {
  app.use(async (ctx, next) => {
    
    await next()
  })
}

APIs

如果不想用 Semo 来调度也可以直接已模块的方式引入,参数可以参考命令行选项

import { startServer } from 'semo-plugin-serve'

async() {
  await startServer({
    publicDir: '.'
  })
}

Constants

  • SEMO_SERVE_DISABLE_ERROR_STACK=1

开源协议

MIT