diff --git a/.gitignore b/.gitignore
index f37c1a6..20761d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,4 +20,4 @@ build/
env.js
package-lock.json
test
-yarn.lock
\ No newline at end of file
+yarn.lock
diff --git a/.travis.yml b/.travis.yml
index b9f070c..d78fad9 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,6 @@
language: node_js
node_js:
- - 8
- 10
install:
@@ -18,5 +17,7 @@ jobs:
deploy:
provider: script
skip_cleanup: true
+ on:
+ branch: master
script:
- npm run release
diff --git a/README.md b/README.md
index 5aa5161..f9a495b 100644
--- a/README.md
+++ b/README.md
@@ -1,100 +1,110 @@
-[![Serverless Components](https://img.serverlesscloud.cn/2020210/1581352135771-express.png)](http://serverless.com)
+# Serverless Nest.js
-
+**腾讯云 Nest.js 组件** ⎯⎯⎯ 通过使用 [Serverless Framework](https://github.com/serverless/components/tree/cloud),基于云上 Serverless 服务(如网关、云函数等),实现“0”配置,便捷开发,极速部署你的 Nest.js 应用。
-**腾讯云 Express 组件** ⎯⎯⎯ 通过使用 [Tencent Serverless Framework](https://github.com/serverless/components/tree/cloud),基于云上 Serverless 服务(如网关、云函数等),实现“0”配置,便捷开发,极速部署你的 express 应用,Express 组件支持丰富的配置扩展,提供了目前最易用、低成本并且弹性伸缩的 Experss 项目开发/托管能力。
-
+> 注意:本项目仅支持使用 [ExpressAdapter](https://docs.nestjs.com/faq/http-adapter) 的 Nest.js 项目。
-特性介绍:
+### 安装
-- [x] **按需付费** - 按照请求的使用量进行收费,没有请求时无需付费
-- [x] **"0"配置** - 只需要关心项目代码,之后部署即可,Serverless Framework 会搞定所有配置。
-- [x] **极速部署** - 仅需几秒,部署你的整个 express 应用。
-- [x] **实时日志** - 通过实时日志的输出查看业务状态,便于直接在云端开发应用。
-- [x] **云端调试** - 针对 Node.js 框架支持一键云端调试能力,屏蔽本地环境的差异。
-- [x] **便捷协作** - 通过云端的状态信息和部署日志,方便的进行多人协作开发。
-- [x] **自定义域名** - 支持配置自定义域名及 HTTPS 访问
+通过 npm 安装最新版本的 Serverless Framework
-
+```bash
+$ npm install -g serverless
+```
-
+### 创建
-快速开始:
+通过如下命令和模板链接,快速创建一个 Nest.js 应用:
-1. [**安装**](#1-安装)
-2. [**创建**](#2-创建)
-3. [**部署**](#3-部署)
-4. [**配置**](#4-配置)
-5. [**开发调试**](#5-开发调试)
-6. [**查看状态**](#6-查看状态)
-7. [**移除**](#7-移除)
+```bash
+$ npm i -g @nestjs/cli
+$ nest new serverless-nestjs
+$ cd serverless-nestjs
+```
-更多资源:
+执行如下命令,安装应用的对应依赖
-- [**架构说明**](#架构说明)
-- [**账号配置**](#账号配置)
+```
+$ npm install
+```
-
+### 项目改造
-### 1. 安装
+1. 由于云端函数执行时不需要监听端口的,所以我们需要修改下入口文件 `src/main.ts`,如下:
-通过 npm 安装最新版本的 Serverless Framework
+```typescript
+import { NestFactory } from '@nestjs/core'
+import { join } from 'path'
+import { AppModule } from './app.module'
-```bash
-$ npm install -g serverless
-```
+async function bootstrap() {
+ const app = await NestFactory.create(AppModule)
-### 2. 创建
+ return app
+}
-通过如下命令和模板链接,快速创建一个 express 应用:
+// 注意: 通过注入 NODE_ENV 为 local,来方便本地启动服务,进行开发调试
+const isLocal = process.env.NODE_ENV === 'local'
+if (isLocal) {
+ bootstrap().then((app) => {
+ app.listen(3000, () => {
+ console.log(`Server start on http://localhost:3000`)
+ })
+ })
+}
-```bash
-$ serverless create --template-url https://github.com/serverless-components/tencent-express/tree/v2/serverless-express
-$ cd serverless-express
+// 导出启动函数,给 sls.js 使用
+export { bootstrap }
```
-执行如下命令,安装 express 应用的对应依赖
+2. 项目根目录下新增 `sls.js` 文件,用来提供给 Nest.js 组件使用:
+```js
+// 注意: 根据实际项目入口文件名进行修改,此 demo 为默认情况
+const { bootstrap } = require('./dist/main')
+
+module.exports = bootstrap
```
-$ npm install
-```
-### 3. 部署
+> 注意:实际开发可根据个人项目路径,来导出启动函数 `bootstrap`。
+
+### 部署
-在 `serverless.yml` 文件下的目录中运行 `serverless deploy` 进行 express 项目的部署。第一次部署可能耗时相对较久,但后续的二次部署会在几秒钟之内完成。部署完毕后,你可以在命令行的输出中查看到你 express 应用的 URL 地址,点击地址即可访问你的 express 项目。
+由于 Nest.js 项目是 TypeScript,部署前需要编译成 JavaScript,在项目中执行编译命令即可:
-**注意:**
+```bash
+$ npm run build
+```
-如您的账号未[登陆](https://cloud.tencent.com/login)或[注册](https://cloud.tencent.com/register)腾讯云,您可以直接通过`微信`扫描命令行中的二维码进行授权登陆和注册。
+在 `serverless.yml` 文件下的目录中运行 `serverless deploy` 进行 Nest.js 项目的部署。第一次部署可能耗时相对较久,但后续的二次部署会在几秒钟之内完成。部署完毕后,你可以在命令行的输出中查看到你 nestjs 应用的 URL 地址,点击地址即可访问你的 Nest.js 项目。
-如果出现了 `internal server error` 的报错,请检查是否在创建模板后没有运行 `npm install`。
+> **注意:** 如您的账号未 [登录](https://cloud.tencent.com/login) 或 [注册](https://cloud.tencent.com/register) 腾讯云,您可以直接通过 `微信` 扫描命令行中的二维码进行授权登陆和注册。
如果希望查看更多部署过程的信息,可以通过`sls deploy --debug` 命令查看部署过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。
-
-
-### 4. 配置
+### 配置
-Express 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 Express 项目。
+nestjs 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 nestjs 项目。
-以下是 Express 组件的 `serverless.yml`完整配置说明:
+以下是 nestjs 组件的 `serverless.yml` 简单配置示例:
```yml
# serverless.yml
-component: express # (required) name of the component. In that case, it's express.
-name: expressDemo # (required) name of your express component instance.
+component: nestjs # (required) name of the component. In that case, it's nestjs.
+name: nestjsDemo # (required) name of your nestjs component instance.
org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup.
app: appDemo # (optional) serverless dashboard app. default is the same as the name property.
stage: dev # (optional) serverless dashboard stage. default is dev.
inputs:
- src: ./ # (optional) path to the source folder. default is a hello world app.
- functionName: expressDemo
+ src:
+ src: ./ # (optional) path to the source folder. default is a hello world app.
+ exclude:
+ - .env
+ functionName: nestjsDemo
region: ap-guangzhou
runtime: Nodejs10.15
- exclude:
- - .env
apigatewayConf:
protocols:
- http
@@ -102,13 +112,13 @@ inputs:
environment: release
```
-点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-express/blob/v2/docs/configure.md)
+点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-nestjs/tree/master/docs/configure.md)
当你根据该配置文件更新配置字段后,再次运行 `serverless deploy` 或者 `serverless` 就可以更新配置到云端。
-### 5. 开发调试
+### 远程调试云函数
-部署了 Express.js 应用后,可以通过开发调试能力对该项目进行二次开发,从而开发一个生产应用。在本地修改和更新代码后,不需要每次都运行 `serverless deploy` 命令来反复部署。你可以直接通过 `serverless dev` 命令对本地代码的改动进行检测和自动上传。
+部署了 nestjs.js 应用后,可以通过开发调试能力对该项目进行二次开发,从而开发一个生产应用。在本地修改和更新代码后,不需要每次都运行 `serverless deploy` 命令来反复部署。你可以直接通过 `serverless dev` 命令对本地代码的改动进行检测和自动上传。
可以通过在 `serverless.yml`文件所在的目录下运行 `serverless dev` 命令开启开发调试能力。
@@ -116,7 +126,7 @@ inputs:
除了实时日志输出之外,针对 Node.js 应用,当前也支持云端调试能力。在开启 `serverless dev` 命令之后,将会自动监听远端端口,并将函数的超时时间临时配置为 900s。此时你可以通过访问 chrome://inspect/#devices 查找远端的调试路径,并直接对云端代码进行断点等调试。在调试模式结束后,需要再次部署从而将代码更新并将超时时间设置为原来的值。详情参考[开发模式和云端调试](https://cloud.tencent.com/document/product/1154/43220)。
-### 6. 查看状态
+### 查看状态
在`serverless.yml`文件所在的目录下,通过如下命令查看部署状态:
@@ -124,9 +134,9 @@ inputs:
$ serverless info
```
-### 7. 移除
+### 移除
-在`serverless.yml`文件所在的目录下,通过以下命令移除部署的 Express 服务。移除后该组件会对应删除云上部署时所创建的所有相关资源。
+在`serverless.yml`文件所在的目录下,通过以下命令移除部署的 nestjs 服务。移除后该组件会对应删除云上部署时所创建的所有相关资源。
```
$ serverless remove
@@ -134,16 +144,6 @@ $ serverless remove
和部署类似,支持通过 `sls remove --debug` 命令查看移除过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。
-## 架构说明
-
-Express 组件将在腾讯云账户中使用到如下 Serverless 服务:
-
-- [x] **API 网关** - API 网关将会接收外部请求并且转发到 SCF 云函数中。
-- [x] **SCF 云函数** - 云函数将承载 Express.js 应用。
-- [x] **CAM 访问控制** - 该组件会创建默认 CAM 角色用于授权访问关联资源。
-- [x] **COS 对象存储** - 为确保上传速度和质量,云函数压缩并上传代码时,会默认将代码包存储在特定命名的 COS 桶中。
-- [x] **SSL 证书服务** - 如果你在 yaml 文件中配置了 `apigatewayConf.customDomains` 字段,需要做自定义域名绑定并开启 HTTPS 时,也会用到证书管理服务和域名服务。Serverless Framework 会根据已经备案的域名自动申请并配置 SSL 证书。
-
## 账号配置
当前默认支持 CLI 扫描二维码登录,如您希望配置持久的环境变量/秘钥信息,也可以本地创建 `.env` 文件
diff --git a/docs/configure.md b/docs/configure.md
index 14a7eca..969ec4a 100644
--- a/docs/configure.md
+++ b/docs/configure.md
@@ -5,15 +5,15 @@
```yml
# serverless.yml
-component: express # (必选) 组件名称,在该实例中为express
-name: expressDemo # 必选) 组件实例名称.
+component: nestjs # (必选) 组件名称,在该实例中为nestjs
+name: nestjsDemo # 必选) 组件实例名称.
org: orgDemo # (可选) 用于记录组织信息,默认值为您的腾讯云账户 appid,必须为字符串
app: appDemo # (可选) 用于记录组织信息. 默认与name相同,必须为字符串
stage: dev # (可选) 用于区分环境信息,默认值是 dev
inputs:
region: ap-guangzhou # 云函数所在区域
- functionName: expressDemo # 云函数名称
+ functionName: nestjsDemo # 云函数名称
serviceName: mytest # api网关服务名称
runtime: Nodejs10.15 # 运行环境
serviceId: service-np1uloxw # api网关服务ID
@@ -32,19 +32,22 @@ inputs:
version: 1 # 版本
functionConf: # 函数配置相关
timeout: 10 # 超时时间,单位秒
+ eip: false # 是否固定出口IP
memorySize: 128 # 内存大小,单位MB
environment: # 环境变量
variables: # 环境变量数组
TEST: vale
vpcConfig: # 私有网络配置
- subnetId: '' # 私有网络的Id
- vpcId: '' # 子网ID
+ vpcId: '' # 私有网络的Id
+ subnetId: '' # 子网ID
apigatewayConf: # api网关配置
isDisabled: false # 是否禁用自动创建 API 网关功能
enableCORS: true # 允许跨域
customDomains: # 自定义域名绑定
- domain: abc.com # 待绑定的自定义的域名
certificateId: abcdefg # 待绑定自定义域名的证书唯一 ID
+ # 如要设置自定义路径映射,请设置为 false
+ isDefaultMapping: false
# 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。
pathMappingSet:
- path: /
@@ -56,13 +59,13 @@ inputs:
- http
- https
environment: test
+ serviceTimeout: 15
usagePlan: # 用户使用计划
usagePlanId: 1111
usagePlanName: slscmp
usagePlanDesc: sls create
maxRequestNum: 1000
auth: # 密钥
- serviceTimeout: 15
secretName: secret
secretIds:
- xxx
@@ -74,15 +77,13 @@ inputs:
| 参数名称 | 是否必选 | 默认值 | 描述 |
| ------------------------------------ | :------: | :-------------: | :------------------------------------------------------------------ |
-| runtime | 否 | Nodejs10.15 | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 |
-| region | 否 | ap-guangzhou | 项目部署所在区域,默认广州区 |
+| runtime | 否 | `Nodejs10.15` | 执行环境, 目前支持: Nodejs6.10, Nodejs8.9, Nodejs10.15, Nodejs12.16 |
+| region | 否 | `ap-guangzhou` | 项目部署所在区域,默认广州区 |
| functionName | 否 | | 云函数名称 |
| serviceName | 否 | | API 网关服务名称, 默认创建一个新的服务名称 |
| serviceId | 否 | | API 网关服务 ID,如果存在将使用这个 API 网关服务 |
| src | 否 | `process.cwd()` | 默认为当前目录, 如果是对象, 配置参数参考 [执行目录](#执行目录) |
| layers | 否 | | 云函数绑定的 layer, 配置参数参考 [层配置](#层配置) |
-| exclude | 否 | | 不包含的文件 |
-| include | 否 | | 包含的文件, 如果是相对路径,是相对于 `serverless.yml`的路径 |
| [functionConf](#函数配置) | 否 | | 函数配置 |
| [apigatewayConf](#API-网关配置) | 否 | | API 网关配置 |
| [cloudDNSConf](#DNS-配置) | 否 | | DNS 配置 |
@@ -90,12 +91,12 @@ inputs:
## 执行目录
-| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
-| -------- | :------: | :-------------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| src | 否 | String | | 代码路径。与 object 不能同时存在。 |
-| exclude | 否 | Array of String | | 不包含的文件或路径, 遵守 [glob 语法](https:# github.com/isaacs/node-glob) |
-| bucket | 否 | String | | bucket 名称。如果配置了 src,表示部署 src 的代码并压缩成 zip 后上传到 bucket-appid 对应的存储桶中;如果配置了 object,表示获取 bucket-appid 对应存储桶中 object 对应的代码进行部署。 |
-| object | 否 | String | | 部署的代码在存储桶中的路径。 |
+| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
+| -------- | :------: | :------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| src | 否 | String | | 代码路径。与 object 不能同时存在。 |
+| exclude | 否 | String[] | | 不包含的文件或路径, 遵守 [glob 语法](https://github.com/isaacs/node-glob) |
+| bucket | 否 | String | | bucket 名称。如果配置了 src,表示部署 src 的代码并压缩成 zip 后上传到 bucket-appid 对应的存储桶中;如果配置了 object,表示获取 bucket-appid 对应存储桶中 object 对应的代码进行部署。 |
+| object | 否 | String | | 部署的代码在存储桶中的路径。 |
## 层配置
@@ -106,11 +107,11 @@ inputs:
### DNS 配置
-参考: https:# cloud.tencent.com/document/product/302/8516
+参考: https://cloud.tencent.com/document/product/302/8516
| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
| ---------- | :------: | -------- | :----: | :---------------------------------------------- |
-| ttl | 否 | Number | 600 | TTL 值,范围 1 - 604800,不同等级域名最小值不同 |
+| ttl | 否 | Number | `600` | TTL 值,范围 1 - 604800,不同等级域名最小值不同 |
| recordLine | 否 | String[] | | 记录的线路名称 |
### 指定区配置
@@ -119,18 +120,18 @@ inputs:
| ------------------------------- | :------: | ------ | ------ | ------------ |
| [functionConf](#函数配置) | 否 | Object | | 函数配置 |
| [apigatewayConf](#API-网关配置) | 否 | Object | | API 网关配置 |
-| [cloudDNSConf](#DNS-配置) | 否 | Object | | DNS 配置 |
### 函数配置
-参考: https:# cloud.tencent.com/document/product/583/18586
+参考: https://cloud.tencent.com/document/product/583/18586
-| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
-| ----------- | :------: | :----: | :----: | :------------------------------------------------------------------------------ |
-| timeout | 否 | Number | 3 | 函数最长执行时间,单位为秒,可选值范围 1-900 秒,默认为 3 秒 |
-| memorySize | 否 | Number | 128 | 函数运行时内存大小,默认为 128M,可选范围 64、128MB-3072MB,并且以 128MB 为阶梯 |
-| environment | 否 | Object | | 函数的环境变量, 参考 [环境变量](#环境变量) |
-| vpcConfig | 否 | Object | | 函数的 VPC 配置, 参考 [VPC 配置](#VPC-配置) |
+| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
+| ----------- | :------: | :-----: | :-----: | :------------------------------------------------------------------------------ |
+| timeout | 否 | Number | `3` | 函数最长执行时间,单位为秒,可选值范围 1-900 秒,默认为 3 秒 |
+| memorySize | 否 | Number | `128` | 函数运行时内存大小,默认为 128M,可选范围 64、128MB-3072MB,并且以 128MB 为阶梯 |
+| environment | 否 | Object | | 函数的环境变量, 参考 [环境变量](#环境变量) |
+| vpcConfig | 否 | Object | | 函数的 VPC 配置, 参考 [VPC 配置](#VPC-配置) |
+| eip | 否 | Boolean | `false` | 是否固定出口 IP |
##### 环境变量
@@ -147,30 +148,31 @@ inputs:
### API 网关配置
-| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
-| ------------ | :------: | :------- | :------- | :--------------------------------------------------------------------------------- |
-| protocols | 否 | String[] | ['http'] | 前端请求的类型,如 http,https,http 与 https |
-| environment | 否 | String | release | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). |
-| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) |
-| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) |
-| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) |
-| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 |
-| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 |
+| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
+| -------------- | :------: | :------- | :--------- | :--------------------------------------------------------------------------------- |
+| protocols | 否 | String[] | `['http']` | 前端请求的类型,如 http,https,http 与 https |
+| environment | 否 | String | `release` | 发布环境. 目前支持三种发布环境: test(测试), prepub(预发布) 与 release(发布). |
+| usagePlan | 否 | | | 使用计划配置, 参考 [使用计划](#使用计划) |
+| auth | 否 | | | API 密钥配置, 参考 [API 密钥](#API-密钥配置) |
+| customDomain | 否 | Object[] | | 自定义 API 域名配置, 参考 [自定义域名](#自定义域名) |
+| enableCORS | 否 | Boolean | `false` | 开启跨域。默认值为否。 |
+| serviceTimeout | 否 | Number | `15` | Api 超时时间,单位: 秒 |
+| isDisabled | 否 | Boolean | `false` | 关闭自动创建 API 网关功能。默认值为否,即默认自动创建 API 网关。 |
##### 使用计划
-参考: https:# cloud.tencent.com/document/product/628/14947
+参考: https://cloud.tencent.com/document/product/628/14947
| 参数名称 | 是否必选 | 类型 | 描述 |
| ------------- | :------: | ------ | :------------------------------------------------------ |
| usagePlanId | 否 | String | 用户自定义使用计划 ID |
| usagePlanName | 否 | String | 用户自定义的使用计划名称 |
| usagePlanDesc | 否 | String | 用户自定义的使用计划描述 |
-| maxRequestNum | 否 | Int | 请求配额总数,如果为空,将使用-1 作为默认值,表示不开启 |
+| maxRequestNum | 否 | Number | 请求配额总数,如果为空,将使用-1 作为默认值,表示不开启 |
##### API 密钥配置
-参考: https:# cloud.tencent.com/document/product/628/14916
+参考: https://cloud.tencent.com/document/product/628/14916
| 参数名称 | 类型 | 描述 |
| ---------- | :----- | :------- |
@@ -179,15 +181,15 @@ inputs:
##### 自定义域名
-Refer to: https:# cloud.tencent.com/document/product/628/14906
+Refer to: https://cloud.tencent.com/document/product/628/14906
-| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
-| ---------------- | :------: | :------: | :------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| domain | 是 | String | | 待绑定的自定义的域名。 |
-| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 https,则为必选 |
-| isDefaultMapping | 否 | String | `'TRUE'` | 是否使用默认路径映射,默认为 TRUE。为 FALSE 时,表示自定义路径映射,此时 pathMappingSet 必填。 |
-| pathMappingSet | 否 | Object[] | `[]` | 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 |
-| protocol | 否 | String[] | | 绑定自定义域名的协议类型,默认与服务的前端协议一致。 |
+| 参数名称 | 是否必选 | 类型 | 默认值 | 描述 |
+| ---------------- | :------: | :------: | :----: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| domain | 是 | String | | 待绑定的自定义的域名。 |
+| certificateId | 否 | String | | 待绑定自定义域名的证书唯一 ID,如果设置了 type 为 https,则为必选 |
+| isDefaultMapping | 否 | String | `true` | 是否使用默认路径映射。为 false 时,表示自定义路径映射,此时 pathMappingSet 必填。 |
+| pathMappingSet | 否 | Object[] | `[]` | 自定义路径映射的路径。使用自定义映射时,可一次仅映射一个 path 到一个环境,也可映射多个 path 到多个环境。并且一旦使用自定义映射,原本的默认映射规则不再生效,只有自定义映射路径生效。 |
+| protocol | 否 | String[] | | 绑定自定义域名的协议类型,默认与服务的前端协议一致。 |
- 自定义路径映射
diff --git a/example/.prettierrc b/example/.prettierrc
new file mode 100644
index 0000000..dcb7279
--- /dev/null
+++ b/example/.prettierrc
@@ -0,0 +1,4 @@
+{
+ "singleQuote": true,
+ "trailingComma": "all"
+}
\ No newline at end of file
diff --git a/example/README.md b/example/README.md
index f9101bc..d85b505 100644
--- a/example/README.md
+++ b/example/README.md
@@ -1,75 +1,171 @@
-
A progressive Node.js framework for building efficient and scalable server-side applications, heavily inspired by Angular.
- - - -## Description - -[Nest](https://github.com/nestjs/nest) framework TypeScript starter repository. - -## Installation +# Serverless Nest.js + +**腾讯云 Nest.js 组件** ⎯⎯⎯ 通过使用 [Serverless Framework](https://github.com/serverless/components/tree/cloud),基于云上 Serverless 服务(如网关、云函数等),实现“0”配置,便捷开发,极速部署你的 Nest.js 应用。 + +> 注意:本项目仅支持使用 [ExpressAdapter](https://docs.nestjs.com/faq/http-adapter) 的 Nest.js 项目。 + +### 安装 + +通过 npm 安装最新版本的 Serverless Framework ```bash -$ npm install +$ npm install -g serverless ``` -## Running the app +### 创建 + +通过如下命令和模板链接,快速创建一个 Nest.js 应用: ```bash -# development -$ npm run start +$ npm i -g @nestjs/cli +$ nest new serverless-nestjs +$ cd serverless-nestjs +``` + +执行如下命令,安装应用的对应依赖 + +``` +$ npm install +``` + +### 项目改造 + +1. 由于云端函数执行时不需要监听端口的,所以我们需要修改下入口文件 `src/main.ts`,如下: -# watch mode -$ npm run start:dev +```typescript +import { NestFactory } from '@nestjs/core'; +import { join } from 'path'; +import { AppModule } from './app.module'; -# production mode -$ npm run start:prod +async function bootstrap() { + const app = await NestFactory.create(AppModule); + + return app; +} + +// TODO: 通过注入 NODE_ENV 为 local,来方便本地启动服务,进行开发调试 +const isLocal = process.env.NODE_ENV === 'local'; +if (isLocal) { + bootstrap().then(app => { + app.listen(3000, () => { + console.log(`Server start on http://localhost:3000`); + }); + }); +} + +// 导出启动函数,给 sls.js 使用 +export { bootstrap }; +``` + +2. 项目根目录下新增 `sls.js` 文件,用来提供给 Nest.js 组件使用: + +```js +// 注意: 根据实际项目入口文件名进行修改,此 demo 为默认情况 +const { bootstrap } = require('./dist/main'); + +module.exports = bootstrap; ``` -## Test +> 注意:实际开发可根据个人项目路径,来导出启动函数 `bootstrap`。 + +### 部署 + +由于 Nest.js 项目是 TypeScript,部署前需要编译成 JavaScript,在项目中执行编译命令即可: ```bash -# unit tests -$ npm run test +$ npm run build +``` + +在 `serverless.yml` 文件下的目录中运行 `serverless deploy` 进行 Nest.js 项目的部署。第一次部署可能耗时相对较久,但后续的二次部署会在几秒钟之内完成。部署完毕后,你可以在命令行的输出中查看到你 nestjs 应用的 URL 地址,点击地址即可访问你的 Nest.js 项目。 + +> **注意:** 如您的账号未 [登录](https://cloud.tencent.com/login) 或 [注册](https://cloud.tencent.com/register) 腾讯云,您可以直接通过 `微信` 扫描命令行中的二维码进行授权登陆和注册。 + +如果希望查看更多部署过程的信息,可以通过`sls deploy --debug` 命令查看部署过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 + +### 配置 -# e2e tests -$ npm run test:e2e +nestjs 组件支持 0 配置部署,也就是可以直接通过配置文件中的默认值进行部署。但你依然可以修改更多可选配置来进一步开发该 nestjs 项目。 + +以下是 nestjs 组件的 `serverless.yml` 简单配置示例: + +```yml +# serverless.yml + +component: nestjs # (required) name of the component. In that case, it's nestjs. +name: nestjsDemo # (required) name of your nestjs component instance. +org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup. +app: appDemo # (optional) serverless dashboard app. default is the same as the name property. +stage: dev # (optional) serverless dashboard stage. default is dev. + +inputs: + src: + src: ./ # (optional) path to the source folder. default is a hello world app. + exclude: + - .env + functionName: nestjsDemo + region: ap-guangzhou + runtime: Nodejs10.15 + apigatewayConf: + protocols: + - http + - https + environment: release +``` + +点此查看[全量配置及配置说明](https://github.com/serverless-components/tencent-nestjs/tree/master/docs/configure.md) + +当你根据该配置文件更新配置字段后,再次运行 `serverless deploy` 或者 `serverless` 就可以更新配置到云端。 + +### 远程调试云函数 + +部署了 nestjs.js 应用后,可以通过开发调试能力对该项目进行二次开发,从而开发一个生产应用。在本地修改和更新代码后,不需要每次都运行 `serverless deploy` 命令来反复部署。你可以直接通过 `serverless dev` 命令对本地代码的改动进行检测和自动上传。 + +可以通过在 `serverless.yml`文件所在的目录下运行 `serverless dev` 命令开启开发调试能力。 + +`serverless dev` 同时支持实时输出云端日志,每次部署完毕后,对项目进行访问,即可在命令行中实时输出调用日志,便于查看业务情况和排障。 + +除了实时日志输出之外,针对 Node.js 应用,当前也支持云端调试能力。在开启 `serverless dev` 命令之后,将会自动监听远端端口,并将函数的超时时间临时配置为 900s。此时你可以通过访问 chrome://inspect/#devices 查找远端的调试路径,并直接对云端代码进行断点等调试。在调试模式结束后,需要再次部署从而将代码更新并将超时时间设置为原来的值。详情参考[开发模式和云端调试](https://cloud.tencent.com/document/product/1154/43220)。 + +### 查看状态 + +在`serverless.yml`文件所在的目录下,通过如下命令查看部署状态: -# test coverage -$ npm run test:cov ``` +$ serverless info +``` + +### 移除 + +在`serverless.yml`文件所在的目录下,通过以下命令移除部署的 nestjs 服务。移除后该组件会对应删除云上部署时所创建的所有相关资源。 + +``` +$ serverless remove +``` + +和部署类似,支持通过 `sls remove --debug` 命令查看移除过程中的实时日志信息,`sls`是 `serverless` 命令的缩写。 -## Support +## 账号配置 -Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please [read more here](https://docs.nestjs.com/support). +当前默认支持 CLI 扫描二维码登录,如您希望配置持久的环境变量/秘钥信息,也可以本地创建 `.env` 文件 -## Stay in touch +```console +$ touch .env # 腾讯云的配置信息 +``` + +在 `.env` 文件中配置腾讯云的 SecretId 和 SecretKey 信息并保存 -- Author - [Kamil Myśliwiec](https://kamilmysliwiec.com) -- Website - [https://nestjs.com](https://nestjs.com/) -- Twitter - [@nestframework](https://twitter.com/nestframework) +如果没有腾讯云账号,可以在此[注册新账号](https://cloud.tencent.com/register)。 + +如果已有腾讯云账号,可以在[API 密钥管理](https://console.cloud.tencent.com/cam/capi)中获取 `SecretId` 和`SecretKey`. + +``` +# .env +TENCENT_SECRET_ID=123 +TENCENT_SECRET_KEY=123 +``` ## License -Nest is [MIT licensed](LICENSE). +MIT License + +Copyright (c) 2020 Tencent Cloud, Inc. diff --git a/example/handler.js b/example/handler.js deleted file mode 100644 index 5812c23..0000000 --- a/example/handler.js +++ /dev/null @@ -1,26 +0,0 @@ -// require('tencent-component-monitor') -const fs = require('fs') -const path = require('path') -const { createServer, proxy } = require('tencent-serverless-http') - -let server -const createApp = require('./dist/main') - -exports.handler = async (event, context) => { - const app = await createApp() - // cache server, not create repeatly - if (!server) { - server = createServer(app, null, app.binaryTypes || []) - } - - context.callbackWaitsForEmptyEventLoop = - app.callbackWaitsForEmptyEventLoop === true ? true : false - - // provide sls intialize hooks - if (app.slsInitialize && typeof app.slsInitialize === 'function') { - await app.slsInitialize() - } - - const result = await proxy(server, event, context, 'PROMISE') - return result.promise -} diff --git a/example/package.json b/example/package.json index 89d68c1..26ee5bb 100644 --- a/example/package.json +++ b/example/package.json @@ -1,5 +1,5 @@ { - "name": "nest-demo", + "name": "nestjs-demo", "version": "0.0.1", "description": "", "author": "", @@ -9,16 +9,10 @@ "prebuild": "rimraf dist", "build": "nest build", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix", "start": "NODE_ENV=local nest start", "start:dev": "NODE_ENV=local nest start --watch", - "start:debug": "NODE_ENV=local nest start --debug --watch", - "start:prod": "NODE_ENV=local 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" + "start:debug": "NODE_ENV=local nest start --debug --watch" }, "dependencies": { "@nestjs/common": "^7.0.0", @@ -27,28 +21,27 @@ "hbs": "^4.1.1", "reflect-metadata": "^0.1.13", "rimraf": "^3.0.2", - "rxjs": "^6.5.4", - "tencent-serverless-http": "^1.2.0" + "rxjs": "^6.5.4" }, "devDependencies": { "@nestjs/cli": "^7.0.0", "@nestjs/schematics": "^7.0.0", "@nestjs/testing": "^7.0.0", "@types/express": "^4.17.3", - "@types/jest": "25.2.3", + "@types/jest": "26.0.10", "@types/node": "^13.9.1", "@types/supertest": "^2.0.8", - "@typescript-eslint/eslint-plugin": "3.0.2", - "@typescript-eslint/parser": "3.0.2", - "eslint": "7.1.0", + "@typescript-eslint/eslint-plugin": "3.9.1", + "@typescript-eslint/parser": "3.9.1", + "eslint": "7.7.0", "eslint-config-prettier": "^6.10.0", "eslint-plugin-import": "^2.20.1", - "jest": "26.0.1", + "jest": "26.4.2", "prettier": "^1.19.1", "supertest": "^4.0.2", - "ts-jest": "26.1.0", + "ts-jest": "26.2.0", "ts-loader": "^6.2.1", - "ts-node": "^8.6.2", + "ts-node": "9.0.0", "tsconfig-paths": "^3.9.0", "typescript": "^3.7.4" }, diff --git a/example/serverless.yml b/example/serverless.yml index 9eae45b..7509a44 100644 --- a/example/serverless.yml +++ b/example/serverless.yml @@ -1,18 +1,19 @@ -org: orgDemo # (optional) serverless dashboard org. default is the first org you created during signup. -app: appDemo # (optional) serverless dashboard app. default is the same as the name property. -stage: dev # (optional) serverless dashboard stage. default is dev. -component: express # (required) name of the component. In that case, it's express. -name: expressDemo # (required) name of your express component instance. +app: appDemo +org: orgDemo +stage: dev +component: nestjs +name: nestjsDemo inputs: src: - src: ./ # (optional) path to the source folder. default is a hello world app. + src: ./ exclude: - .env - region: ap-guangzhou - runtime: Nodejs10.15 - apigatewayConf: - protocols: - - http - - https - environment: release + - 'test/**' + # functionConf: + # timeout: 10 + # memorySize: 128 + # apigatewayConf: + # protocols: + # - http + # - https diff --git a/example/sls.js b/example/sls.js index 195d143..b5e8fc9 100644 --- a/example/sls.js +++ b/example/sls.js @@ -1,3 +1,4 @@ -const createServer = require('./dist/main') +// Notice: change filename to your real project entry filename +const { bootstrap } = require('./dist/main'); -module.exports = createServer +module.exports = bootstrap; diff --git a/example/src/main.ts b/example/src/main.ts index 6932a51..0af609a 100644 --- a/example/src/main.ts +++ b/example/src/main.ts @@ -1,41 +1,25 @@ import { NestFactory } from '@nestjs/core'; -import { - NestExpressApplication, - ExpressAdapter, -} from '@nestjs/platform-express'; +import { NestExpressApplication } from '@nestjs/platform-express'; import { join } from 'path'; -import * as express from 'express'; import { AppModule } from './app.module'; -// -const createServerlessApp = async (): Promise