# CloudBase
云开发
# 准备工作
- 安装
CloudBase CLI
npm i -g @cloudbase/cli
1
- 测试安装是否成功
tcb -v
1
- 查看所有命令
tcb -h
1
授权登录
左上角点击 新建 按钮 创建新环境
- 应用模板 选择 空模板
- 地域 选择 广州
- 计费方式 (opens new window) 选择 按量计费 后期改为 包年包月
- 新用户有 一个月 的免费体验期 (opens new window)
本地命令行 授权登录云开发环境
tcb login
1
# CloudBase
基本操作
- 基本命令
命令 | 参数 | 说明 |
---|---|---|
Login | [options] | 登录腾讯云账号 |
logout | 登出腾讯云账号 | |
env | [cmd] | 环境管理操作 |
fn | [cmd] | 操作函数 |
framework | [cmd] | 云开发 Serverless 应用框架操作 |
hosting | [cmd] | 静态托管资源管理操作 |
new | [appName] [template] | 创建新的云开发应用 |
open | [link] | 在浏览器中打开云开发相关连接 |
storage | [cmd] | 云存储资源管理操作 |
service | [cmd] | HTTP 访问服务管理操作 |
# cloudbaserc.json
云开发配置文件 (opens new window)
通过
{tcb.属性名}
获取配置文件或命令行的值通过
.env
类型文件作为主要数据源 通过{env.属性名}
根据环境获取值.env
默认环境.env.local
本地默认环境通过
tcb framework deploy --mode development
加载development
环境的配置文件.env.development
开发阶段配置.env.production
生成环境配置
总配置项
配置项 | 类型 | 描述 |
---|---|---|
version | String | 当前配置文件的版本 2.0 |
envId | String | 环境ID |
region | String | 当前环境的地域信息 |
functionRoot | String | 云函数函数代码存放的文件夹路径 |
functions | Array | 函数配置项组成的数组 |
framework | Object | 腾讯云配置 (opens new window) |
{
"version": "2.0",
"envId": "MelonEnv",
"region": "ap-shanghai",
"$schema": "https://framework-1258016615.tcloudbaseapp.com/schema/latest.json",
"functionRoot": "./functions",
"functions": []
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
# CloudBase Framework
插件
@cloudbase/framework-plugin-website
静态网站部署
配置项 | 描述 |
---|---|
installCommand | 安装命令 |
buildCommand | 构建命令 |
outputPath | 网站静态文件的路径 |
cloudPath | 静态资源部署到云开发环境的路径 |
ignore | 部署时忽略文件 |
envVariables | 环境变量键值对 通过 window._tcbEnv 获取 |
{
"framework": {
"name": "melon-vue",
"plugins": {
"client": {
"use": "@cloudbase/framework-plugin-website",
"inputs": {
"installCommand": "npm install --prefer-offline --no-audit --progress=false",
"buildCommand": "npm run build",
"outputPath": "dist",
"cloudPath": "/vue",
"ignore": [
".git",
"node_modules",
"cloudbaserc.js"
],
"envVariables": {
"TCB_SERVICE_DOMAIN": "https://node.rickychan.cn",
"TCB_ENV_ID": "MelonEnv",
"TCB_REGION": "ap-shanghai"
}
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@cloudbase/framework-plugin-function
云函数
配置项 | 描述 |
---|---|
functionRootPath | 函数根目录 |
publishIncludeList | 只发布列表中的函数 f1,f2 |
functionDefaultConfig | 云函数默认配置 |
servicePaths | 服务路径配置 |
配置项 | 类型 | 描述 |
---|---|---|
name | String | 云函数名称 |
handler | String | 函数处理方法名称 |
params | Object | 调用云函数时的函数入参 |
triggers | Array | 触发器配置(定时器) (opens new window) |
timeout | Number | 函数超时时间 |
envVariables | Object | 环境变量的键值对对象 |
vpc | VPC | 私有网络配置 |
runtime | String | 环境配置 |
memorySize | Number | 函数内存 |
ignore | Array | 忽略文件 |
installDependency | Boolean | 是否云端安装依赖 |
codeSecret | String | 代码加密 |
{
"framework": {
"name": "melon-egg",
"plugins": {
"function": {
"use": "@cloudbase/framework-plugin-function",
"inputs": {
"functionRootPath": "./functions",
"functionDefaultConfig": {
"timeout": 10,
"ignore": [
"*.md",
"node_modules"
],
"installDependency": true,
"vpc": {
"vpcId": "vpc-xxx",
"subnetId": "subnet-xxx"
}
},
"functions": [
{
"name": "vuepressFn1",
"handler": "melon.fn1",
"envVariables": {
"name": "melon",
"age": 21
},
"triggers": [
{
"name": "myTrigger",
"type": "timer",
"config": "0 0 2 1 * * *"
}
]
}
]
}
}
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Vue
项目开发&上线部署
运行
tcb new vue-app vue
初始化项目运行
npm i
安装依赖配置
VueRouter
运行
npm i vue-router -S
安装路由在
app
文件夹里面新建views
文件夹、router
文件夹 和index.js
在
index.js
编写路由
import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) const routes = [ { path: '/', name: 'Index', component: () => import('@/views/Index.vue'), } ] const router = new VueRouter({ routes, }) export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18- 在
main.js
加载路由
import router from './router' new Vue({ router, render: h => h(App) }).$mount("#app");
1
2
3
4
5
6配置
Vuex
运行
npm i vuex -S
安装状态管理在
app
文件夹里面新建store
文件夹和index.js
在
index.js
编写
import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: {}, mutations: {}, actions: {} })
1
2
3
4
5
6
7
8
9
10- 在
main.js
加载
import store from './store' new Vue({ router, store, render: h => h(App) }).$mount("#app");
1
2
3
4
5
6
7运行
npm run deploy
一键部署上线
# Egg.js
项目开发&上线部署
- 运行
tcb new egg-app egg-starter
初始化项目 - 运行
npm i
安装依赖 - 运行
npm run deploy
一键部署上线 - 基于
RESTful
风格编写路由 (opens new window)
module.exports = app => {
const { router, controller } = app;
const preRouter = '/api';
router.resources('/users', preRouter + '/users', controller.users);
};
1
2
3
4
5
2
3
4
5
- 在
/app/utils/resModel.js
定义统一返回格式
'use strict';
/**
* 200 成功
* 204 OPTIONS请求返回
* 400 缺少必要参数
* 401 缺少权限
* 404 地址错误或者请求方式不对
* 409 操作失败
*/
const baseModel = (data = [], msg, code) => {
(typeof data === 'string') && ([msg, data] = [data, (typeof msg === 'string') ? [] : msg]);
return { code, msg, data };
};
const _success = (data, msg = '成功操作') => {
return baseModel(data, msg, 200);
};
const _pass = (data, msg = '允许请求') => {
return baseModel(data, msg, 204);
};
const _lack = (data, msg = '缺少参数') => {
(typeof data === 'string') && (data = `${data}参数格式不正确`);
return baseModel(data, msg, 400);
};
const _notLogin = (data, msg = 'token已过期,请重新登录!') => {
return baseModel(data, msg, 401);
};
const _notFound = (data, msg = '地址错误或者请求方式不对') => {
return baseModel(data, msg, 404);
};
const _error = (data, msg = '操作失败') => {
return baseModel(data, msg, 409);
};
module.exports = { _success, _pass, _lack, _notLogin, _notFound, _error };
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
- 在
/app/extend/response.js
引入
'use strict';
const { _success, _notFound, _error, _lack, _notLogin, _pass } = require('../utils/resModel.js');
module.exports = {
_success, _pass, _lack, _notLogin, _notFound, _error,
};
1
2
3
4
5
6
2
3
4
5
6
- 在
/app/middleware/statusRespose.js
处理返回格式
'use strict';
module.exports = () => async function statusRespose(ctx, next) {
await next();
if (ctx.body.code === 400) {
console.log(ctx.body);
ctx.body.msg = `缺少${ctx.body.data.errors.reduce((pre, ele) => pre += ele.field + ',', '').slice(0, -1)}参数`;
ctx.body.data = [];
}
(ctx.body) || (ctx.body = ctx.response._notFound());
ctx.body.code && (ctx.status = ctx.body.code);
};
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 在
/app/middleware/responseOption.js
处理POST
的预请求
'use strict';
module.exports = () => async function responseOption(ctx, next) {
if (ctx.method === 'OPTIONS') {
ctx.body = ctx.response._pass();
} else {
await next();
}
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
- 在
/app/config/config.default.js
使用中间件config.middleware = ['responseOption', 'statusRespose']
- 在
/app/controller/users.js
处理路由请求和检测参数 (opens new window)
'use strict';
const Controller = require('egg').Controller;
class UserController extends Controller {
async index() {
this.ctx.body = this.ctx.response._success(await this.ctx.service.users.show());
}
}
module.exports = UserController;
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 团队开发
个人中心、访问管理、用户列表、新建用户
配置权限策略
ReadOnlyAccess
QcloudAccessForTCBRoleInAccessCloudBaseRun
QcloudTCBFullAccess
QcloudAccessForTCBRole
VS Code
编辑器插件 Tencent CloudBase Toolkit