前端大基建
“基建”,就是研发团队的技术基础设施建设,是一个团队通用技术能力的沉淀,是一个团队未来的保证。网上看到的一句话,说的很好,“业务支撑是活在当下,技术基建是活好未来”。
源码和更多案例放在github上面,欢迎star
基建的意义在哪里 ?
基建的搭建有三个要素去确定:公司的团队规模、公司的业务、团队水平。根据不同的环境来搭建不同"重量"的基建系统。
对我们开发来说,技术之所以有价值,是因为技术最终是为了解决业务问题。搞基建主要是为了以下几点:
- 提高效率,基建可以提高单个人的工作产出和工作效率,可以从代码层面解决一些普遍性和常用性的业务问题
- 优化流程制度,优异的流程制度必将带来正面的、积极的、有实效的业务支撑
- 更好的面对未来的业务发展,像建房子一样,好的地基可以建出万丈高楼
- 影响力建设和团队的技术沉淀,一个好的技术团队,是一个公司的实力象征
前端基建链路层
基建的内容和业务阶段团队既有建设的沉淀是分不开的,所以基建就是从最基础的部分开始搞,怎么样能规范流程,方便开发,方便维护,怎样 能更加优雅的扩展业务,就怎么去搞基建。
接下来我们以“基建链路层”来搭建基建系统,下面是我所整理的基建链路层:
项目初始化
谈到基建,最基础的就是脚手架init,每个公司都有自己的项目架构,很多新建的项目,都会按照现有项目的架构,进行扩展或者删减,但大致变化不会太大。
用Node创建一个自己的(Webpack, vue)项目的CLI工具,包括以下几个功能:
- 定制命令行界面
- github上面存放一个模板项目,并且clone
- 自动安装依赖
- 发布脚手架
假设公司项目就这些功能架构,这样新项目完全可以做到开箱即用,只用通过一些命令行选择就能创建一个现有架构的新项目。这里我们就创建一个简单的基础的脚手架,如果还想要什么功能,可以按照这种模式去添加,本质是用node去操作文件。
以下是这个简易cli工具的项目图:
创建一个启动入口
创建一个bin文件夹 里面创建k-cil.js
启动文件。
#! /usr/bin/env node
const program = require('commander')
program.version(require('../package.json').version)
program
.command('init <name>')
.description('init project name')
.action(require('./../lib/init'))
program.parse(process.argv)
这段代码是创建一个需要输入初始项目名称命令的命令行界面
其中commander包是主要工具,这个包主要是提供人机交互的命令。
- command (用户输入的,<>里面是参数)
- description (-help命令里面的描述)
- aciton (这段输入之后,Node进行的行为,可以理解为函数调用)
最重要的一点就是 第一句 #!/usr/bin/env node
这句代码不可以没有,整体的意思就是说会有一个新的shell执行指定的脚本,执行这个脚本的解释程序是node,
如果不加这句代码的话是会报错的
命令行界面
下面我们来分析下,所需要添加的行为函数。
// lib/init.js
const {promisify} = require('util')
const figlet = promisify(require('figlet')) // 图形,本身是一个回调方法,所以才用promisify来加工
const clear = require('clear') // 清屏
const path = require('path')
const chalk = require('chalk') // 文字修饰
const clone = require('./download')
const log = content =>{
console.log(chalk.blue(content))
}
module.exports = async name =>{
// 欢迎界面
clear()
const data = await figlet('Welcome To K-cli')
log(data)
// 克隆远程模板项目
await clone("github:193Eric/vue-template", path.resolve(process.cwd())+'/'+name)
log(`模板下载成功!`)
}
这段代码是创建一个命令行界面,通过figlet
、chalk
来美化界面,并且在里面添加了一些我们需要cli工具去做的行为,克隆模板之类的,类似的还可以加别的行为。
以下是输入命令node bin/k-cli init projiect
后界面的样子:
克隆远程仓库的模板项目
// lib/download.js
const {promisify} = require('util')
const download = promisify(require('download-git-repo'))
const ora = require('ora') // 修饰
const clone = async (repo,desc)=>{
const process = ora('下载中....... '+repo)
process.start()
await download(repo,desc)
process.succeed()
}
module.exports = clone
这个代码是通过download-git-repo包来下载仓库项目。
注意download接收两个参数。
第一个参数是远程仓库地址,格式是github:193Eric/vue-template
,先指明什么仓库,然后再是项目地址。
第二个参数是下载的项目放在什么路径,一般会放在当前文件夹,process.cwd()
可以得到当前文件夹路径,用它加上输入的项目名就会自动创建项目了。
自动安装依赖
ps: 由于安装依赖我们要用shell来触发npm install,在node里面我们想调用shell,一般都会子进程的
child_process
方式
// lib/init.js
const cProcessInstall = async (...args)=>{
const {spawn} = require('child_process')
return new Promise((resolve)=>{
const proc = spawn(...args)
proc.stdout.pipe(process.stdout)
proc.stderr.pipe(process.stderr)
proc.on("close",()=>{
resolve()
})
})
}
// ....init内容
log(`安装依赖 等待安装...`)
await cProcessInstall('npm',['install'],{cwd:`./${name}`})
log(`🚀安装依赖完成!`)
这里用了node子进程的方式封装了一个promise,来异步调用安装依赖。这里面比较重要的就是pipe的操作,子进程完成之后输出都需要通过pipe来发送到主进程。
npm发布
- 首先我们创建一个npm的账号npm官网
- npm login 输入你的账号密码邮箱
- 然后登陆成功后 npm publish 推送
到这里就完成了一个简单的脚手架了。然后我们来测试一下
// 全局安装一下
npm install eric-k-cli -g
// 按照之前的命令
k-cli init ericTest
这样一个简易的脚手架就成功了,由于是示例代码就放了两个简单的功能函数。
在实际项目中我们还可以加入:
- 项目注入sentry监控
- 接入iconfont指定云包
- 接入rap接口管理
…
接口联调
说到接口联调,我们是经历三个时代的演变。
1、石器时代
团队评审完需求,前端开始做静态页面,后端开始写接口。等两边都写完之后,后端给出接口,前端一个个接入。
尿点:无法合理利用两个人时间,浪费联调接口时间
2、青铜时代
mock的引入,解决了石器时代的痛点。
后端先设计接口,抛出接口文档,前端引入mock.js,做好项目后,直接无缝衔接后端接口。
尿点:每次前端都要复写一份后端的接口文档,到本地。mock数据结构一多,分了很多模块,不好管理(毕竟后端也维护了一份)且本地代码厚重
3、白银时代
Rap平台,RAP(基于Mock.js)是一个新的解决方案,将前端后端拉倒一个团队仓库中,共享一个仓库,无论是URL地址,还是请求需要的参数,在团队仓库中双方都可以管理,并且可以记录团队成员修改了哪些接口。解决了青铜时代所面临的问题
现在我们用Rap的方式,来处理接口联调。
github有提供 RAP的开源代码和release下载 https://github.com/thx/RAP/releases。我们可以部署一个RAP服务在我们本地服务器。
具体的RAP流程:
centos安装RAP
安装基础软件
wget http://repo.mysql.com/yum/mysql-5.6-community/el/7/x86_64/mysql-community-libs-5.6.26-2.el7.x86_64.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
yum install -y mysql-server nginx tomcat unzip redis
下载war包
wget http://rap.taobao.org/release/RAP-0.14.0-SNAPSHOT.war
解压至ROOT
unzip -x RAP-0.14.0-SNAPSHOT.war -d ROOT
配置数据库
创建数据库及用户
create database rap_db default charset utf8 COLLATE utf8_general_ci;
grant all on rap_db.* to 'rap'@'localhost' IDENTIFIED BY 'password';
flush privileges;
初始化数据库,输入刚才创建用户的密码
mysql -u rap -p rap_db < ROOT/WEB-INF/classes/database/initialize.sql
配置应用中数据库连接
vi ROOT/WEB-INF/classes/config.properties
修改为刚才创建的数据库用户名及密码
jdbc.username=rap
jdbc.password=password
其中redis配置可根据需求更改
启动redis
systemctl start redis
配置tomcat
sudo cp -rf ROOT /var/lib/tomcat/webapps
sudo chown -R tomcat. /var/lib/tomcat/webapps/ROOT
重启tomcat
systemctl restart tomcat
配置nginx
在/etc/nginx/conf.d 中添加如下配置 rap.conf
注意: 将其中的xxxx替换为你的本机ip地址或者域名
server {
listen 80;
server_name xxxxx; #本机IP或者域名
access_log /var/log/nginx/rap_access.log;
charset utf-8;
autoindex off;
location /{
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
重启nginx
systemctl restart nginx
配置防火墙
firewall-cmd --permanent --add-service=http
firewall-cmd --reload
访问
访问http://ip地址或者域名
为什么信赖RAP?
-
企业级应用,包括阿里集团在内得350多个企业都在使用RAP管理重要的接口文档。
-
快速高效的技术支持,持续的更新,去Issues看一看就知道有多热闹。
-
免费、开源,一切尽在掌握中!
数据埋点分析
埋点是网站和APP等产品进行日常改进及数据分析的数据采集基础,我们主要用来采集用户行为数据(例如:页面访问路径,点击了哪一个按钮)进行数据分析,从而让运营同学更加合理的安排运营计划让产品经理更好的优化产品路径。每个公司的情况不同,大的公司有自己的数据分析系统,很多公司都会采用第三方的数据分析平台来进行数据收集和分析。
这里我们比较省事,直接用google Analytics来做的数据埋点,建议大家如果不是特别大的公司,或者特殊的需求,还是用第三方的。
这里我们主要介绍Google Analytics
简单的说它是谷歌推出的服务于广大站长的一款统计工具,它可以详细的让你知道很多数据,例如:
- 那些国家和地区的人访问了你网站
- 那些网站页面是最受欢迎的
- 网站的流量来源有哪些
- 每个访客的停留时间是多少
- 网站访客的年龄段分布
- 访客是通过什么设备(pc或者移动端)的
安装Google Analytics
首先访问 https://analytics.google.com 注册一个账号
然后点击跟踪代码
目录,GA会让你把一段代码插入到前端代码<head>
里面。插入过这段代码的页面会跟GA建立联系。
在前端代码<head>
植入好之后,点开实时就可以看到数据了。
这里面有一个事件,事件是我们主动设置的事件,然后再代码中去触发它,GA这边能接收到。日常统计中,最常用的就是这个功能了,可以统计用户的点击行为,或者领取什么行为,甚至是统计接口请求。
以上就是GA的一些安装和简单应用方式,如果想要深入运用的话,可以去官网文档看看https://developers.google.cn/analytics/devguides/platform