by yugasun from Yugasun.com/post/server…Эта статья может быть воспроизведена полностью, но должны быть сохранены первоначальный автор и источник.
Как фронтенд-разработчик, при выборе серверной службы Nodejs первое, что приходит на ум, этоEgg.js,должен сказатьEgg.js
Это отличный фреймворк корпоративного уровня, его высокая масштабируемость и богатые плагины значительно повышают эффективность разработки. Разработчикам нужно сосредоточиться только на бизнесе, например, на использованииredis
, импортegg-redisПлагин, а затем просто настроить его. Из-за этого я влюбился в него, как только впервые столкнулся с ним, и с тех пор разработал с ним множество приложений.
С такой превосходной структурой, как можетEgg.js
службы перешли наServerless
Архитектурно?
онлайн предварительный просмотр
задний план
я в статьеПолнофункциональное решение на основе бессерверного компонентаописано, как интегрироватьVue.js
интерфейсные приложения и на основеExpress
Серверная служба быстро развертывается в облаке Tencent. Хотя это нравится многим разработчикам, многие разработчики спрашивают меня в частном порядке, это все ещеDemo
Суть проекта только в том, что более практичного решения нет. И в своей реальной разработке многие из них используют точно такие жеEgg.js
рамки, можете ли вы предоставитьEgg.js
решение?
Эта статья научит вас сочетатьEgg.js
а такжеServerless
Внедрите систему фонового управления.
Прочитав эту статью, вы узнаете:
- Основное использование Egg.js
- Как использовать модуль Sequelize ORM для операций Mysql
- Как использовать Редис
- Как использовать JWT для аутентификации пользователя при входе
- Serverless Frameworkосновное использование
- Как развернуть локально разработанное приложение Egg.js в Tencent Cloud Functions
- Как быстро развернуть статичный сайт на базе облачного объектного хранилища
Начало работы с Egg.js
Инициализируйте проект Egg.js:
$ mkdir egg-example && cd egg-example
$ npm init egg --type=simple
$ npm i
Стартовый проект:
$ npm run dev
затем доступ к браузеруhttp://localhost:7001
, вы можете увидеть видhi, egg
.
Для получения дополнительных сведений о структуре Egg.js рекомендуется прочитатьофициальная документация
Подготовить
Имея простое представление о Egg.js, давайте инициализируем нашу систему управления фоном и создадим новый каталог проекта.admin-system
:
$ mkdir admin-system
Скопируйте проект Egg.js, созданный выше, вadmin-system
каталог, переименуйте его вbackend
. Затем скопируйте проект шаблона внешнего интерфейса вfrontend
В папке:
$ git clone https://github.com/PanJiaChen/vue-admin-template.git frontend
проиллюстрировать:vue-admin-templateЭто шаблон системы управления, основанный на Vue 2.0. Это очень отличный проект. Разработчикам, интересующимся Vue.js, рекомендуется изучить его. Конечно, если вы мало знаете о Vue.js, вот основное введение в обучение.Vuejs от входа до мастер-серии статей
После этого структура каталогов вашего проекта выглядит следующим образом:
.
├── README.md
├── backend // 创建的 Egg.js 项目
└── frontend // 克隆的 Vue.js 前端项目模板
Запустите интерфейсный проект и ознакомьтесь со следующим интерфейсом:
$ cd frontend
$ npm install
$ npm run dev
затем посетитеhttp://localhost:9528
Вы можете увидеть интерфейс входа.
Разработка серверных сервисов
Для службы системы фонового управления мы реализуем здесь только функции аутентификации входа и управления статьями, а остальные другие функции аналогичны, и читатели могут свободно дополнять и расширять их позже.
1. Добавьте плагин Sequelize
Перед формальной разработкой нам нужно ввести плагины базы данных, здесь я предпочитаю использоватьSequelizeИнструменты ORM для операций с базами данных, которые предоставляет только Egg.jsegg-sequelizeПлагин, так что он используется напрямую, вам нужно сначала установить его:
$ cd backend
# 因为需要通过 sequelize 链接 mysql 所以这也同时安装 mysql2 模块
$ npm install egg-sequelize mysql2 --save
затем вbackend/config/plugin.js
Введите плагин в:
module.exports = {
// ....
sequelize: {
enable: true,
package: "egg-sequelize"
}
// ....
};
существуетbackend/config/config.default.js
Настройте параметры подключения к базе данных в:
// ...
const userConfig = {
// ...
sequelize: {
dialect: "mysql",
// 这里也可以通过 .env 文件注入环境变量,然后通过 process.env 获取
host: "xxx",
port: "xxx",
database: "xxx",
username: "xxx",
password: "xxx"
}
// ...
};
// ...
2. Добавьте плагин JWT
Система будет использовать токен JWT для аутентификации при входе в систему.Пожалуйста, обратитесь к официальной документации по установке и настройке.egg-jwt
3. Добавьте плагин Redis
Система будет использовать Redis для хранения токенов пользователей и управления ими.Пожалуйста, обратитесь к официальной документации по установке и настройке.egg-redis
4. Ролевой API
определить модель пользователя, создатьbackend/app/model/role.js
Файлы следующие:
module.exports = app => {
const { STRING, INTEGER, DATE } = app.Sequelize;
const Role = app.model.define("role", {
id: { type: INTEGER, primaryKey: true, autoIncrement: true },
name: STRING(30),
created_at: DATE,
updated_at: DATE
});
// 这里定义与 users 表的关系,一个角色可以含有多个用户,外键相关
Role.associate = () => {
app.model.Role.hasMany(app.model.User, { as: "users" });
};
return Role;
};
Реализовать сервисы, связанные с ролью, создатьbackend/app/service/role.js
Файлы следующие:
const { Service } = require("egg");
class RoleService extends Service {
// 获取角色列表
async list(options) {
const {
ctx: { model }
} = this;
return model.Role.findAndCountAll({
...options,
order: [
["created_at", "desc"],
["id", "desc"]
]
});
}
// 通过 id 获取角色
async find(id) {
const {
ctx: { model }
} = this;
const role = await model.Role.findByPk(id);
if (!role) {
this.ctx.throw(404, "role not found");
}
return role;
}
// 创建角色
async create(role) {
const {
ctx: { model }
} = this;
return model.Role.create(role);
}
// 更新角色
async update({ id, updates }) {
const role = await this.ctx.model.Role.findByPk(id);
if (!role) {
this.ctx.throw(404, "role not found");
}
return role.update(updates);
}
// 删除角色
async destroy(id) {
const role = await this.ctx.model.Role.findByPk(id);
if (!role) {
this.ctx.throw(404, "role not found");
}
return role.destroy();
}
}
module.exports = RoleService;
Полный RESTful API должен включать пять вышеуказанных методов, а затем реализовыватьRoleController
, Создайтеbackend/app/controller/role.js
:
const { Controller } = require("egg");
class RoleController extends Controller {
async index() {
const { ctx } = this;
const { query, service, helper } = ctx;
const options = {
limit: helper.parseInt(query.limit),
offset: helper.parseInt(query.offset)
};
const data = await service.role.list(options);
ctx.body = {
code: 0,
data: {
count: data.count,
items: data.rows
}
};
}
async show() {
const { ctx } = this;
const { params, service, helper } = ctx;
const id = helper.parseInt(params.id);
ctx.body = await service.role.find(id);
}
async create() {
const { ctx } = this;
const { service } = ctx;
const body = ctx.request.body;
const role = await service.role.create(body);
ctx.status = 201;
ctx.body = role;
}
async update() {
const { ctx } = this;
const { params, service, helper } = ctx;
const body = ctx.request.body;
const id = helper.parseInt(params.id);
ctx.body = await service.role.update({
id,
updates: body
});
}
async destroy() {
const { ctx } = this;
const { params, service, helper } = ctx;
const id = helper.parseInt(params.id);
await service.role.destroy(id);
ctx.status = 200;
}
}
module.exports = RoleController;
позжеbackend/app/route.js
Определяется в файле конфигурации маршрутизацииrole
REST API:
router.resources("roles", "/roles", controller.role);
пройти черезrouter.resources
метод, мы будемroles
Интерфейс CRUD этого ресурса сопоставлен наapp/controller/roles.js
документ. Ссылка на подробное описаниеофициальная документация
5. Пользовательский API
Определите наш пользовательский API, например роль, мы не будем копировать и вставлять его сюда, вы можете обратиться к исходному коду экземпляра проекта.admin-system.
6. Синхронизируйте таблицы базы данных
Вышеупомянутое просто хорошее определениеRole
а такжеUser
Две схемы, так как синхронизировать с базой данных? Здесь мы сначала используем крючки, запущенные Egg.js, чтобы достичь этого. Платформа Egg.js предоставляет унифицированный файл ввода (app.js) для настройки процесса запуска. Этот файл возвращает класс Boot. Мы можем определить жизненный цикл в методе класса Boot для выполнения работы по инициализации во время запуска приложения.
мы вbackend
каталог созданapp.js
файл следующим образом:
"use strict";
class AppBootHook {
constructor(app) {
this.app = app;
}
async willReady() {
// 这里只能在开发模式下同步数据库表格
const isDev = process.env.NODE_ENV === "development";
if (isDev) {
try {
console.log("Start syncing database models...");
await this.app.model.sync({ logging: console.log, force: isDev });
console.log("Start init database data...");
await this.app.model.query(
"INSERT INTO roles (id, name, created_at, updated_at) VALUES (1, 'admin', '2020-02-04 09:54:25', '2020-02-04 09:54:25'),(2, 'editor', '2020-02-04 09:54:30', '2020-02-04 09:54:30');"
);
await this.app.model.query(
"INSERT INTO users (id, name, password, age, avatar, introduction, created_at, updated_at, role_id) VALUES (1, 'admin', 'e10adc3949ba59abbe56e057f20f883e', 20, 'https://yugasun.com/static/avatar.jpg', 'Fullstack Engineer', '2020-02-04 09:55:23', '2020-02-04 09:55:23', 1);"
);
await this.app.model.query(
"INSERT INTO posts (id, title, content, created_at, updated_at, user_id) VALUES (2, 'Awesome Egg.js', 'Egg.js is a awesome framework', '2020-02-04 09:57:24', '2020-02-04 09:57:24', 1),(3, 'Awesome Serverless', 'Build web, mobile and IoT applications using Tencent Cloud and API Gateway, Tencent Cloud Functions, and more.', '2020-02-04 10:00:23', '2020-02-04 10:00:23', 1);"
);
console.log("Successfully init database data.");
console.log("Successfully sync database models.");
} catch (e) {
console.log(e);
throw new Error("Database migration failed.");
}
}
}
}
module.exports = AppBootHook;
пройти черезwillReady
Функции жизненного цикла, которые мы можем выполнитьthis.app.model.sync()
функция для синхронизации таблицы данных, конечно, роль и пользовательские записи данных инициализируются здесь для демонстрационных целей.
Примечание. Эта синхронизация базы данных предназначена только для локальной отладки. Если вам нужна база данных Mysql от Tencent Cloud, рекомендуется открыть удаленное подключение через
sequelize db:migrate
Вместо того, чтобы синхронизировать каждый раз при запуске приложения Egg, пример кода уже выполнил эту функцию,Обратитесь к документации Egg Sequelize.. Здесь, чтобы избежать проблем, я напрямую открываю общедоступное сетевое соединение Tencent Cloud Mysql, а затем изменяюconfig.default.js
серединаsequelize
настроить, запуститьnpm run dev
Синхронизировать режим разработки.
На данный момент наши пользовательские и ролевые API определены, запустите службуnpm run dev
,доступhttps://127.0.0.1:7001/users
Теперь можно получить список всех пользователей.
7. API входа/выхода пользователей
Логика входа здесь относительно проста, клиент отправляет用户名
а также密码
прибыть/login
маршрутизация, бэкэнд черезlogin
Функция принимает, а затем запрашивает имя пользователя из базы данных, и заодно сравнивает, верен ли пароль. Если правильно то звонитеapp.jwt.sign()
генерация функцийtoken
, и воляtoken
депозит вredis
, возвращая этоtoken
, то клиент должен аутентифицировать запрос будет нестиtoken
, чтобы выполнить проверку подлинности. Идея проста, и мы приступаем к ее реализации.
Блок-схема выглядит следующим образом:
Первый вbackend/app/controller/home.js
Добавлена обработка входа вlogin
метод:
class HomeController extends Controller {
// ...
async login() {
const { ctx, app, config } = this;
const { service, helper } = ctx;
const { username, password } = ctx.request.body;
const user = await service.user.findByName(username);
if (!user) {
ctx.status = 403;
ctx.body = {
code: 403,
message: "Username or password wrong"
};
} else {
if (user.password === helper.encryptPwd(password)) {
ctx.status = 200;
const token = app.jwt.sign(
{
id: user.id,
name: user.name,
role: user.role.name,
avatar: user.avatar
},
config.jwt.secret,
{
expiresIn: "1h"
}
);
try {
await app.redis.set(`token_${user.id}`, token);
ctx.body = {
code: 0,
message: "Get token success",
token
};
} catch (e) {
console.error(e);
ctx.body = {
code: 500,
message: "Server busy, please try again"
};
}
} else {
ctx.status = 403;
ctx.body = {
code: 403,
message: "Username or password wrong"
};
}
}
}
}
Примечание: здесь есть логика хранения пароля, когда пользователь регистрируется, пароль передается через
helper
функцияencryptPwd()
Для шифрования (здесь используется простейший метод шифрования md5, в реальной разработке рекомендуется использовать более продвинутый метод шифрования), поэтому при проверке правильности пароля его тоже нужно один раз зашифровать. Что касается того, как добавить новые элементы в структуру Egg.jshelper
функция, просто нужноbackend/app/extend
новый в папкеhelper.js
файл, затемmodole.exports
Подойдет объект, содержащий функцию, см.Документация по расширению Egg Framework
Затем вbackend/app/controller/home.js
новое вuserInfo
способ получения информации о пользователе:
async userInfo() {
const { ctx } = this;
const { user } = ctx.state;
ctx.status = 200;
ctx.body = {
code: 0,
data: user,
};
}
egg-jwtПлагин в функции контроллера, соответствующей маршруту, прошедшему аутентификацию, будетapp.jwt.sign(user, secrete)
Зашифрованная информация о пользователе, добавленная вctx.state.user
, такuserInfo
Функция просто должна вернуть его.
После этого вbackend/app/controller/home.js
новое вlogout
метод:
async logout() {
const { ctx } = this;
ctx.status = 200;
ctx.body = {
code: 0,
message: 'Logout success',
};
}
userInfo
а такжеlogout
Функция очень проста, основное внимание уделяется тому, как ее обрабатывает промежуточное ПО маршрутизации.
Далее давайте определим маршруты, связанные с входом в систему, изменимbackend/app/router.js
файл, добавить/login
, /user-info
, /logout
Три маршрута:
const koajwt = require("koa-jwt2");
module.exports = app => {
const { router, controller, jwt } = app;
router.get("/", controller.home.index);
router.post("/login", controller.home.login);
router.get("/user-info", jwt, controller.home.userInfo);
const isRevokedAsync = function(req, payload) {
return new Promise(resolve => {
try {
const userId = payload.id;
const tokenKey = `token_${userId}`;
const token = app.redis.get(tokenKey);
if (token) {
app.redis.del(tokenKey);
}
resolve(false);
} catch (e) {
resolve(true);
}
});
};
router.post(
"/logout",
koajwt({
secret: app.config.jwt.secret,
credentialsRequired: false,
isRevoked: isRevokedAsync
}),
controller.home.logout
);
router.resources("roles", "/roles", controller.role);
router.resources("users", "/users", controller.user);
router.resources("posts", "/posts", controller.post);
};
Когда платформа Egg.js определяет маршруты,router.post()
Функция может принимать функции промежуточного программного обеспечения для обработки некоторой специальной логики, связанной с маршрутизацией.
Например/user-info
, маршрут добавленapp.jwt
Как функция промежуточного программного обеспечения аутентификации JWT, почему она используется,egg-jwtПлагины имеют четкие инструкции.
Здесь немного сложнее/logout
route, потому что при выходе из системы и входе в систему нам нужно преобразоватьtoken
отredis
удалено из , так что вот помощьkoa-jwt2изisRevokded
параметры, выполнитьtoken
удалять.
Развертывание серверной службы
На этом логика входа и выхода из серверной службы в основном завершена. Итак, как выполнить развертывание в облачных функциях? можно использовать напрямуюtencent-eggComponent, который представляет собой бессерверный компонент, специально созданный для платформы Egg.js. С его помощью мы можем быстро развернуть наш проект Egg.js в Tencent Cloud Functions.
1. Подготовьте
Давайте создадимbackend/sls.js
Входной файл:
const { Application } = require("egg");
const app = new Application();
module.exports = app;
затем изменитьbackend/config/config.default.js
документ:
const config = (exports = {
env: "prod", // 推荐云函数的 egg 运行环境变量修改为 prod
rundir: "/tmp",
logger: {
dir: "/tmp"
}
});
Примечание. Все, что необходимо изменить в каталогах операций и журналов, связано с тем, что при работе облачной функции
/tmp
иметь разрешение на запись.
Установить глобальноserverless
Заказ:
$ npm install serverless -g
2. Настройте бессерверное
Создан в корневом каталоге проектаserverless.yml
файл, при добавленииbackend
Конфигурация:
backend:
component: "@serverless/tencent-egg"
inputs:
code: ./backend
functionName: admin-system
# 这里必须指定一个具有操作 mysql 和 redis 的角色,具体角色创建,可访问 https://console.cloud.tencent.com/cam/role
role: QCS_SCFFull
functionConf:
timeout: 120
# 这里的私有网络必须和 mysql、redis 实例一致
vpcConfig:
vpcId: vpc-xxx
subnetId: subnet-xxx
apigatewayConf:
protocols:
- https
На данный момент структура каталогов вашего проекта выглядит следующим образом:
.
├── README.md // 项目说明文件
├── serverless.yml // serverless yml 配合文件
├── backend // 创建的 Egg.js 项目
└── frontend // 克隆的 Vue.js 前端项目模板
3. Выполните развертывание
Выполните команду развертывания:
$ serverless --debug
После этого консоль должна отсканировать код для входа в систему, чтобы подтвердить учетную запись Tencent Cloud, просто отсканируйте код для входа. После успешного развертывания отобразится следующая информация:
backend:
region: ap-guangzhou
functionName: admin-system
apiGatewayServiceId: service-f1bhmhk4
url: https://service-f1bhmhk4-1251556596.gz.apigw.tencentcs.com/release/
Выходной URL-адрес здесь — это успешно развернутый интерфейс шлюза API, к которому можно получить прямой доступ для тестирования.
Примечание. При развертывании облачной функции служба будет автоматически создана в шлюзе API Tencent Cloud, и в то же время будет создан API, с помощью которого можно запустить выполнение облачной функции.
4. Настройка учетной записи (необязательно)
В настоящее время по умолчанию поддерживается безсерверный клиентский интерфейс для сканирования QR-кода для входа в систему. Если вы хотите настроить постоянные переменные среды/ключевую информацию, вы также можете создать их в корневом каталоге проекта..env
документ
существует.env
Настройте и сохраните информацию SecretId и SecretKey Tencent Cloud в файле. Ключ можно найти вУправление ключами APIПолучить или создать из .
# .env
TENCENT_SECRET_ID=123
TENCENT_SECRET_KEY=123
5. API статьи
Подобно пользовательскому API, вам нужно только скопировать и вставить указанные выше модули, связанные с пользователем, и изменить имя наposts
, и измените модель данных, поэтому я не буду вставлять сюда код.
Фронтенд разработка
используется непосредственно в этом примереvue-admin-templateфронтальный шаблон.
Нам необходимо внести следующие изменения:
- Удалите насмешку над интерфейсом: замените его реальным интерфейсом серверной службы.
- Изменить функции интерфейса: в том числе связанные с пользователем
frontend/src/api/user.js
Интерфейсы, связанные со статьямиfrontend/src/api/post.js
. - Измените функцию интерфейса. Функция: в основном для модификации
frontend/src/utils/request.js
документы, в том числеaxios
просилbaseURL
и заголовки запроса. - Модификация интерфейса пользовательского интерфейса: в основном для добавления страниц управления статьями, включая страницы списков и новые страницы.
1. Удалить симуляцию интерфейса
сначала удалитьfrontend/mock
папка. Затем измените файл записи внешнего интерфейсаfrontend/src/main.js
:
// 1. 引入接口变量文件,这个会依赖 @serverless/tencent-website 组件自动生成
import "./env.js";
import Vue from "vue";
import "normalize.css/normalize.css";
import ElementUI from "element-ui";
import "element-ui/lib/theme-chalk/index.css";
import locale from "element-ui/lib/locale/lang/en";
import "@/styles/index.scss";
import App from "./App";
import store from "./store";
import router from "./router";
import "@/icons";
import "@/permission";
// 2. 下面这段就是 mock server 引入,删除就好
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
Vue.use(ElementUI, { locale });
Vue.config.productionTip = false;
new Vue({
el: "#app",
router,
store,
render: h => h(App)
});
2. Изменить функцию интерфейса
Исправлятьfrontend/src/api/user.js
Файл, включая вход в систему, выход из системы, получение информации о пользователе и получение списка пользователей, выглядит следующим образом:
import request from "@/utils/request";
// 登录
export function login(data) {
return request({
url: "/login",
method: "post",
data
});
}
// 获取用户信息
export function getInfo(token) {
return request({
url: "/user-info",
method: "get"
});
}
// 注销登录
export function logout() {
return request({
url: "/logout",
method: "post"
});
}
// 获取用户列表
export function getList() {
return request({
url: "/users",
method: "get"
});
}
новыйfrontend/src/api/post.js
Файлы следующие:
import request from "@/utils/request";
// 获取文章列表
export function getList(params) {
return request({
url: "/posts",
method: "get",
params
});
}
// 创建文章
export function create(data) {
return request({
url: "/posts",
method: "post",
data
});
}
// 删除文章
export function destroy(id) {
return request({
url: `/posts/${id}`,
method: "delete"
});
}
3. Изменить функцию инструмента интерфейса
потому что@serverless/tencent-website
Компоненты могут быть определеныenv
параметр, после успешного выполнения он будет указан вroot
Автоматически созданный каталогenv.js
, затем вfrontend/src/main.js
Введен в эксплуатацию.
он будет монтироватьсяenv
Переменные интерфейса, определенные в towindow
на объекте. такие, как это сгенерированоenv.js
Файлы следующие:
window.env = {};
window.env.apiUrl =
"https://service-f1bhmhk4-1251556596.gz.apigw.tencentcs.com/release/";
По этому файлу будем модифицироватьfrontend/src/utils/request.js
документ:
import axios from "axios";
import { MessageBox, Message } from "element-ui";
import store from "@/store";
import { getToken } from "@/utils/auth";
// 创建 axios 实例
const service = axios.create({
// 1. 这里设置为 `env.js` 中的变量 `window.env.apiUrl`
baseURL: window.env.apiUrl || "/", // url = base url + request url
timeout: 5000 // request timeout
});
// request 注入
service.interceptors.request.use(
config => {
// 2. 添加鉴权token
if (store.getters.token) {
config.headers["Authorization"] = `Bearer ${getToken()}`;
}
return config;
},
error => {
console.log(error); // for debug
return Promise.reject(error);
}
);
// 请求 response 注入
service.interceptors.response.use(
response => {
const res = response.data;
// 只有请求code为0,才是正常返回,否则需要提示接口错误
if (res.code !== 0) {
Message({
message: res.message || "Error",
type: "error",
duration: 5 * 1000
});
if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// to re-login
MessageBox.confirm(
"You have been logged out, you can cancel to stay on this page, or log in again",
"Confirm logout",
{
confirmButtonText: "Re-Login",
cancelButtonText: "Cancel",
type: "warning"
}
).then(() => {
store.dispatch("user/resetToken").then(() => {
location.reload();
});
});
}
return Promise.reject(new Error(res.message || "Error"));
} else {
return res;
}
},
error => {
console.log("err" + error);
Message({
message: error.message,
type: "error",
duration: 5 * 1000
});
return Promise.reject(error);
}
);
export default service;
4. Модификация пользовательского интерфейса
Что касается модификации интерфейса пользовательского интерфейса, я не буду объяснять это здесь, потому что это включает в себя базовое использование Vue.js.Если вы не знаете, как использовать Vue.js, рекомендуется сначала скопировать пример кода. Если вы заинтересованы в Vue.js, вы можете перейти наОфициальный сайт Vue.jsУчить. Вы также можете прочитать мой собственныйVuejs от входа до мастер-серии статей, если хотите, вы можете отправить свой драгоценныйStar (*^▽^*)
Просто скопируйте сюдаИсходный код демоизfrontend/router
а такжеfrontend/views
Две папки - это нормально.
Интерфейсное развертывание
Поскольку интерфейс представляет собой все статические файлы после компиляции, нам необходимо загрузить статические файлы в службу COS (хранилище объектов) Tencent Cloud, а затем включить функцию статического веб-сайта COS. Это не требует ручного управления, использовать@serverless/tencent-websiteкомпоненты могут быть легко сделаны.
1. Измените файл конфигурации Serverless
Изменить корневой каталог проектаserverless.yml
файл, добавьте конфигурацию, связанную с внешним интерфейсом:
name: admin-system
# 前端配置
frontend:
component: "@serverless/tencent-website"
inputs:
code:
src: dist
root: frontend
envPath: src # 相对于 root 指定目录,这里实际就是 frontend/src
hook: npm run build
env:
# 依赖后端部署成功后生成的 url
apiUrl: ${backend.url}
protocol: https
# TODO: CDN 配置,请修改!!!
hosts:
- host: sls-admin.yugasun.com # CDN 加速域名
https:
certId: abcdedg # 为加速域名在腾讯云平台申请的免费证书 ID
http2: off
httpsType: 4
forceSwitch: -2
# 后端配置
backend:
component: "@serverless/tencent-egg"
inputs:
code: ./backend
functionName: admin-system
role: QCS_SCFFull
functionConf:
timeout: 120
vpcConfig:
vpcId: vpc-6n5x55kb
subnetId: subnet-4cvr91js
apigatewayConf:
protocols:
- https
2. Выполните развертывание
Выполните команду развертывания:
$ serverless --debug
Выводятся следующие успешные результаты:
frontend:
url: https://dtnu69vl-470dpfh-1251556596.cos-website.ap-guangzhou.myqcloud.com
env:
apiUrl: https://service-f1bhmhk4-1251556596.gz.apigw.tencentcs.com/release/
host:
- https://sls-admin.yugasun.com (CNAME: sls-admin.yugasun.com.cdn.dnsv1.com)
backend:
region: ap-guangzhou
functionName: admin-system
apiGatewayServiceId: service-f1bhmhk4
url: https://service-f1bhmhk4-1251556596.gz.apigw.tencentcs.com/release/
Примечания: здесь
frontend
Средний выходhost
, — это имя нашего домена ускорения CDN, которое можно настроить с помощью@serverless/tencent-website
компонентinputs.hosts
реализовать. Инструкции по настройке CDN см.Полнофункциональное решение на основе Serverless Component — продолжение. Конечно, если вы не хотите настраивать CDN, просто удалите его и посетите статический URL-адрес веб-сайта, сгенерированный COS.
После успешного развертывания мы можем получить доступhttps://sls-admin.yugasun.com
Войдите, чтобы испытать.
исходный код
Весь исходный код, задействованный в этой статье, поддерживается в проектах с открытым исходным кодом.tencent-serverless-demoсерединаadmin-system
Суммировать
Эта статья включает в себя много контента, рекомендуется читать и развивать во время чтения, и следовать ритму статьи, чтобы реализовать ее шаг за шагом. Если у вас возникнут проблемы, вы можете обратиться к исходному коду этой статьи. Если вы успешно внедрили его, вы можете перейти на официальный сайт для дальнейшего ознакомления с фреймворком Egg.js, чтобы в будущем реализовать более сложные приложения. Хотя в этой статье используется интерфейсная среда Vue.js, вы также можете использоватьfrontend
Замените его любым проектом front-end framework, который вам нравится, вам нужно только использовать префикс запроса интерфейса при разработке@serverless/tencent-website
сгенерированный компонентenv.js
файл подойдет.
Если вы находитесь в разработке и хотите найти отличный Serverless Component, но не знаете, где его найти, вы можете собрать проекты с открытым исходным кодом, которые я поддерживаю и обновляю в течение длительного времени.awesome-serverless-framework.