工程化-学习笔记

127 阅读13分钟

1. 脚本

1.1 npmscripts

常用命令:

npm init  // 初始化工具
npm run  // run scripts
npm install  // 安装依赖
npm update  // 升级依赖
npm bin  // 查看bin文件目录
npm link  // 将工程软链接到全局
npm publish  // 发布包
npm deprecate  // 废弃包

如何对npm scripts 二次包装过的命令传参? 利用 -- 透传

{
    "scripts": {
        "server": "server ./build",
        "server:prod": "npm run server -- -l 80"
    }
}

脚本钩子

  • 脚本钩子类似于hook,当事件触发时,对应的钩子逻辑也被触发,githook,web hook等...
  • 部分npm 内置脚本钩子如下:
preinstall  // 用户执行npm install命令时,先执行该脚本
postinstall  // 用户执行npm install命令时,安装结束后执行该脚本
preuninstall  // 卸载一个模块前执行
postuninstall  // 卸载一个模块后执行
prelink    // link模块前执行
postlink   // link模块后执行
pretest   // 运行 npm test 命令前执行

规律:pre- 和 post-
除了内置脚本钩子,我们也可以按规则自定义地添加钩子。

1.2 Bash

1.2.1 Shell是什么

  • Shell不仅仅是命令行,也可以是GUI
  • Shell是操作系统和用户交互的“接口”
  • 一般来说,我们说的Shell都是Unix Shell,可以认为是CLI

命令(Command)是什么?

  • 命令的本质是一个程序
  • 这些程序具有发起系统调用(System Call)的能力
  • 编写Shell脚本,其实是在编排这些程序的执行
  • 除此之外,还有Shell语法解释器负责解释一行行的Shell语句

image.png

1.2.2 常见的Bash命令

没有什么是-h解决不了的,如果有那就是man命令。

// 1. 文件新建
touch ./index.js; // 新建一个文件
mkdir ./a-new-project; // 新建一个目录

// 2. 文件删除 rm
rmdir ./a-new-project  // 删除目录a-new-project
rm ./a-single-file;  // 删除一个文件
rm -r ./a-dir   // 递归地删除该目录以及该目录下的文件
rm -rf ./a-dir-with-files // 递归地强制删除该目录以及该目录下的文件

// 3. 文件移动 mv
mv ./source/a.txt ./target
mv -f ./source/a.txt ./target  // 移动并强制覆盖里面的同名文件
mv -n ./source/a.txt ./target  // 移动并不覆盖里面的同名文件

// 4. cp 复制
cp ./source/a.txt ./target/
cp -R ./source/ ./target/  // 递归复制(复制目录)

// 5. 文件查看 cat head tail
cat ./package.json  // 查看文件的全部内容
head -n 10 ~/.logs/service-a.log  // 查看文件的前10行内容
tail -n 10 ~/.logs/service-a.log  // 查看文件的后10行内容

文件编辑

  • nano
    GNU nano是Linux上最简单的文本编辑器,操作简单,功能也比较初级。对于一些临时和简单的文件编辑操作,我们可以直接使用nano就好。
  • vi/vim vi是Linux上的一款功能强大的编辑器,vim是vi的加强版。vim和emacs都是cli世界中的编辑器王者,如果能够熟练使用,效率完全不输于现代的GUI编辑器(如VS Code)。

进程相关的命令

// ps
ps   // 查看当前用户进程
ps -ax  // 查看所有进程

// lsof
lsof -l   // 查看打开的网络相关文件
lsof -p 2333  // 查看pid=2333的进程打开的文件

// top

// kill
kill 45934
kill -9 45934  // 强杀进程

// grep
lsof -i | grep LISTEN // 找到所有正在被监听的端口

// awk
docker rm ${docker ps -a | awk 'NR>1 {print $1}'} // 删除所有的docker容器
chmod +x ${ls -al | awk 'NR>1 {print $9}'} // 为当前目录下的所有文件添加可执行权限

image.png

1.2.3 Bash编程基础

1. 变量

image.png

注意:=两边不能有空格

image.png

image.png

2. 运算

image.png

image.png

3. 条件语句

image.png

image.png

4. 循环语句

image.png

5. 函数

image.png

image.png

6. 重定向

image.png

7. 交互式程序

image.png

1.3 Node CLI

1.3.1 CLI参数处理-引入Commander.js

image.png

1.3.2 CLI友好的交互方式-引入Inquirer.js

image.png

1.3.3 CLI友好的输出方式(醒目的错误提示、关键词搜索高亮等)-引入chalk模块

image.png

1.3.4 调用其他程序-shell.js、execa

image.png

shell.js:对bash命令提供了跨平台的封装,可以同步的获得命令结果。
execa:调用结果Promise化,跨平台支持shebang,能获取进程结束信号,优雅退出,更好的Windows支持等等。

1.3.5 拆解CLI设计-以脚手架为例

image.png

1.3.6 扩展阅读-ink和oclif

  • ink:关注CLI的视图层,使用React编写CLI界面的功能
  • oclif:从工程角度封装CLI开发的复杂性(提供Plugin机制,便于扩展;提供预定义的生命周期;更紧凑的工程结构)

2. 规范

image.png

image.png

image.png

2.1 ESLint

image.png

image.png

2.2 Stylelint

image.png

2.3 Prettier

image.png

Prettier vs Linters

image.png

2.4 npm包的版本

image.png

image.png

2.5 自动化的npm包版本控制和Changelog

release-it image.png

2.6 其他规约

2.6.1 ignore - .gitignore和.npmignore的原则

让git忽略对哪些文件的追踪以及让npm忽略对哪些文件的打包。

image.png

image.png

2.6.2 .npmrc-对npm的配置

image.png

image.png

image.png

2.6.3 .vscode、.editorconfig - 如何利用编辑器配置,保持团队代码风格统一

image.png

image.png

3. 质量

  • code review
  • 自动化测试
  • 单元测试
  • E2E测试
  • 测试驱动开发
  • 监控异常上报

4. 工程设计

image.png

5.构建艺术

image.png

5.1 Babel

babel的源语言是JS,目标语言还是JS,总的来说是将高版本的js转换成低版本的js。

image.png

5.1.1 Babel的作用

  • 作用1:语法转换,比如将ES6中的箭头函数转换为低版本浏览器能理解的函数。

image.png

  • 作用2:Polyfill 腻子,补丁,解决高低浏览器之间的差异,可以让老环境支持新的api
  • 作用3:源码修改

image.png

5.1.2 Syntax 即 ‘语法’

语言级的某一种概念的写法,不可被语言中的其他概念实现。比如

image.png

5.1.3 Feature 指API

实例方法、静态方法、全局对象等,可以被我们自己实现。比如

image.png 我们可以使用低版本代码实现promise。

5.1.4 plugin 插件

babel 本身不会对代码做任何的操作,所有的功能都靠插件实现。

有哪些插件?

image.png

5.1.5 preset 插件集合

一组插件的集合。

image.png

5.1.6 ECMAScript 新特性的诞生

image.png

具体信息见官网:www.babeljs.cn/docs/config…

image.png

5.2 webpack

image.png

5.2.1 webpack的工作流程

  1. 初始化配置
  2. 准备工作(初始化Plugin等)
  3. resolve源文件,构建module
  4. 生成chunk
  5. 构建资源
  6. 最终文件生成

更多的信息见官网:webpack.docschina.org/

推荐关于 tree-shaking 的一篇文章:你的Tree-Shaking并没什么卵用

6. 持续集成与部署

6.1 CI/CD 简介

  • CI - 持续集成

image.png

image.png

  • CD - 持续交付、持续部署

image.png

image.png

image.png

6.2 CI/CD 的实现

image.png

image.png

6.2 Github Actions

image.png

Github Actions 特点:

  • Github 提供慷慨的计算资源
  • 广泛支持各种语言和框架
  • 实时日志,为你的构建行为提供丰富的反馈
  • 可以自由地创建和分享 Actions

image.png

Github Actions 的使用

image.png

image.png

image.png

具体例子见 Next.js 官方应用例子。

6.3 CI 平台,以Jenkins 为例

image.png

image.png

image.png

image.png

image.png

6.4 发布策略

6.4.1 前端发布策略

静态资源的发布,涉及到缓存和资源版本号的问题。 image.png

image.png

6.4.2 后端发布策略

image.png

image.png

image.png

6.5 多环境发布

常用环境有dev、test、pre(预发布环境)、prod(生产环境)。

环境的隔离和切换

image.png

image.png

多环境的配置

image.png

6.6 虚拟化:Docker

image.png

Docker的基本操作

image.png

image.png

DockerHub是Docker的NPM仓库。

image.png

6.7 虚拟化:Kubernetes 即K8s

image.png

image.png

7. GIT

代码管理工具 Git:git-scm.com/book/zh/v2

image.png

image.png

7.1 Git commit 规范

image.png

image.png

Commit message 的格式:

<type>(<scope>): <subject>
<空行>
<body>
<空行>
<footer>

上面就是AngularJS目前的Commit规范,相信第一次接触的话不免会有些头大,这时如果有什么能Step by Step的提醒或者可视化的演示就好了。那么 Commitizen 就诞生了。

7.2 标准化Git的Commit Message 的工具:Commitizen

大量的代码提交,必然会产生大量的commit log,而每一次commit是阶段性的Ending,应记录着这一阶段所完成的事以及关注点,尽可能详细具体;且提供更多的历史信息,方便快速浏览;可以过滤某些commit(比如文档改动),便于快速查找信息;可以直接从commit生成Change log。所以log的格式就是关键所在,而Commitizen可以完美的解决这些问题。

7.2.1 Commitizen是什么?

是一个格式化commit message的工具。它的安装需要NPM的支持,NPM是Node.js的包管理工具,所以首先安装node.js,下载对应系统的包,安装即可。

image.png

安装完插件之后,修改完项目代码后,执行 git add . 上传到暂存区,本来下一步是执行git commit -m ,但是我们不再使用git commit -m方法,而是git cz,将会出现交互式选项,让你选择或者输入信息,给你一个完善的commit message。示例动图:

1966717-1dbd6294bb208b46.webp

7.2.2 如何自定义commit message 文档的格式模板-customizable 插件

image.png

~ vi .czrc

~ vi .cz-config.js 内容如下:

image.png

7.2.3 commit message 增加图标的插件 - gitmoji

npm i -g gitmoji-cli
在执行完 git add .操作之后,执行 gitmoji -c,选择需要的图标

image.png

7.3 Git Hooks

客户端 Hooks

pre-commit:执行git commit 命令时触发,常用于检查代码风格
pre-push:执行 git push命令时触发,可用于执行测试用例
prepare-commit-msg:commit message 编辑器呼起前
default commit message创建后触发,常用于生成默认的标准化的提交说明
commit-msg:开发者编写并确认commit message后触发,常用于校验提交说明是否标准
post-commit:整个git commit 完成后触发,常用于邮件通知、提醒
applypatch-msg:git am提取出补丁并应用于当前分支后,准备提交前触发,常用于执行测试用例或检查缓冲区代码

pre-applypatch:git am提交后触发,常用于通知、或补丁邮件回复(此钩子不能停止git am过程)
pre-rebase:执行 git rebase 命令时触发
post-rewrite:执行会替换 commit 的命令时触发,比如 git rebase 或 git commit --amend
post-checkout:执行 git checkout 命令成功后触发,可用于生成特定文档,处理大二进制文件等

服务端Hooks

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

Husky

安装:npm install husky lint-staged --save-dev 配置:

// package.json
{
    "husky":{
        "hooks":{
            "pre-commit":"npm test",
            ...:...
        }
    }
},
 "lint-staged": {
    "**/*.{js,jsx,es6}": [
      "eslint --fix --quiet",
      "git add"
    ]
  },

8. 效率工具

8.1 使用USB连接调试

ios真机调试方法、安卓真机调试方法、devtool调试方法。

8.2 ‘无线’调试工具-weinre

npm install -g weinre

image.png

8.3 在移动端调试

主流的移动端devtool:vConsole 和 eruda。 具体的调试方法见官网介绍。

8.4 使用代理服务器(抓包工具)调试

image.png image.png

Charles 的 mapLocal和map Remote

image.png

Charles 的 rewrite

image.png

8.5 如何在公网访问本地服务

image.png

为什么要做内网穿透

  • 部署本地服务,只能在内网共享
  • 专门部署服务器测试环境,太复杂,性价比不高
  • 方便代码分享和测试
  • 立刻生效,避免重复部署
  • 不需要额外的服务器
  • 不需要配置DNS、防火墙

localtunnel 实现内网穿透

localtunnel可以将内网服务器暴露到外网服务器(将我们本地电脑的项目暴露到互联网供用户访问)。

  1. 内网穿透是什么? 对于前端领域的同学来说,指在公网上访问到部署在本地的服务器上的项目。 应用场景:前端同学在公司内网部署了一个项目,老板在外出差想访问我在本地的一个项目,这时候百年可使用内网穿透,使用公网访问本地启动的服务。

  2. 工具localtunnel 生成唯一可在公网访问的url,该url会代理本地运行的web服务请求,localtunnel是部署在国外的,访问比较满。 优势:部署方便,不需要部署测试环境,为了方便向世界暴露你的项目,而且修改起来也是很方便。

3.使用方法 全局安装localtunnel npm install –g localtunnel 启动服务 lt --port 8000 lt:localtunnel的缩写,后面端口表示本地项目启动运行的端口。 安装localtunnel之后,可以使用lt --help查看localtunnel命令,端口是必选的。 例如:启动本地一个react项目,端口号为3000 使用localtunnel实行内穿透: lt –p 3000 tunnel.svrx.io –s happy 在公网上的地址:happy.tunnel.svrx.io

image.png localtunnel 也可以植入本地服务中,默认当服务启动时即localtunnel开启。

image.png

8.6 随机数据的生成 -mock.js

mock.js github.com/nuysoft/Moc…

8.7 json-server 模拟restful api

一个在前端本地运行,可以存储json数据的server。 通俗来说,就是模拟服务端接口数据,一般用在前后端分离后,前端人员可以不依赖API开发,而在本地搭建一个JSON服务,自己产生测试数据。

顾名思义,json-server就是个存储json数据的server。 json-server网址:json-server - npm

8.8 Server-X 一个平台代替前面所有工具

前面出现了很多前端本地开发或者调试阶段的小工具,如:

image.png

试想现在你要换一台新电脑或者重装新系统了,你还得一个个把它们重新安装回来。 况且大部分这样的工具是无法根据工程进行独立配置的, 也就是说你在不同项目之间切换时还需要手动修改你的开发工具配置。 这些都是一些强迫症患者如作者本人无法忍受的。

总结一下平时搞开发的时候一些习以为常但仔细一想又挺麻烦的场景:

  • 你必须手动安装各类工具软件以丰富你的本地开发环境
  • 这样的本地开发环境无法拷贝或者很难拷贝,无法分享
  • 每种工具都要单独配置,且配置基本不是按照项目隔离的,切换项目时经常需要修改配置
  • 有时候你的需求并没有合适的工具来满足,自己写一个又太麻烦
  • 写一个项目要同时打开 N 种 工具:本地服务器、mock 服务器等
  • 经常还需要不断重启这些工具以刷新配置
  • ……

基于以上以及一些其它痛点,便出现了 server-x。 更多信息参考:zhuanlan.zhihu.com/p/87684011

server-x 的特点

  • all in one 整合所有单一功能
  • 安装简单
  • 配置简单,一键启动
  • 可扩展性强

image.png

svrx 安装和包管理

image.png

svrx 常用指令

image.png

svrx 参数配置

image.png

image.png

9. 总结

9.1 前端工程化是什么

  • 工程化是一种思想,而不是技术;
  • 可复用的、用来给我们工程开发提效保质的一套标准流程。

9.2 如何进行前端工程化

9.2.1 技术选型

  • 从产品出发

    • 短生命周期 VS 长生命周期
    • 探索类 VS 稳定类
    • 边缘线 VS 生命线
  • 从用户出发

    • 使用环境(比如浏览器、wifi等)
    • 使用频率
  • 从开发团队出发

    • 技术背景
    • 团队规模
    • 人员流动性
  • 从技术本身出发

    • 该技术的维护团队怎么样
    • 社区氛围
    • 代码质量

9.2.2 代码规范

  • clean code
    • 逻辑正确
    • 简洁明了
    • 清晰易读
  • 练习写好代码
    • 先思考再下手
    • 工具辅助(eslint等工具)
    • code review
    • 阅读优秀源码
  • 白板手写代码
    • 熟能生巧
    • 用函数封装
    • 不用纠结api的名字
    • 字尽量整齐
    • 行间距要大
    • 要将思路说出来

9.3 Git 最佳实践

  1. 确保自己阅读过git文档:git-scm.com/book/zh/v2
  2. 要经常提交 commit often git rebase -i 合并多次提交内容
  3. 当你突然发现什么都不见了,要冷静对待,先确保当前进度的保存,然后开始寻找 git refloggit reset/rebase/cherry-pick,少数情况可能会用到 git stash list
  4. 不要修改远程分支的 commit 历史,慎用 git push -f,想清楚再 push
  5. 使用一种规范的 workflow(feature branch workflow 和 GitFlow workflow)
  6. 使用规范的 commit message
  7. 随时保持和远程分支的同步 image.png

9.4 性能测试

这里的性能指的是代码性能,非页面性能。使用 Benchmark 基准测试。

image.png