启动和部署
Midway 提供了一个轻量的启动器,用于启动你的应用。我们为应用提供了多种部署模式,你既可以将应用按照传统的样子,部署到任意的服务上(比如自己购买的服务器),也可以将应用构建为一个 Serverless 应用,Midway 提供跨多云的部署方式。
本地开发
这里列举的主要是本地使用 dev
命令开发的方式,有两种。
快速启动单个服务
在本地研发时,Midway 在 package.json
中提供了一个 dev
命令启动框架,比如:
{
"script": {
"dev": "midway-bin dev --ts"
}
}
这是一个最精简的命令,他有如下特性:
- 1、使用
--ts
指定 TypeScript(ts-node)环境启动 - 2、使用内置的(@midwayjs/mock 的 createApp)创建一个**匹配当前框架 **的服务,并返回 app
在命令行运行下面的命令即可执行。
$ npm run dev
所谓匹配当前框架,指的是根据内部的框架列表,和 pkg 的依赖匹配查找到最符合当前的框架并启动。
内部的框架列表如下:
const currentFramework = [
'@midwayjs/web',
'@midwayjs/koa',
'@midwayjs/express',
'@midwayjs/serverless-app',
'@midwayjs/grpc',
'@midwayjs/rabbitmq',
'@midwayjs/socketio',
'@midwayjs/faas',
];
这样启动的服务用于本地快速开发测试,使用的是 框架初始化的默认值。
比如,你的 package.json
中依赖如下;
{
"@midwayjs/grpc": "xxx",
"@midwayjs/web": "xxx"
}
按照优先级顺序,默认的 dev
依旧会启动 @midwayjs/web
服务。
指定入口启动服务
由于本地的 dev 命令普通情况下和 bootstrap.js
启动文件初始化参数不同,有些用户担心本地开发和线上开发不一致,或者希望一次启动多个框架(多种协议)。
这个时候我们可以直接传递一个入口文件给 dev
命令,直接使用入口文件启动服务。
{
"script": {
"dev": "midway-bin dev --ts --entryFile=bootstrap.js"
}
}
这种情况下,会忽略其余的参数,比如 --port。
部署到普通服务器
部署后和本地开发的区别
在部署后,有些地方和本地开发有所区别。
1、node 环境的变化
最大的不同是,服务器部署后,会直接使用 node 来启动项目,而不是 ts-node,这意味着不再读取 *.ts
文件。
2、加载目录的变化
服务器部署后,只会加载构建后的 dist
目录,而本地开发则是加载 src
目录。
本地 | 服务器 | |
---|---|---|
appDir | 项目根目录 | 项目根目录 |
baseDir | 项目根目录下的 src 目录 | 项目根目录下的 dist 目录 |
3、环境的变化
服务器环境,一般使用 NODE_ENV=production
,很多库都会在这个环境下提供性能更好的方式,例如启用缓存,报错处理等。
4、日志文件
一般服务器环境,日志不再打印到项目的 logs 目录下,而是其他不会受到项目更新影响的目录,比如 home/admin/logs
等等,这样固定的目录,也方便其他工具采集日志。
部署的流程
整个部署分为几个部分,由于 Midway 是 TypeScript 编写,比传统 JavaScript 代码增加了一个构建的步骤,整个部署的过程如下。

由于部署和平台、环境非常相关,下面我们都将以 Linux 来演示,其他平台可以视情况参考。
编译代码和安装依赖
由于 Midway 项目是 TypeScript 编写,在部署前,我们先进行编译。在示例中,我们预先写好了构建脚本,执行 npm run build
即可,如果没有,在 package.json
中添加下面的 build
命令即可。
// package.json
{
"scripts": {
"build": "midway-bin build -c"
}
}
虽然不是必须,但是推荐大家先执行测试和 lint。
一般来说,部署构建的环境和本地开发的环境是两套,我们推荐在一个干净的环境中构建你的应用。
下面 的代码,是一个示例脚本,你可以保存为 build.sh
执行。
## 服务器构建(已经下载好代码)
$ npm install # 安装开发期依赖
$ npm run build # 构建项目
$ npm prune --production # 移除开发依赖
## 本地构建(已经安装好 dev 依赖)
$ npm run build
$ npm prune --production # 移除开发依赖
一般安装依赖会指定 NODE_ENV=production
或 npm install --production
,在构建正式包的时候只安装 dependencies 的依赖。因为 devDependencies 中的模块过大而且在生产环境不会使用,安装后也可能遇到未知问题。
执行完构建后,会出现 Midway 构建产物 dist
目录。
➜ my_midway_app tree
.
├── src
├── dist # Midway 构建产物目录
├── node_modules # Node.js 依赖包目录
├── test
├── package.json
└── tsconfig.json
打包压缩
构建完成后,你可以简单的打包压缩,上传到待发布的环境。
上传和解压
有很多种方式可以上传到服务器,比如常见的 ssh/FTP/git
等。也可以使用 OSS 等在线服务进行中转。
启动方式一:使用纯 Node.js 或者 pm2 等工具启动
Midway 构建出来的项目是单进程的,不管是采用 fork
模式还是 cluster
模式,单进程的代码总是很容易的兼容到不同的体系中,因此非常容易被社区现有的 pm2/forever 等工具所加载,
我们这里以 pm2 来演示如何部署。
项目一般都需要一个入口文件,比如,我们在根目录创建一个 bootstrap.js
作为我们的部署文件。
➜ my_midway_app tree
.
├── src
├── dist # Midway 构建产物目录
├── test
├── bootstrap.js # 部署启动文件
├── package.json
└── tsconfig.json
Midway 提供了一个简单方式以满足不同场景的启动方式,只需要安装我们提供的 @midwayjs/bootstrap
模块。
$ npm install @midwayjs/bootstrap --save
然后在入口文件中写入代码,注意,这里的代码使用的是 JavaScript
。
// 获取框架
const WebFramework = require('@midwayjs/web').Framework;
// 初始化 web 框架并传入启动参数
const web = new WebFramework().configure({
port: 7001,
});
const { Bootstrap } = require('@midwayjs/bootstrap');
// 加载框架并执行
Bootstrap.load(web).run();
我们提供的每个上层框架都将会导出一个 Framework
类,而 Bootstrap
的作用则是加载这些框架,传入启动参数,运行他们。
启动参数,你可以在不同的框架处查询到。
这个时候,你已经可以直接使用 NODE_ENV=production node bootstrap.js
来启动代码了,也可以使用 pm2 来执行启动。
pm2 启动可以参考 pm2 使用文档。
如果你希望把 bootstrap.js
文件放到不同的目录,比如 bin/bootstrap.js
,你可以修改 Bootstrap 的参数。
// bin/bootstrap.js
const { join } = require('path');
// 获取框架
const WebFramework = require('@midwayjs/web').Framework;
// 初始化 web 框架并传入启动参数
const web = new WebFramework().configure({
port: 7001,
});
const { Bootstrap } = require('@midwayjs/bootstrap');
// 加载框架并执行
Bootstrap.configure({
appDir: join(__dirname, '../'),
})
.load(web)
.run();
启动方式二:EggJS 特有的启动形式
由于 EggJS 提供了默认的多进程部署工具 egg-scripts
,Midway 也继续支持这种方式,如果上层是 EggJS,推荐这种部署方式。
首先在依赖中,确保安装 egg-scripts
包和 midway
包。
$ npm i egg-scripts --save
添加 npm scripts
到 package.json
:
在上面的代码构建之后,使用我们的 start
和 stop
命令即可完成启动和停止。
"scripts": {
"start": "egg-scripts start --daemon --title=********* --framework=@midwayjs/web",
"stop": "egg-scripts stop --title=*********",
}
*********
的地方是你的项目名。
注意:
egg-scripts
对 Windows 系统的支持有限,参见 #22。
启动参数
$ egg-scripts start --port=7001 --daemon --title=egg-server-showcase
如上示例,支持以下参数:
--port=7001
端口号,默认会读取环境变量 process.env.PORT,如未传递将使用框架内置端口 7001。--daemon
是否允许在后台模式,无需 nohup。若使用 Docker 建议直接前台运行。--env=prod
框架运行环境,默认会读取环境变量 process.env.EGG_SERVER_ENV, 如未传递将使用框架内置环境 prod。--workers=2
框架 worker 线程数,默认会创建和 CPU 核数相当的 app worker 数,可以充分的利用 CPU 资源。--title=egg-server-showcase
用于方便 ps 进程时 grep 用,默认为egg-server-${appname}
。--framework=yadan
如果应用使用了自定义框架,可以配置 package.json 的 egg.framework 或指定该参数。--ignore-stderr
忽略启动期的报错。--https.key
指定 HTTPS 所需密钥文件的完整路径。--https.cert
指定 HTTPS 所需证书文件的完整路径。- 所有 egg-cluster 的 Options 都支持透传,如 --port 等。
更多参数可查看 egg-scripts 和 egg-cluster 文档。
使用 egg-scripts 部署的日志会存放在 **用户目录 下,**比如 /home/xxxx/logs
。
部署为 Serverless 应用
Midway 可以将现有的 Web 项目部署为 Serverless 应用,这里以部署到阿里云函数计算作为示例。
部署到 Serverless 环境
1、添加 f.yml
文件到你的项目根目录。
➜ my_midway_app tree
.
├── src
├── dist
├── f.yml # Midway Serverless 部署配置文件
├── package.json
└── tsconfig.json
service: my-midway-app ## 应用发布到云平台的名字,一般指应用名
provider:
name: aliyun ## 发布的云平台,aliyun,tencent 等
deployType: egg ## 部署的应用类型
应用类型选项如下:
@midwayjs/web 项目 | egg | |
---|---|---|
@midwayjs/experss 项目 | express | |
@midwayjs/koa 项目 | koa |
2、添加发布时的构建钩子
在 package.json
加入下面的这段,用于在发布时自动执行 npm run build
。
"midway-integration": {
"lifecycle": {
"before:package:cleanup": "npm run build"
}
},
"scripts": {
"deploy": "midway-bin deploy"
},
"egg":{
"framework": "@midwayjs/web"
}
如果使用了自己的 egg 上层框架,这里的 egg.framework 可以变为自己的包名。
3、执行 npm run deploy
即可,发布后,阿里云会输出一个临时可用的域名,打开浏览器访问即可。

如需更详细的发布文档,请查阅 Serverless 发布 FAQ。