# CloudBase 云开发

# 准备工作

  1. 安装 CloudBase CLI
npm i -g @cloudbase/cli
1
  1. 测试安装是否成功
tcb -v
1
  1. 查看所有命令
tcb -h
1
  1. 授权登录

    tcb login
    
    1
  2. 项目应用模板 (opens new window)

# CloudBase 基本操作

  1. 基本命令
命令 参数 说明
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)

  1. 通过 {tcb.属性名} 获取配置文件或命令行的值

  2. 通过 .env 类型文件作为主要数据源 通过 {env.属性名} 根据环境获取值

    • .env 默认环境

    • .env.local 本地默认环境

    • 通过 tcb framework deploy --mode development 加载 development 环境的配置文件

      • .env.development 开发阶段配置
      • .env.production 生成环境配置
  3. 总配置项

配置项 类型 描述
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

# 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
  • @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

# Vue 项目开发&上线部署

  1. 运行 tcb new vue-app vue 初始化项目

  2. 运行 npm i 安装依赖

  3. 配置 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
  4. 配置 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
  5. 运行 npm run deploy 一键部署上线

# Egg.js 项目开发&上线部署

  1. 运行 tcb new egg-app egg-starter 初始化项目
  2. 运行 npm i 安装依赖
  3. 运行 npm run deploy 一键部署上线
  4. 基于 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
  1. /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
  1. /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
  1. /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
  1. /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
  1. /app/config/config.default.js 使用中间件 config.middleware = ['responseOption', 'statusRespose']
  2. /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

# 团队开发

  1. 个人中心、访问管理、用户列表、新建用户

  2. 配置权限策略

    • ReadOnlyAccess
    • QcloudAccessForTCBRoleInAccessCloudBaseRun
    • QcloudTCBFullAccess
    • QcloudAccessForTCBRole
  3. VS Code 编辑器插件 Tencent CloudBase Toolkit