共计 6667 个字符,预计需要花费 17 分钟才能阅读完成。
DevUI 是一支兼具设计视角和工程视角的团队,服务于华为云 DevCloud 平台和华为外部数个中后盾零碎,服务于设计师和前端工程师。
官方网站:devui.design
Ng 组件库:ng-devui(欢送 Star)
官网交换群:增加 DevUI 小助手(微信号:devui-official)
DevUIHelper 插件:DevUIHelper-LSP(欢送 Star)
前言
之前发过一个沸点,聊到前端为了晋升业务交付效率,有必要去除对上游的依赖,这次想给大家分享下我本人在去后盾依赖方面的一些实际,欢送大家一起探讨!
前端依赖后盾什么?
在整个研发链路上,后盾的定位是给前端提供高效、稳固的 API 接口,前端通过这些 API 去获取须要的数据,并展现给用户。
所以要去除对后盾的依赖,前端就须要本人模仿这些接口,并结构相应的测试数据。
怎么模仿后盾接口?
为了在前端模仿后盾接口,我给大家介绍第一件神器:JSON Server。
以下是 JSON Server 官网对本人的定位:
Get a full fake REST API with zero coding in less than 30 seconds (seriously)
无需写代码,在 30 秒内取得残缺的 REST API。
以我当初负责的 DevCloud 业务——XBoard 看板我的项目——举栗子,有一个接口是获取某个看板上面的所有卡片信息(只保留关键字段),接口根本协定如下(接口协议提前跟后盾协商好):
GET /v1/[projectid]/[boardid]/cards
{
"error": null,
"status": "success",
"result": [
{
"column_id": "7c489b6746fe4329aa8c869f4c13fab5",
"card_list": [
{
"id": "4634045604195569664", // 卡片 ID
"subject": "工作已 ready, 筹备启动开发的工作", // 卡片主题
"sequence": "11203427", // 卡片序列号
"index": "12", // 序号(用于拖动排序)"archived": false, // 是否已归档
"blocked": false, // 是否设置阻塞
"is_parent": false, // 是否父卡片
"createdOn": "1598238210463", // 创立工夫
"updatedOn": "1598238210463", // 最近更新工夫
"parent": { // 父卡片
"subject": "设计实现, 正在进行开发的需要",
"id": "4634045604190851072"
},
"board": { // 卡片所在的看板
"id": "1661625c5f72471a81979482ab148066",
"name": "开发"
},
"column": { // 状态列
"id": "7c489b6746fe4329aa8c869f4c13fab5",
"name": "就绪",
"type": "READY",
"deleted": false
},
"card_type": { // 卡片类型
"color": "#6CBFFF",
"name": "工作",
"icon": "icon-op-task",
"id": "2"
},
"author": { // 卡片作者
"name": "kagolzeng",
"id": "05329882ba000f711ffec00c21191097",
"nick_name": "kagol",
"gender": "male"
},
"updater": { // 最近更新者
"name": "kagolzeng",
"id": "05329882ba000f711ffec00c21191097",
"nick_name": "kagol",
"gender": "male"
}
},
... // 其余卡片
]
},
... // 其余状态列
]
}
这个接口怎么用 JSON Server 模仿呢?
只须要以下 4 步(假如曾经有我的项目工程,比方:NG CLI 工程):
- 第 1 步:装置 JSON Server
- 第 2 步:配置测试数据
- 第 3 步:编写启动脚本命令
- 第 4 步:启动 Mock 服务
咱们一步一步来搭建一个 Mock 服务:
第 1 步:装置 JSON Server
在我的项目根目录下执行以下命令:
npm i -D json-server
第 2 步:配置测试数据
在我的项目根目录下新建 db.json 文件,加上之前曾经跟后盾定好的接口数据(为防止反复,已省略局部字段):
{
"result": [
{
"column_id": "7c489b6746fe4329aa8c869f4c13fab5",
"card_list": [
{
"id": "4634045604195569664", // 卡片 ID
"subject": "工作已 ready, 筹备启动开发的工作", // 卡片主题
"board": { // 卡片所在的看板
"id": "1661625c5f72471a81979482ab148066",
"name": "开发"
},
"column": { // 状态列
"id": "7c489b6746fe4329aa8c869f4c13fab5",
"name": "就绪",
"type": "READY",
"deleted": false
},
"card_type": { // 卡片类型
"color": "#6CBFFF",
"name": "工作",
"icon": "icon-op-task",
"id": "2"
}
}
]
}
]
}
第 3 步:编写启动脚本命令
只须要在 package.json 的 scripts 中编写 Mock 服务的启动脚本即可:
"mock": "node_modules/.bin/json-server --watch db.json --port 9090"
第 4 步:启动 Mock 服务
npm run mock
启动之后控制台显示:
在浏览器地址栏输出:http://localhost:9090/cards,即可查看该接口的返回数据
如何结构测试数据?
大家发现以上模仿后盾接口的形式有什么问题了没?
测试数据的结构太麻烦!
如果每个接口的返回数据都须要一个一个去结构,至多会有两个问题:
- 一是每条记录都本人手写,太累,数据也太死;
- 二是想要模仿大量的数据很难,且会导致我的项目源文件体积变大。
为了解决以上问题,我要给大家介绍第二件神器:Mock.js。
Mock.js 对本人的定位是:
生成随机数据,拦挡 Ajax 申请
Mock.js 能够生成简直任何你能想到的数据类型,比方数字、字符、布尔值、日期、色彩、图片、地址、URL、名字、题目、段落等,甚至还反对正则表达式。
将 Mock.js 集成进来也只须要简略的 3 个步骤:
- 第 1 步:批改 JSON Server 配置
- 第 2 步:批改脚本命令
- 第 3 步:重启 Mock 服务
第 1 步:批改 JSON Server 配置
为了集成 Mock.js,咱们须要将之前的 db.json 改成 db.js,并减少 routes.json 文件,能够将这两个文件放到根目录下的 mock 文件夹下。
mock/db.js
var Mock = require('mockjs');
const CARDS = Mock.mock({
"error": null,
"status": "success",
"result|10": [{ // 生成 10 个状态列
"column_id": "@guid",
"card_list|20": [{ // 状态列下有 20 张卡片
"id": "@guid", // 卡片 ID
"subject": '@title', // 卡片主题
"sequence": /d{8}/, // 卡片序列号
"index": "@integer(1, 100)", // 序号(用于拖动排序)"archived": "@boolean", // 是否已归档
"blocked": "@boolean", // 是否设置阻塞
"is_parent": "@boolean", // 是否父卡片
"createdOn": "@date", // 创立工夫
"updatedOn": "@date", // 最近更新工夫
"parent": { // 父卡片
"id": "@guid",
"name": "@cword(2,10)"
},
"board": { // 卡片所在的看板
"id": "@guid",
"name": "@cword(2,10)"
},
"column": { // 状态列
"id": "@guid",
"name": "@cword(2,10)",
"type": "@string('upper', 2, 20)",
"deleted": "@boolean"
},
"card_type": { // 卡片类型
"color": "@color",
"name": "@cword(2,10)",
"icon": /icon-[a-z]-{1-3}/,
"id": "@integer(1, 100)"
},
"author": { // 卡片作者
"name": "@name",
"id": "@guid",
"nick_name": "@name",
"gender": "@string('lower', 4)"
},
"updater": { // 最近更新者
"name": "@name",
"id": "@guid",
"nick_name": "@name",
"gender": "@string('lower', 4)"
}
}]
}]
});
const API = () => ({'cards': CARDS,});
module.exports = API;
mock/routes.json
{"/cards": "/cards"}
第 2 步:批改脚本命令
脚本命令也须要做相应的批改
"mock": "node_modules/.bin/json-server --watch mock/db.js --routes mock/routes.json --port 9090"
第 3 步:重启 Mock 服务
这时咱们从新应用:
npm run mock
命令启动 Mock 服务,在浏览器中输出
http://localhost:9090/cards
拜访 /cards 接口:
能够看到 Mock.js 为咱们生成了十分多随机测试数据,之前结构这些数据可是要费很大的时间。
并且为了结构这大量的测试数据,咱们只是在 db.js 中减少了不到 50 行代码,不必在放心源文件体积太大的问题。
是不是十分便捷?
让咱们一起来试试业务中如何应用这些 Mock 接口,以及如何无缝切换成实在的后盾接口吧。
一起来试试看吧
假如咱们曾经用 NG CLI 创立了一个我的项目,为了调用 Mock 接口,咱们须要引入 Angular 的 HttpClientModule 模块:
src/app/app.module.ts
import {HttpClientModule} from '@angular/common/http';
imports: [
...,
HttpClientModule
]
间接调用 Mock 服务接口
而后注入 Angular 的 HttpClient 服务,就能够向 Mock 服务的 /cards 接口发动申请:
src/app/app.component.ts
import {HttpClient} from '@angular/common/http';
constructor(private http: HttpClient) {}
ngOnInit() {this.http.get('http://localhost:9090/cards').subscribe(cards => {console.log('cards:', cards);
});
}
获取到的接口数据如下:
应用代理无缝切换后盾接口
聪慧的你必定发现间接调用 Mock 服务的接口有问题:部署到测试环境或者现网怎么办?
因为环境上调用的必定是相应环境的后盾接口,而不是 Mock 服务的接口,所以在本地开发时将接口代理到 Mock 服务,理论调用接口时不加具体的域名信息。
理论调用接口应该是以下的形式:
this.http.get('/v1/cards').subscribe(cards => {console.log('cards:', cards);
});
为了做到无缝切换后盾接口,即:无需批改任何代码,本地调用 Mock 服务接口,线上调用后盾接口。
咱们须要在本地开发时将接口代理到 Mock 服务,能够应用 NG CLI 提供代理配置 proxyConfig:
angular.json
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "ng-demo:build",
"port": 4600,
"proxyConfig": "proxy.config.js" // 新增代理配置
},
...
}
代理配置文件:
proxy.config.js
const PROXY_CONFIG = {
'/v1': {target: 'http://localhost:9090/v1'}
};
module.exports = PROXY_CONFIG;
咱们的 Mock 服务不须要做任何扭转。
其余框架配置代理
如果你应用的不是 NG CLI,要怎么配置代理呢?
Vue CLI 配置代理
vue.config.js
devServer: {
proxy: {
'/v1': {target: 'http://localhost:9090/v1'}
}
}
Webpack 配置代理
Webpack 的写法和 Vue CLI 的差不多
webpack.config.js
devServer: {
proxy: {
'/v1': {target: 'http://localhost:9090/v1'}
}
}
CreateReactApp 配置代理
React 略微麻烦一点儿,须要装置 http-proxy-middleware 中间件。
const proxy = require("http-proxy-middleware");
module.exports = function(app) {
app.use(
proxy("/api/", {target: "http://localhost:9090/v1"})
);
};
减少 TS 类型
如果你的我的项目应用 TypeScript 的话,个别都会给接口数据减少 TS 类型,我给大家介绍一个依据接口主动生成 TS 类型文件的神器:quicktype。
quicktype 的定位是:
Generate types and converters from JSON, Schema, and GraphQL.
从 JSON、Schema 和 GraphQL 生成类型和转换器。
方才咱们曾经启动了咱们的 Mock 服务,在浏览器地址栏输出 http://localhost:9090/cards,也能够查看 /cards 接口的返回数据,这时咱们能够应用 quicktype 工具根,据接口地址生成相应的 TS 类型文件。
只须要 2 步即可:
- 第 1 步:装置 quicktype
- 第 2 步:生成 TS 类型文件
第 1 步:装置 quicktype
npm i -g quicktype
第 2 步:生成 TS 类型文件
quicktype http://localhost:9090/cards -o ./src/app/shared/types/card.interface.ts --runtime-typecheck
应用 TS 类型
import {CardInterface} from './shared/types/card.interface';
this.http.get('/v1/cards').subscribe((cards: CardInterface) => {console.log('cards:', cards);
});
应用 TS 类型有两个不言而喻的益处:
一是类型校验和主动提醒;
二是数据文档化和字段主动揭示和补齐。
类型校验和主动提醒:
数据文档化和字段主动揭示和补齐:
小结
本文次要介绍如何通过 JSON Server 和 Mock.js 两大神器,在前端搭建 Mock 服务,模仿后盾接口,从而在开发阶段去除对后盾的依赖,晋升业务交付的效率。
欢送大家评论交换!
源码地址:https://github.com/kagol/ng-mock-server
退出咱们
咱们是 DevUI 团队,欢送来这里和咱们一起打造优雅高效的人机设计 / 研发体系。招聘邮箱:muyang2@huawei.com。
文 /Kagol
往期文章举荐
《RxJS 源码解析(六)——Scheduler》
《Web 界面深色模式和主题化开发》
《手把手教你搭建一个灰度公布环境》
附录:XBoard 看板我的项目一览
XBoard 我的项目的开发看板