ts版的egg的部署报错:nodejs.Error: Please set config.keys first
将项目代码放到服务器上之后,按照egg文档使用命令去启动项目:
npm start
这个时候没有又看到明显的报错信息,以为服务正常启动了,于是我们去随机找了个接口使用 APIPost 工具来测试,结果接口报错了:
Internal Server Error, real status: 500
就很奇葩,于是我们开始排查问题,在服务器上以开发模式启动服务:
npm run dev
可以看到服务正常启动,然后去试接口也是正常的,看样子代码本身没什么问题,应该什么配置没搞对导致的。
然后只能去找错误日志来帮助我们定位问题,项目启动成功后一般会提示出日志保存位置:
...
[egg-ts-helper] create typings/app/controller/index.d.ts (3ms)
[egg-ts-helper] create typings/app/middleware/index.d.ts (1ms)
[egg-ts-helper] create typings/app/model/index.d.ts (1ms)
[egg-ts-helper] create typings/config/index.d.ts (16ms)
[egg-ts-helper] create typings/config/plugin.d.ts (1ms)
[egg-ts-helper] create typings/app/service/index.d.ts (1ms)
[egg-ts-helper] create typings/app/index.d.ts (0ms)
[egg-scripts] Starting egg application at /www/wwwroot/farmer-server
[egg-scripts] Run node --no-deprecation --trace-warnings --require /www/wwwroot/farmer-server/node_modules/egg-scripts/node_modules/source-map-support/register.js /www/wwwroot/farmer-server/node_modules/egg-scripts/lib/start-cluster {"title":"egg-server-farmer-server","baseDir":"/www/wwwroot/farmer-server","framework":"/www/wwwroot/farmer-server/node_modules/egg"} --title=egg-server-farmer-server
[egg-scripts] Save log file to /root/logs
[egg-scripts] Wait Start: 1...
[egg-scripts] egg started on http://127.0.0.1:7001
可以看到当前我们的日志保存在 /root/logs,根据日志可以看到错误信息:nodejs.Error: Please set config.keys first。
奇怪了,我们明明在 config.default.ts 里面配置了对应的key,而且 config.{env}.js 里面定义的属性是覆盖 config.default.ts 的,等于说都合并到config.default.ts里面,不可能未定义的。难道是因为文件是ts的吗?
问题原因
egg.js的文档上 Typescript 教程中有句话:
如果项目需要在线上运行,请先使用 tsc 将 ts 编译成 js ( npm run tsc )再运行 npm start。
其原因在文档中也有说明:
npm start 运行的是 egg-scripts start,而我们只在 egg-bin 中集成了 ts-node,也就是只有在使用 egg-bin 的时候才允许直接运行 ts 。
egg-scripts 是用于在生产环境下运行 egg 的 cli ,在生产环境下我们建议将 ts 编译成 js 之后再运行,毕竟在线上是需要考虑应用的健壮性和性能的,因此不建议在线上环境使用 ts-node 来运行应用。
而在开发期 ts-node 能降低 tsc 编译产生的文件带来的管理成本,并且 ts-node 带来的性能损耗在开发期几乎可以忽略,所以我们在 egg-bin 集成了 ts-node。
文档地址:https://www.eggjs.org/zh-CN/tutorials/typescript#%E9%83%A8%E7%BD%B2deploy
解决办法
在执行 npm start 之前先将 ts 代码编译为 js ,修改 npm start 命令再执行:
// 修改npm start命令
// package.json
...
"script":
{
...
"start": "npm run ci && egg-scripts start --daemon --title=egg-server-farmer-server",
"cov": "egg-bin cov",
"ci": "npm run lint && npm run cov && npm run tsc",
"lint": "eslint . --ext .ts --resolve-plugins-relative-to ."
...
}
``
## 其他部署问题
在修改了 npm start 命令后执行我们还遇到了 eslint 检查错误:
error Expected linebreaks to be 'LF' but found 'CRLF' linebreak-style
解决办法就是找到eslintrc.js文件,在rules下添加以下代码即可解决此问题
{
"extends": "eslint-config-egg/typescript",
"parserOptions": {
"project": "./tsconfig.json"
},
"rules":{
"linebreak-style": [0, "error", "windows"]
}
}
```