Git与效率工具

131 阅读18分钟

七、Git

7.1 Git工程规范

git文档

package.json配置查询

#7.1.1 Git flow规范

在工作中避免不了多人协作,协作避免不了有一个规范的流程,让大家有效的去合作;让项目仅仅有条的发展下去;git flow是最早诞生, 并得到广泛采用的一种工作流,git flow采用的是功能驱动式开发。  功能驱动式开发(Feature-driven development,简称FDD)

  • 长期分支

    • master - 主分支
    • develop - 开发分支
  • 短期分支

    • feature - 功能分支
    • hotfix - 补丁分支
    • release - 预发分支
分支详细介绍
master产品分支:只能从其他分支合并内容,不能在这个分支直接修改。合并到master上的commmit只能来字release分支或hotfix分支
develop开发主干分支:基于master的tag建立,主要用来暂时保存开发完成而又未发布的feature分支内容,以及release和hotfix的补充内容
feature功能分支:一般一个新功能对应一个功能分支,从而和已经完成的功能隔离开来,而且只有在新功能完成开发的情况下,其对应的feature分支才会合并到主开发分支(develop分支)上
release预发分支:当需要发布时,我们从develop分支创建一个release分支,然后这个release分支会发布到测试环境进行测试,如果发现问题就在这个分支直接进行修复。发布结束后,这个release分支会合并到develop和master分支,从而保证不会有代码丢失。
hotfix补丁分支:主要用于紧急修复一些bug,会从master分支上的某一个tag建立,修复结束后再合并到develop和master分支上

7.1.2 Git commit 规范

#为什么要写好 Git Commit?

  • 提供更多的历史信息,方便快速浏览
  • 可以过滤某些commit(比如文档改动),方便快速查找信息
  # 过滤日志信息
  git log HEAD --pretty=format:%s --grep 关键字
  • 可以直接从commit生成Change log

如何优雅地写好Git Commit

业界使用比较广泛的是Angular规范

<type>(<scope>):<subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
  • 标题行:必填,描述主要修改类型和内容
  • 主要内容:描述为什么修改,做什么样的修改,以及开发的思路等等
  • 页脚注释:放 Breaking Changes 或 Closed Issuses

type | commit 类型

类型详细介绍
feat新功能、新特性
fixbugfix,修改问题
refactor代码重构
docs文档修改
style代码格式修改,注意不是css修改
test测试用例修改
chore其他修改,比如构建,依赖管理

scope | commit影响的范围 比如:route、component、utils、build.....

  • subject:commit 的概述,建议符合 50/72 formatting
  • body:commit 具体修改内容,可以分为多行,建议符合50/72 formatting
  • footer:一些备注,通常是BREAKING CHANGE 或 修改的bug链接

#利用插件(commitizen)

利用commitizen,提交规范的commit。

package.json配置查询

  • commitizen 用于提示用户输入或选择,生成规范的commit
  • cz-conventional-changelog 用于生成changelog
# 1. 下载cz-conventional-changelog changelog插件 
npm install -g commitizen cz-conventional-changelog
# 2. package.json 配置

{
    "scripts": { 
    # 以后提交commit 直接执行npm run commit
       "commit": "git-cz",
    },
    # config用来设置一些项目不怎么变化的项目配置,用户用的时候可以使用如下用法:process.env.npm_package_config_commitizen
    "config": {
      "commitizen": {
        "path": "./node_modules/cz-conventional-changelog"
      }
  }
}

# 也可以使用以下配置,配置全局变量
# 命令行中输入以下命令,配置到czrc目录下,也可以用vim编辑~/.cz
echo '{ "path": "cz-conventional-changelog"}' > ~/.czrc

自定义文档格式,commit用中文去写(扩展)

# 1.下载
npm install -g cz-customizable
# 2. package.json 配置
...
"config": {
  "commitizen": {
    "path": "node_modules/cz-customizable"
  },
  "cz-customizable": {
    "config": "./cz.config.js"
  }
}

# 也可以使用以下配置,配置全局变量
echo '{ "path": "cz-customizable"}' > ~/.czrc
# echo添加或vim编辑添加
vim .czrc
# 添加配置 { "path": "cz-customizable"}

# 3.创建配置文件
touch ./cz.config.js

cz.config.js

module.exports = {
  //可选类型
  types: [
    { value: 'feat', name: 'feat:   新功能' },
    { value: 'fix', name: 'fix:   修复' },
    { value: 'docs', name: 'docs:   文档变更' },
    { value: 'style', name: 'style:   代码格式(不影响代码运行的变动)' },
    {
      value: 'refactor',
      name: 'refactor:重构(既不是增加feature),也不是修复bug'
    },
    { value: 'perf', name: 'perf:   性能优化' },
    { value: 'test', name: 'test:   增加测试' },
    { value: 'chore', name: 'chore:   构建过程或辅助功能的变动' },
    { value: 'revert', name: 'revert:   回退' },
    { value: 'build', name: 'build:   打包' },
    { value: 'revert', name: 'revert:   回退' }
  ],
  //消息步骤
  messages: {
    type: '请选择提交类型',
    customScope: '请输入修改范围(可选)',
    subject: '请简要描述提交(必填)',
    body: '请输入详细描述(可选)',
    footer: '请输入要关闭的issue(可选)',
    confirmCommit: '确认以上信息提交?(y/n)'
  },
  //跳过问题
  skipQuestion: ['body', 'footer'],
  //subject文字长度默认是
  subjectLimit: 72
}

gitmoji(趣味图标)(扩展)

npm i -g gitmoji-cli
gitmoji -c # git commit 提交

7.2 Git Hooks

#7.2.1 git hooks

Git 钩子(hooks)是在Git仓库中特定事件(certain points)触发后被调用的脚本

可以用git init初始化git文件,在.git/hooks下有各种钩子模版,可以用例如less prepare-commit-msg.sample查看文件,里面是一段执行脚本。

  • 客户端钩子-> 由诸如提交和合并这样的操作所调用
  • 服务端钩子-> 作用于诸如接收被推送的提交这样的联网操作

#客户端 Hooks

类型详细介绍
prepare-commit-msgcommit message编辑器呼起前 default commit message创建后触发,常用于生成默认的标准化的提交说明
commit-msg开发者编写完并确认commit message后触发,常用于校验提交说明是否标准
post-commit整个git commit完成后触发,常用于邮件通知、提醒
applypatch-msggit am提取补丁并 应用于当前分支后,准备提交触发,常用于执行测试用例或检查缓冲区代码
pre-applypatchgit am提交后触发,常用于通知、补丁、邮件推送回复(此钩子不能停止git am过程)
pre-rebase执行git rebase命令时触发
post-rewrite执行会替换commit的命令时触发,比如git rebase 或 git cimmit-amend
post-checkout执行git checkout命令成功后触发,可用于生成特定文档,处理大二进制文件等
post-merge成功完成一次merge行为后触发
pre-auto-gc执行垃圾回收前触发

#服务端 Hooks

类型详细介绍
pre-receive当服务端收到一个push操作请求时触发,可用于检测push的内容
update与pre-receive相似,但当一次push想更新多个分支时,pre-receive只执行一次,而此钩子会为没一分支都执行一次
post-receive当整个push操作完成时触发,常用于服务侧同步、通知

7.2.2 工程实践

#Husky

用node实现的的快速安装git hooks的工具

// npm install husky --save-dev
// package.json
{
  "husky" : {
    "hooks": {
       "pre-commit": "npm test",
        // ......
    }
  }
}

命令行 less .git/hooks/pre-commit 查看pre-commit文件,可以看见"(dirname"(dirname "0")/husky.sh",然后可以查看less .git/hooks/husky.sh

#link-staged

只会检测暂存区的文件,不会对所有的文件进行检测,也就是说我修改一个文件,只会检测当前这个文件

 # 安装代码检测工具
 npm install prettier eslint -D
 # 安装lint-staged
 npx mrm lint-staged
{
"gitHooks": {
    "pre-commit": "lint-staged"
  },
{
  "lint-staged": {
    "*.js": "eslint --cache --fix",
    "*.{js,css,md}": "prettier --write"
  }
}

7.2.3 Git Hooks 拓展学习资料

自定义Git - Git 钩子:git-scm.com/book/zh/v2/…

Husky:github.com/typicode/hu…

8.1 真机远程代码调试

#8.1.1 ios真机设备调试

  1. 在手机上开启网页检查器

设置-> safari 浏览器 -> 高级 -> 网页检测器

  1. 开启Safari上的Develop功能

菜单 -> Preferences(偏好设置) -> Advanced(高级)

3. 使用数据线连接手机个开发主机

  • 信任电脑
  1. 打开devTool

Develop -> 你的ios设备 -> 要调试的页面

8.1.2 Android真机设备调试

  1. 在手机上开启USB调试功能

设置-> 开发者选项 -> USB调试

  1. 使用数据线连接手机和开发主机
  • 允许USB调试
  1. 打开Chrome DevTools
  • 在地址栏输入chrome://inspect
  • 确保开启了 Discover USB devices

#8.2 无线调试工具-Weinre

  • 无需数据线
  • pc和移动都可以调试
  1. 环境准备与安装
  • 环境:任何node.js 环境
  • 安装:npm install -g weinre
 weinre -h  #获取帮助信息
 weinre --boundHost=-all- --httpPort=1000 # 启动,boundHost为all是允许本机所有有效ip访问,默认端口8080

2. arget 页面配置

<!-- 往被调试页面添加脚本 -->
<script src="http://ip:端口/target/target-script-min.js#anonymous"></script>
<!-- 示例 -->
<script src="http://172.20.10.11:1000/target/target-script-min.js#anonymous"></script>
  1. 调试

调试移动手机的页面需要手机访问局域网内的页面服务(例如react开启了3000端口的服务,那么手机访问ip+3000)

扩展

weinre官网

#8.3 在移动端调试

主流的移动端devTool

  • vConsole
  • eruda

扩展资料

vConsole项目主页

eruda项目主页

创建一个vConsole 插件

#8.4 使用代理服务器进行调试(charles)

#8.4.1 常见的代理服务器

  • Fiddler

    • C#编写
    • 正式版仅支持Windows
    • 请求展示:时间顺序
    • 支持解析HTTPS请求
    • 免费
  • Charles

    • java编写
    • 多平台支持
    • 请求展示:树状结构
    • 不支持直接解析HTTPS请求
    • 付费获得更好体验

8.4.2 HTTP抓包

  1. 移动端配置(配置代理)

点击手机连接的Wi-Fi->HTTP代理->配置代理

  • 服务器:填入电脑的ip地址(可以在charles查看 help->Local IP Address)
  • 端口:默认是8888
  1. 开始抓包

工具栏第二个按钮(红色说明正在抓包)

#8.4.3 HTTPS抓包

charles不能直接抓包https,所以我们还需要进行以下操作

  1. 移动端配置代理

与上面http配置完全相同 (切记!!!这一步一定要做,只有配置了代理服务,才能下载证书,因为这是你电脑上charles给你颁发的,你换了电脑还需要另一个电脑给你颁发)

  1. 添加要解析的域名列表
  • 菜单栏Proxy-> SSL Proxying Settings
  • 在Host一栏设置要解析的域名,也可以*表示所有的HTTPS都做解析,port:443;点击ok后重启charles。

设置后重启charles

  1. 信任Charles根证书
  • 在移动端用浏览器访问https:chls.pro/ssl下载证书描述文件

    • 安卓:直接安装即可

    • IOS:

      1. 在设置-通用-描述文件与设置管理中安装证书,
      2. 然后开启 设置-通用-关于本机-针对根证书启用完全信任

(当你访问上面chls网站时,电脑上charles会有一个弹窗询问你是否允许给手机安装证书,你要点同意(allow))

🍅 HTTPS 协议

  • https = http + sll(secure sockets layer)

发送一个HTTPS请求的过程简单来说客户端是向服务端索取一个公钥放在客户端,公钥的载体就是数字证书;客户端通过公钥加密,服务端通过私钥解密。

🍅 charles 代理HTTPS请求的机制

charles做客户端和服务端的中介,代理了https请求;charles会动态为每个服务器生成由charles根证书签发的数字证书;当请求产生时客户端收到的不是 服务端的原始证书而是charles签发的证书,原始证书是保存在charles上的;客户端与服务端的通信是由charles公钥加密的,而charles与原始服务器的通信是 由服务端的原始证书加密的,charles通过自己的私钥解密,所以我们能通过charles看见未加密的数据。

🍅 可能出现的问题

  1. 开启后电脑浏览器无法打开网页

关掉charles的External Proxy setting:点击顶部Proxy-> 去掉勾选 External Proxy Settings

  1. 开启手机代理后浏览器无法打开网页

    • 要保证电脑和手机同一个Wi-Fi,手机上填的代理服务器ip不要填错了,可以查看charles:Help/Local IP Address;端口一般是8888
    • 打开https的网站,会提醒不是安全连接,说明你证书没有安装正确,或者没有信任
    • 一般就上诉2个问题,也可以重启试试
  2. 关闭charles后 无法联网

打开网络偏好设置-> 高级 -> 代理 -> 检测网页代理和安全网页代理是否开启(不需要开启,你关闭charles后就没有代理服务器了,记得手机也取消代理配置)

  1. 抓取手机端的返回的是unknow
  • 确保证书在手机端被信任
  • safari浏览器访问https:chls.pro/ssl下载证书描述文件时候,确保配置了http代理(ip:8888), 如果换电脑需要再次下载证书,可以在描述文件中查看证书,charles通用名称中会包含你电脑系统的名称
  1. 手机开启代理后,也能访问网页,但是电脑上的charles没有抓取到数据
  • 检查代理是否正确
  • 重启charles

8.4.4 Map请求重定向

🍅 Map Local / Map Remote

  • 生产环境代码打包压缩后不利于debug
  • 调试时不方便频繁发布
  • Map Local:将某请求重定向至本地某个文件
  • Map Remote:将某请求重定向至另一个请求
  • 将生成环境的代码替换成本地的代码

🍅 Map Remote

image.png

尝试改动代码,查看页面变化

🍅 Map Local

image.png

Map Local可以替换任意charles能抓包到的文件,甚至可以将api请求替换成本地的json文件,做接口的一个mock, 其实就是一个文件的代理功能。

如果想取消Map Local / Map Remote:charles顶部tools-> Map Local / Map Remote -> 不勾选enable map local/Remote-> ok

8.4.5 Rewrite 修改请求内容

🍅 Rewrite功能

  • 可作用于:request & reponses
  • 可修改:header、host、path、url、params、body等
  • 采用新增、替换的形式

🍅 案例

向生产环境页面注入vConsole脚本

  1. 顶部tools-> Rewrite

添加匹配location 

添加rewrite规则

上面其实就是将</head>标签替换成 <script src="<script src="https://cdn.bootcdn.net/ajax/libs/vConsole/2.5.0/vconsole.min.js"></script>">new VConsole()</script></head>

8.5 在公网访问本地服务

#8.5.1 内网穿透

#什么叫内网穿透

  • NAT(Network Address Translation)穿透

  • 从公网访问内网

  • 在公网访问部署在本地服务器上的服务

  • ngrok & localtunnel

    • 生成唯一可在公网访问的url,该url会在代理本地运行的web服务请求

#8.5.2 localtunnel的使用

  1. 安装
    npm install -g localtunnel
    lt --help # 帮助信息
  1. 启动
    # -p 本地启动服务的端口,-s 指定自己子域名地址,也可以不指定
    lt -p 3000 -h https://tunnel.svrx.io -s mayi
    # 启动成功后 your url is: https://mayi.tunnel.svrx.io
    # 访问地址 https://mayi.tunnel.svrx.io

8.5.3 部署你的localtunnel服务

  • localtunnel默认服务在外国,不稳定,访问速度慢

  • 自己部署lt服务的机器需要满足:

    1. 支持DNS泛域名解析,比如:mydomain.com 和 *.mydomain.com
    2. Localtunnel服务端能监听任何非root权限的TCP端口
  1. 配置dns解析 添加两个A类记录

    • mydomain.com
    • *.mydomain.com
  2. 启动localtunnel server

    git clone git://github.com/defunctzombie/localtunnel-server.git
    cd localtunnel-server
    npm install
    bin/server --port 1234
    bin/server --port 1234 --domain sub.mydomain.com
  1. 在localtunnel客户端使用部署的host
    lt --host http://sub.mydomain.com:1234  --port 8000

8.6 随机数据生成(mock)

#特点

  • “生成随机数据,拦截Ajax请求“
  • 业务代码物侵入
  • 数据类型丰富
  • 用法简单,可扩展性强

#8.6.1 Mock.js 的安装及基本语法

// 安装
npm install mockjs

// 基本用法
const Mock = require('mockjs')
const data = Mock.mock({
  // 属性list 的值是一个数组,其中含有 1 到 10个元素,数组里的对象数量是随机的
  'list|1-10':[{
    // 属性id 是一个子增函数,起始值为1,每次增1
    'id|+1':1
  }]
})
// 输出结果
console.log(JSON.stringify(data,null,4))

mockjs的语法

// name 是属性名,rule是规则 ,value是属性值;属性名和规则之间是用|分割的
'name|rule':  value
 name: value

1. 'name|min-max': value
2. 'name|count': value
3. 'name|min-max.dmin-dmax': value
4. 'name|min-max.dcount': value
5. 'name|count.dmin-dmax': value
6. 'name|count.dcount':  value
7. 'name|+step': value
  • 属性值决定了规则的初始值和类型
  • 生成规则的含义需要依赖属性值的类型才能确定
  1. 属性值是字符串
  • 将value字符串重复min-max次
// 1. 'name|min-max': value  生成的数量是随机的
{'repeater|1-5': 'hi!'} -> { repeater: 'hi!hi!hi!'}
  • 将value字符串重复count次
// 2. 'name|count': value
{'repeater|2': 'hi!'} -> {repeater: 'hi!hi!'}
  1. 属性值是数字
  • 随机生成min-max 范围内的一个数字
 // 1. 'name|min-max': value
 // 现在value是数字,属性值决定了初始值,1和50也可以换成其他数字;不影响结果
 {'age|1-30': 1} -> { age: 22 }
 {'age|1-30': 50} -> { age:15 }
  • 随机生成一个小数,整数部分值在min-max范围内,小数部分位数在dmin-dmax之间
// 'name|min-max.dmin-dmax':vlaue
{ 'price|1-30.2-3': 1} -> { price: 20.28}
{ 'price|1-30.2-3': 1} -> { price: 4.827}
  1. 属性值是布尔值
  • 随机生成一个布尔值,其中value和!value的比例为min-max

    • value 概率 = min / (min+max)
    • !value 概率 = max / (min + max)
  // 'name|min-max':vlaue
  { 'active|1-1': true } -> { active: true }
  { 'active|1-1': true } -> { active: true }
  1. 属性值是对象
  • 从value中随机min-max个属性
  // 'name|min-max': vaule
  { 'user|1-2': { name: 'jack', age: 2 }} -> { user: { age:2}}
  { 'use|1-2': { name: 'jack', age: 2 }} -> { user: { name: 'jack', age:2 }}
  • 从value中随机取count个属性
// 从value中随机取count个属性
// ‘name|count’: value
{ 'user|1': { name: 'jack', age: 2}} -> { user: { age:2 }}
  1. 属性值是数组
  • 从value列表中随机获取1个元素
{ 'fruit|1': ['apple','banana']} -> { fruit: 'banana' }
  • 将value列表内的值重复min-max次
{ 'list|1-2': ['a']} -> { list: ['a']}
{ 'list|1-2': ['a']} -> { list: ['a','a']}
  1. 属性值是其它类型
  • 生成值为function执行结果
// function
{ age: ()=> 1 } -> { age:1 }
  • 随机生成符合正则表达式的字符串
// reExp
{ age: /1[0-9]/ } -> { age: '19' }

8.6.2 Mock.js的常用方法

  1. Mock.mock()
  • Mock.mock(rurl?,rtype?,template|function(options))

    • rurl: 要拦截的请求url,支持正则
    • rtype:要拦截的请求类型,如POST、GET、DELETE等
    • template:数据模版,支持对象、字符串
    • function(options): 生成相应数据的方法,options:{ url,type,body }

🍅 使用mock()方法拦截请求

//  在入口文件中引入mockjs,对 ‘api/activity‘进行拦截
import Mock from 'mockjs';

if(process.env.NODE_ENV !== 'production')
    Mock.mock(/api/activity/,{
      code: 200,
      data: {
        'isLegal|2-1':false
      } 
    })
  }
  1. Mock.Random
  • 工具类
const { Random }  =  Mock;
Random.email()
// => "n.abc.@miller.io"
Random.image()
// => http://dummyimage.com/336x330

🍅 Mock.Random 支持的方法

typeMethod
Basicboolean、natural、integer、float、character、string、range、date、time、datetime、now
Imageimage、dateImage
Colorcolor
Textparagraph、sentence、word、title、cparagraph
Namefirst、last、name、cfirst、clast、cname
Weburl、domain、email、ip、tld
Addressarea、region
Helpercapitalize、upper、lower、pick、shuffle
Miscellaneousguid、id

🍅 Mock.Random 与模版语法

const Mock =  require('mockjs');

const { Random } = Mock
const user = Mock.mock({
  code: '200',
  'list|10': [{
    name: `${Random.first()} ${Random.last()}`,
    avatar: Random.image()
  }]
})

console.log(users)

{
  code: 200,
  list: [
    { name:'Sarah Leris', avatar: 'http://dummyimage.com/300x600'},
    { name:'Sarah Leris', avatar: 'http://dummyimage.com/300x600'}
    .....
  ]
}
// 10个相同的对象

由于用Random生成的都是一样的,这可能不是我们想要的,我们想要每一个对象里的数据都不一样,那就看下面的占位符。

🍅 Mock.js 的占位符

  • 占位符
  • 使用最广泛
  • @占位符
  • @占位符(参数、[,参数])
  • 只是在属性值字符串中占个位置,并不出现在最终的属性值中
  • 实际采用Random中的方法计算
const Mock =  require('mockjs');

const { Random } = Mock
const user = Mock.mock({
 code: '200',
 'list|10': [{
   name: '@first @last',
   avatar: '@image'
 }]
})

console.log(users)

{
 code: 200,
 list: [
   { name:'Carol Brown', avatar: 'http://dummyimage.com/3335x220'},
   { name:'Angela Lopez', avatar: 'http://dummyimage.com/378x600'}
   .....
 ]
}
// 10个不同的对象

8.7 RestFul API 快速模拟

#8.7.1 复杂的接口mock场景

#RESTful API

  • REpresentational State Transfer 表现层
  • 资源是由URI来指定:/songs(代表歌曲) /playlist/12(代表第12个playlist)
  • 对资源的操作包括增删改查:POST、DELETE、PUT和GET方法
  • 是一套API设计理论,约束规范、增强可读性、便于开发

#RESTful 规范

GET http://abc.com/api/playlists # 获取歌单列表
GET http://abc.com/api/playlist/12345 # 获取id为123456的歌单
POST http://abc.com/api/playlists # 添加一个歌单
DELETE http://music.163.com/api/palylist/55 # 删除id为 55 的歌单
PUT http://music.163.com/api/palylist/123456 # 删除id为 123456 的歌单

GET : 返回资源对象
POST :返回新生成的资源对象
PUT :返回完整的资源对象
DELETE:返回一个空文档

{
  "code": 200,
  "message": "success",
  "data": {
    playlist: {....}
  }
}

HTTP 状态码:
2xx: 请求成功
3xx:重定向
4xx:客户端错误
5xx:服务端错误
  • 如何mock对同一个资源的增删改查
  • 在前端运行、可以存储数据的server
  • JSON-Server :零开发,快速模拟RESTful API

#8.7.2 JSON-server 的安装和用法

// install
npm install -g json-server

// db.json
{
    "songs":[
      { "id": 1, "name": "Baby"}
    ],
    "comments": [
      { "id": 1, "content": "nice" }
    ]
  }

// start server
json-server --watch db.json

运行成功输出的日志

  {^_^}/ hi!

  Loading ./db.json
  Done

  Resources
  http://localhost:3000/songs
  http://localhost:3000/comments

  Home
  http://localhost:3000

  Type s + enter at any time to create a snapshot of the database
  Watching...

GET /songs 200 8.036 ms - 43
GET /songs 304 3.381 ms - -

GET http://localhost:3000/songs/1 会返回 { "id":1,"name":"Baby"} 根据songs/1路由1进行筛选

POST、PUT、PATCH、DELETE 操作会改变db.json文件的内容 Routes 规则-过滤

{
  "songs": [
    { "name": "吻别", "artist": "张学友" },
    { "name": "燃烧我的卡路里 ", "artist": "火箭少女 101" },
    { "name": "麻雀", "artist": "李荣浩" }
  ],
  "comments": [
      { "id": 1, "content": "nice" }
    ]
}
GET /songs?artist=张学友
GET /songs?artist=张学友&arttist=李荣浩
GET /comments?author.id=1

🍅 Routes 规则-翻页与排序

// 以_开头的是json-server的保留字
// 分页
GET /songs?_page=2
GET /songs?_page=1&_limit=15

// 排序
GET /songs?_sort=id&_order=asc

// 多字段排序
GET /songs/_sort=id,name&_order=desc,asc

🍅 Routes 规则-查询

// operators:
// _gte _lte _ne 大约小于等于
GET /users?age_gte=10&age_lte=20 
GET /users?age_ne=18

// _like 支持正则
GET /songs?name_like=爱

// q 全局搜索
GET /songs?q=喜欢

🍅 自定义 routes

  • 更贴近后端接口
// routes.json
// 左边是实际访问的路径,右边是资源的路径
{
  "/api/*": "/$1",
  "/:resource/:id/show": "/:resource/:id", 
  "/posts/:category": "/posts?category=:cagegory",
  "/articles\?id=:id": "/posts/:id"
}

// 添加启动参数:json-server db.json --routes routes.json
/api/posts // -> /posts
/api/posts/1  // -> /posts/1
/posts/1/show //  -> /posts/1
/posts/javascript // -> posts?category=javascript
/articles?id=1 // -> /posts/1

🍅 添加 middleware

  • 统一定制个性化请求
// my-middleware.js
module.exports= (req, res ,next) => {
  res.header('X-token',"xxxxx")
  next()
}
// 启动
json-server db.json --middlewares ./my-middleware.js

8.7.3 生成随机数据

当数据量过大时候,我们不能手写庞大数据量的db.json,json-server也支持js对象。

快速生成随机数据-Mock.js

// index.js
const Mock = require('mock.js')
module.exports= () => {
  const data = Mock.mock({
    'user|1000': [{{
      'id|+1': 1,
      'name': '@first @last'
    }]
  })
  return data
}
// 启动
json-server index.js --middlewares ./my-middleware.js

#8.7.4 JSON-Server的基本使用

搭配Mock.js 生成随机数据接口

🍅 查询歌单列表

新建文件index.js

const Mock = require('mockjs')

module.exports= ()=> {
    const data = Mock.mock({
        'playlists|100': [{
            'id|+1':1,
            'name': '@title',
            'cover': '@image'
        }]
    })
    return data
}

新建routes.json

// /api/music/ 下面所有的请求转发到去掉这个前缀的下面
// $1 表示任意的字符
{
    "/api/music/*": "/$1"
}

启动 json-server index.js --routes routes.json

访问 http://localhost:3000/api/music/playlists可以获得100条数据

🍅 查询分页的歌单

修改routes.json

{
    "/api/music/*": "/$1",
    "/playlists\?limit=:limit&offset=:offset": "/playlists?_start=:offset&_limit=:limit"
}

启动 json-server index.js --routes routes.json

访问 http://localhost:3000/api/music/playlists?limit=10&offset=20从20开始返回10条数据

🍅 新增一个歌单

// 用curl模拟一下请求 参数{"name":"夜曲","cover":"xxxx"}
curl localhost:3000/api/music/playlists -X POST -d '{"name":"夜曲","cover":"xxxx"}' -H 'Content-Type: application/json'

🍅 修改一个歌单

curl localhost:3000/api/music/playlists/101 -X PUT -d '{"id":101,"name":"月半小夜曲","cover":"xxxx"}' -H 'Content-Type: application/json'

🍅 删除一个歌单

curl localhost:3000/api/music/playlists/101 -X DELETE  -H 'Content-Type: application/json'

以上也可以用postman模拟请求

#给所有的响应头添加header

新建middleware.js

json-server index.js --routes routes.json --middleware middleware.js

8.8 Stream 手机抓包APP

安装软件-> 安装证书-> 信任证书