本文将会分享,如何从零开始搭建一个基于腾讯云 Serverless 的图片艺术化应用!作者 @蒋启钲
线上 demo 预览:https://art.x96.xyz/ ,项目已开源,完整代码见文末。
在完整阅读文章后,读者应该能够实现并部署一个相同的应用,这也是本篇文章的目标。
项目看点概览:
- 前端 react(Next.js)、后端 node(koa2)
- 全面使用 ts 进行开发,极致开发体验(后端运行时 ts 的方案,虽然性能差点,不过胜在无需编译,适合写 demo)
- 突破云函数代码 500mb 限制(提供解决方案)
- TensorFlow2 + Serverless 扩展想象力边际
- 高性能,轻松应对万级高并发,实现高可用(自信的表情,反正是平台干的活)
- 秒级部署,十秒部署上线
- 开发周期短(本文就能带你完成开发)
本项目部署借助了 Serverless component,因此当前开发环境需先全局安装 Serverless 命令行工具
npm install -g serverless
需求与架构
本应用的整体需求很简单:图片上传与展示。
- 模块概览
- 上传图片
- 浏览图片
用对象存储提供存储服务
在开发之前,我们先创建一个 oss 用于提供图片存储(可以使用你已有的对象存储)
mkdir oss
在新建的 oss 目录下添加 serverless.yml
component: cos
name: xart-oss
app: xart
stage: dev
inputs:
src:
src: ./
exclude:
- .env # 防止密钥被上传
bucket: ${name} # 存储桶名称,如若不添加 AppId 后缀,则系统会自动添加,后缀为大写(xart-oss-<你的appid>)
website: false
targetDir: /
protocol: https
region: ap-guangzhou # 配置区域,尽量配置在和服务同区域内,速度更快
acl:
permissions: public-read # 读写配置为,私有写,共有读
执行 sls deploy 几秒后,你应该就能看到如下提示,表示新建对象存储成功。
这里,我们看到 url
https://art-oss- .cos.ap-guangzhou.myqcloud.com,可以发现默认的命名规则是 https://<名字-appid>.cos.<地域>.myqcloud.com
简单记录一下,在后面服务中会用到,忘记了也不要紧,看看 .env
内 TENCENT_APP_ID
字段(部署后会自动生成 .env)
实现后端服务
新建一个目录并初始化
mkdir art-api && cd art-api && npm init
安装依赖(期望获取 ts 类型提示,请自行安装 @types)
npm i koa @koa/router @koa/cors koa-body typescript ts-node cos-nodejs-sdk-v5 axios dotenv
配置 tsconfig.json
{
"compilerOptions": {
"target": "es2018",
"module": "commonjs",
"lib": ["es2018", "esnext.asynciterable"],
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true
}
}
入口文件 sls.js
require("ts-node").register({ transpileOnly: true }); // 载入 ts 运行时环境,配置忽略类型错误
module.exports = require("./app.ts"); // 直接引入业务逻辑,下面我会和你一起实现
补充两个实用知识点:
node -r
在入口文件中引入 require("ts-node").register({ transpileOnly: true })
实际等同于 node -r ts-node/register/transpile-only
所以 node -r
就是在执行之前载入一些特定模块,利用这个能力,能快速实现对一些功能的支持
比如 node -r esm main.js
通过 esm 模块就能在无需 babel、webpack 的情况下快速 import 与 export 进行模块加载与导出
ts 加载路径
如果不希望用 ../../../../../
来加载模块,那么
- 在 tsconfig.json 中配置
baseUrl: "."
ts-node -r tsconfig-paths/register main.ts
或require("tsconfig-paths").register()
import utils from 'src/utils'
即可愉快地从项目根路径加载模块
下面来实现具体逻辑&#