目前工作终于不是太忙,可以闲下心做一点新东西,作为一个前端开发者,综合考虑了 express,koa2,egg,nest 等后端框架,最后决定使用 Nest + 腾讯云 Serverless 做一个后端小项目用来入门 nest+typeorm+serverless, 此系列将持续更新,记录过程中遇到的问题及经验。
# 安装 Nest 框架与腾讯云 Serverless Framework
# 安装 Nest
| $ npm i -g @nestjs/cli | |
| $ nest new manager | 
# 安装 Serverless Framework
| $ npm install -g serverless | 
# 在项目根目录创建.env 文件及 serverless.yml 文件
| $ touch .env | |
| $ touch serverless.yml | 
.env 文件主要包含腾讯云 secretKey 和一些项目的全局配置
| # .env | |
| TENCENT_SECRET_ID=AKIDPxxxxxxxxxxxxxxxxxxxxxpNffOq1 | |
| TENCENT_SECRET_KEY=wb091xxxxxxxxxxxxxxxxxxxxxfW7RVI | |
| # 地域可用区配置 | |
| REGION=ap-shanghai | |
| ZONE=ap-shanghai-2 | 
serverless.yml 文件主要包含云函数及网络相关配置 以下是我的配置
| app: manager | |
| stage: dev | |
| component: http | |
| name: manager | |
| inputs: | |
| src: | |
| dist: ./ | |
| hook: npm run build | |
| exclude: | |
|       - .env | |
|       - node_modules | |
| src: ./ | |
| faas: | |
| runtime: Nodejs16.13 | |
| framework: nestjs | |
| name: '${name}-${stage}' | |
| eip: false | |
| timeout: 3 | |
| memorySize: 512 | |
| tags: [] | |
| environments: | |
| - key: MYSQL_HOST | |
| value: 10.0.0.5 | |
| - key: MYSQL_USER | |
| value: serverless | |
| - key: MYSQL_DATABASE | |
| value: manager | |
| - key: MYSQL_PASSWORD | |
| value: managerpassword | |
| vpc: # 私有网络配置 | |
| vpcId: 'vpc-b5776770' | |
| subnetId: 'subnet-asy3z93z' | |
| layers: | |
| - name: manager-layer | |
| version: 1 | |
| apigw: | |
| protocols: | |
|       - http | |
|       - https | |
| timeout: 60 | |
| customDomains: [] | |
| region: ${env:REGION} | 
这里是 《component 为 http 的 yaml 文件配置项》
# 使用 Serverless Framework 部署
首先需要对项目进行一些修改以满足腾讯云 Serverless 的要求
编辑 package.json 添加一些 script
| { | |
| "name": "manager", | |
| "version": "0.0.1", | |
| "description": "", | |
| "author": "", | |
| "private": true, | |
| "license": "MIT", | |
| "scripts": { | |
| "prebuild": "rimraf dist", | |
| "build": "nest build", | |
| "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", | |
| "start": "nest start", | |
| "start:dev": "nest start --watch", | |
| "dev": "nest start --watch", | |
| "start:debug": "nest start --debug --watch", | |
| "start:prod": "node dist/main", | |
| "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", | |
| "test": "jest", | |
| "test:watch": "jest --watch", | |
| "test:cov": "jest --coverage", | |
| "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand", | |
| "test:e2e": "jest --config ./test/jest-e2e.json", | |
| "deploy": "sls deploy", | |
| "remove": "sls remove", | |
| "info": "sls info" | |
| }, | |
| "dependencies": { | |
| "@nestjs/common": "^9.0.11", | |
| "@nestjs/core": "^9.0.11", | |
| "@nestjs/platform-express": "^9.0.11", | |
| "reflect-metadata": "^0.1.13", | |
| "rimraf": "^3.0.2", | |
| "rxjs": "^7.2.0" | |
| }, | |
| "devDependencies": { | |
| "@nestjs/cli": "^9.0.0", | |
| "@nestjs/schematics": "^9.0.0", | |
| "@nestjs/testing": "^9.0.0", | |
| "@types/express": "^4.17.13", | |
| "@types/jest": "28.1.4", | |
| "@types/node": "^16.0.0", | |
| "@types/supertest": "^2.0.11", | |
| "@typescript-eslint/eslint-plugin": "^5.0.0", | |
| "@typescript-eslint/parser": "^5.0.0", | |
| "eslint": "^8.0.1", | |
| "eslint-config-prettier": "^8.3.0", | |
| "eslint-plugin-prettier": "^4.0.0", | |
| "jest": "28.1.2", | |
| "prettier": "^2.3.2", | |
| "source-map-support": "^0.5.20", | |
| "supertest": "^6.1.3", | |
| "ts-jest": "28.0.5", | |
| "ts-loader": "^9.2.3", | |
| "ts-node": "^10.0.0", | |
| "tsconfig-paths": "4.0.0", | |
| "typescript": "^4.3.5" | |
| }, | |
| "jest": { | |
| "moduleFileExtensions": [ | |
| "js", | |
| "json", | |
|       "ts" | |
| ], | |
| "rootDir": "src", | |
| "testRegex": ".*\\.spec\\.ts$", | |
| "transform": { | |
| "^.+\\.(t|j)s$": "ts-jest" | |
| }, | |
| "collectCoverageFrom": [ | |
|       "**/*.(t|j)s" | |
| ], | |
| "coverageDirectory": "../coverage", | |
| "testEnvironment": "node" | |
|   } | |
| } | 
修改 main.ts 将监听 3000 端口改为监听 9000 端口
| import { NestFactory } from '@nestjs/core'; | |
| import { AppModule } from './app.module'; | |
| async function bootstrap() { | |
| const app = await NestFactory.create(AppModule); | |
| await app.listen(9000); | |
| console.log("server listen on 9000!"); | |
| } | |
| bootstrap(); | 
创建启动文件 scf_bootstrap
| #!/bin/bash | |
| SERVERLESS=1 /var/lang/node16/bin/node ./dist/main.js | 
最后执行 sls deploy 进行部署项目,大概 50 多秒就部署完成了,取决于网络速度
| $ sls deploy | |
| serverless ⚡tencent | |
| Action: "deploy" - Stage: "dev" - App: "manager" - Name: "manager" | |
| apigw: | |
| apiList: | |
| - | |
| apiId: api-l764cd57 | |
| apiName: http_api | |
| authType: NONE | |
| businessType: NORMAL | |
|       created:         true | |
| internalDomain: | |
|       isBase64Encoded: false | |
| method: ANY | |
| path: / | |
| url: https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/release/ | |
| environment: release | |
| id: service-mlmh4ts7 | |
| subDomain: service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com | |
| url: https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com/release/ | |
| faas: | |
| name: manager-dev | |
| namespace: default | |
| runtime: Nodejs16.13 | |
| type: web | |
| region: ap-shanghai | |
| sourceCodeDownloadUrl: https://sls-app-code-prod-1300862921.cos.ap-guangzhou.myqcloud.com/1252902543%2Fdev%2Fmanager%2Fmanager%2Fsource.zip?sign=q-sign-algorithm%3Dsha1%26q-ak%3DAKIDfBS1NUcuMcgVSTqzRhiX6lBUbY4KeLXW%26q-sign-time%3D1661312847%3B1661316447%26q-key-time%3D1661312847%3B1661316447%26q-header-list%3Dhost%26q-url-param-list%3D%26q-signature%3D600f78221ddc7718eea6d5959f3049fd918699ec | |
| 应用控制台: https://serverless.cloud.tencent.com/apps/manager/manager/dev | 
打开浏览器访问 https://service-mlmh4ts7-1252902543.sh.apigw.tencentcs.com
如期看到 Hello World!
至此,一个最基本的 Nest 框架就被我们使用腾讯云 Serverless 部署成功了!
