NUTUI-React底层架构工具升级 -- 巧用Shell脚本

NutUI 是一款京东风格的移动端组件库。NutUI 目前支持 Vue 和 React技术栈,支持Taro多端适配。本次架构升级主要介绍NutUI-React在npm到pnpm的升级迁移、巧用Shell脚本和构建工具Vite2升级到Vite4的过程中所经历的踩坑之旅。作为此系列的第二篇文章,希望大家可以学会并熟练使用Shell脚本。

一、前言

首先在介绍Shell脚本之前,我们一定要先了解清楚Shell是什么,在开发平时的项目中引用Shell可以帮助我们解决什么问题,是否可以给我们带来开发效率的提升,以及作为前端工程师要学习并学会使用Shell是否具有价值?

好,带着这些疑问,我会在后面的文章内容中逐一给大家解惑。废话不多说,发车啦~

二、Shell基本概念

1.Shell是什么?

我们先看一个比较官方的介绍:

  • Shell 可以是一个程序,提供一个与用户对话的环境。是计算机提供给用户与其他程序 进行交互的接口

  • Shell 是一个命令解释器,当你输入命令后,由 Shell 进行解释后交给操作系统内核(OS Kernel)进行处理

刚接触shell的家人们估计看完后虎躯一震,这是啥意思啊?没关系,我来把它说的通俗一点:大家就可以把Shell 当做是一个壳,或者可以理解成一个"核桃壳 ",里面包裹的"核桃仁 "就是操作系统内核

Shell本质上就可以理解为是操作系统内核提供的一个接口,比如咱平时用的控制台就是一个命令行的Shell。说白了,Shell就是人机互动的一种方式,使用操作系统的用户和计算机硬件交互的一种方式。

我们再来看一张图,很清晰的表示了Shell与内核、操作系统之间的关系:

怎么样,有没有一种很通透的感觉~

2.Shell的种类

下面是一些历史上比较流行的Shell种类,大家简单看一下了解即可:

  • Bourne Shell (sh):由Stephen Bourne在1977年开发,是Unix的默认Shell,也是很多其他Shell的基础。它是一种较为基础的shell,不支持交互式界面、命令行编辑等高级功能。
  • C Shell (csh):由Bill Joy开发,类似于C语言的语法,支持命令行编辑、命令别名等高级功能。
  • Korn Shell (ksh):由David Korn开发,是Bourne Shell的扩展,同时继承了C Shell的一些优秀特性,支持命令行编辑、命令别名、作业控制等功能。
  • Bourne-Again Shell (bash):由Brian Fox和Chet Ramey开发,是Bourne Shell的升级版,兼容Bourne Shell,并添加了许多新功能,如命令补全、命令历史、自动提示等。
  • Z Shell (zsh):由Paul Falstad开发,是Bourne Shell的扩展版本,支持命令补全、模式匹配、参数替换等高级功能,同时也可以兼容Bourne Shell和Bash。
  • Fish Shell (fish):由Gustav "Goose" Norstrom开发,它的设计目标是简单易用,具有友好的交互式界面和自动提示功能,支持命令补全、模式匹配、命令历史等高级功能。

除了上述几种Shell外,还有许多其他的Shell,如tcsh、ash、dash等。每种Shell都有其独特的特点和用途,在不同的环境下选用合适的Shell可以提高工作效率和命令行使用体验。

这里我们用到的Shell种类大多数都是bash,也是目前大多数Linux发行版以及macOs操作系统的默认Shell。

Bash 使用了一种与图形界面(GUI)完全相反的方案:通过纯文本的控制台进行控制,它的主要交互方式通过键盘输入文本,文字反馈来实现人机交互。

很多人估计会说了,界面这么丑,是不是Bash马上就要过时了呀!No,no,no...恰恰相反 Bash 在开发领域应用反倒越来越广泛。正因为其最大的优势就是简单易用,虽然它的显示效果不如 GUI,但一旦熟练后其操作效率远远大于 GUI!

3.Shell的优势

这里我也是总结了几条使用Shell脚本编写代码的优势:

  • 自动化:使用Shell脚本可以自动化执行一系列命令,自动完成一些繁琐的工作,比如打包、压缩、部署等。
  • 快速:使用Shell脚本可以快速地执行一些操作,避免了手动输入命令的繁琐过程。
  • 可扩展:使用Shell脚本可以根据实际需求编写不同的脚本,从而扩展功能和应用场景。
  • 可重复性:使用Shell脚本可以确保执行过程中不会出现手误,从而保证执行结果的一致性和可重复性。
  • 跨平台:Shell脚本可以在各种操作系统中运行,比如Linux、Unix、MacOS等,从而提高了代码的可移植性和兼容性。

综上所述,使用Shell脚本可以帮助我们提高工作效率、降低出错率、扩展功能和应用场景,从而提升代码的质量和可维护性。

4.Shell的例子

为了让家人们对后文项目中稍复杂的Shell脚本可以有一个更好的理解,这里我先给大家举一个简单的小例子,先练练手~

编写一个Shell脚本名字为hello.sh,脚本输出内容为hello world :

bash 复制代码
#!/bin/bash

# 执行的命令主体
echo "hello world"

#!/bin/bash 就是指定脚本要使用的 Shell 类型为 Bash ,echo就可以理解为前端控制台中的console.log。

怎么样,easy不,我们也可以定义一个变量再输出,像下面这样:

bash 复制代码
#!/bin/bash

# 执行的命令主体
message="Hello World" # message 为变量名
echo $message  # 打印message变量

好滴,Shell的一些基础语法,我就不在这一一介绍了,推荐大家先进入这个网站 shellscript.readthedocs.io/zh_CN/lates... 简单扫一眼,了解下Shell的基本使用。

后面实战开发就要正式开始啦~

三、前端工程NutUI-React巧用Shell脚本实践

1.要解决什么问题?

平时我们在发布NutUI-React组件库版本的时候,都需要发布一个CHANGELOG.md,为了让开发者和用户可以了解项目的演化历史,并知道每个版本都带来了哪些变化。

同时,用户也可以通过查看 CHANGELOG.md 来了解项目的新特性和功能,以及已知的问题和待解决的问题。

这些迭代的新特性和功能的文案,难道需要我们根据提交pr的记录自己一条条的手敲么?或者一个个手动ctrl c + ctrl v么?那就真的妥妥的ctrl c/ctrl v高级开发工程师了。

那有没有什么比较智能化的脚本,可以自动抓取开发者提交pr的记录,并将记录自动生成如上图格式的文案呢?

2.CHANGELOG自动化shell脚本

当然有咯~,下面就是一段用Shell编写的一段自动化的脚本。

这里我们以NutUI-React最新发布的v1.5.1版本为例,执行方法:./gitlog.sh 2023/4/13 1.5.1

这是一个gitlog.sh的bash脚本文件

bash 复制代码
#!/bin/bash

# 提取 某个时间之后的提交信息
latestPublishedDate="$1"
log=$(git log --since="$latestPublishedDate" --pretty=format:%s\ @%an)

## Feat 和 Fix 转小写,句号转空
log=$(echo "$log" | sed 's/feat/feat/i;s/fix/fix/i;s/。//')

# 提交信息进行不区分大小写的排序
log=$(echo "$log" | sort -f)

# 增加 emoji
log=$(echo "$log" | sed 's/^feat/* :sparkles: feat/i;s/^fix/* :bug: fix/i;s/^chore/* 🔨 chore/i;s/^docs/* 📖 docs/i')

# 获取当前日期和迭代版本
version="$2"
today=$(date "+%Y-%m-%d")
todayChangeLog=$(echo -e "# v$version\n\`$today\`\n\n$log")

# 输出结果追加到CHANGELOG.md文件顶部
oldChangeLog=$(cat ./CHANGELOG.md)
echo -e "$todayChangeLog\n\n\n$oldChangeLog" > ./CHANGELOG.md

输出的结果在./CHANGELOG.md文件中:

markdown 复制代码
# v1.5.1
`2023-04-19`


* :bug: fix: 修改inputnumber微信小程序的带小数点的键盘 (#907) @junjun666
* :bug: fix: 修复uploader组件编译xhr报错的问题 (#916) @junjun666
* 🔨 chore: 开发编译兼容taro 3.6.5版本 (#911) @junjun666

估计很多人看到这就滑走了,这么一大串代码是啥子,表示看不懂......别急家人们哈,咱逐行一步步分析,保证大家完全get到~

四、自动化shell脚本逐行分析

1.提取某个时间之后的提交信息

代码如下:

bash 复制代码
# 提取某个时间之后的提交信息
latestPublishedDate="$1"
log=$(git log --since="$latestPublishedDate" --pretty=format:%s\ @%an)

当我们调用脚本文件时,比如上面的./gitlog.sh 2023/4/13 1.5.1,2023/4/13就是参数1,1.5.1就是参数2。

那么对应的在Shell脚本中就可以通过以下变量获取参数:

  • $1 第一个参数
  • $2 第二个参数
  • $N 第N个参数

所以latestPublishedDate="$1"就代表把2023/4/13这个参数赋值给latestPublishedDate这个变量

好滴,我们来看第二行,就可以理解成如下的输出方式:

bash 复制代码
git log --since=2023/4/13 --pretty=format:%s\ @%an

我们把这句命令来拆解一下:

  • git log:这是Git命令的基本部分,用于查看提交历史。log子命令会显示提交的详细信息,例如作者、日期、提交消息等。

  • --since="2023/4/13":此选项用于过滤提交历史,只显示指定日期之后的提交。在这里,它将只显示2023年4月13日之后的提交。

  • --pretty=format:%s\ @%an:这部分是一个高级选项,用于自定义日志输出的格式。--pretty=format: 之后的内容用于定义格式字符串。

    • %s:这是一个占位符,表示提交消息的简短描述(通常是一行)。
    • \ :这是一个空格,用于在提交消息和作者名之间插入空格。
    • @:这是一个普通字符,它将在输出中显示为"@"。
    • %an:这是一个占位符,表示提交作者的名字。

最后我们把log这个变量输出一下,看看输出的结果是什么。

echo "$log"

2.Feat 和 Fix 转小写,句号转空

代码如下:

bash 复制代码
## Feat 和 Fix 转小写,句号转空
log=$(echo "$log" | sed 's/feat/feat/i;s/fix/fix/i;s/。//')

这一句怎么理解呢?有些用户在提交信息时肯定有不规范的地方,比如Feat大写啦,Fix大写啦,或者带句号啊等等

首先sed是什么呢?就是类似流编辑器,对标准输出或文件逐行进行处理。

我们可以先看一个比较基础的例子:

  • s/parent/child -- 将行内第一个 parent 替换为 child
  • s/parent/child/g -- 将行内全部的 parent 替换为 child
  • s/parent/child/2g --同一行,只替换从第二个开始到剩下所有的
  • s/parent/child/ig -- 将行内 parent 全部替换为 child ,忽略大小写

这个时候再回头看我们的语句:

bash 复制代码
sed 's/feat/feat/i;s/fix/fix/i;s/。//'
  • s/feat/feat/i:将输入文本中的"feat"(大小写不敏感,因为使用了i标记)替换为"feat"。这个表达式实际上没有改变文本内容,只是确保了"feat"的大小写一致。
  • s/fix/fix/i:将输入文本中的"fix"(大小写不敏感,因为使用了i标记)替换为"fix"。这个表达式同样没有改变文本内容,只是确保了"fix"的大小写一致。
  • s/。//:从输入文本中删除所有的"。"字符。这个表达式用于去除全角句号。

总结一下就是:这条命令的作用是将 <math xmlns="http://www.w3.org/1998/Math/MathML"> l o g 变量中的文本进行处理,将 " f e a t " 和 " f i x " 统一为小写,并删除所有的全角句号 " 。 " ,然后将处理后的文本重新赋值给 log变量中的文本进行处理,将"feat"和"fix"统一为小写,并删除所有的全角句号"。",然后将处理后的文本重新赋值给 </math>log变量中的文本进行处理,将"feat"和"fix"统一为小写,并删除所有的全角句号"。",然后将处理后的文本重新赋值给log变量。

3.提交信息进行不区分大小写的排序

代码如下:

bash 复制代码
# 提交信息进行不区分大小写的排序
log=$(echo "$log" | sort -f)

sort就很好理解啦,就是排序嘛,-f选项表示"忽略大小写"。

这里再补充一个知识点:|: 管道符号,它表示将前一个命令的输出作为下一个命令的输入。在这个例子中,我们将echo "$log"的输出传递给sort -f命令。

我们再把log这个变量输出一下,会发现此时已经把之前的输出结果进行了一个排序。

4.增加emoji

代码如下:

bash 复制代码
log=$(echo "$log" | sed 's/^feat/* :sparkles: feat/i;s/^fix/* :bug: fix/i;s/^chore/* 🔨 chore/i;s/^docs/* 📖 docs/i')

大家现在再来看这句命令,是不是一下就清晰多咯~简单理解就是通过sed流将输出文本进行一个文案emoji替换

替换结果详见下图:

5.获取当前日期和迭代版本

代码如下:

bash 复制代码
version="$2"
today=$(date "+%Y-%m-%d")
todayChangeLog=$(echo -e "# v$version\n\`$today\`\n\n$log")

上文我们讲过,$2就代表执行命令的第二个参数,因为我们执行的命令是./gitlog.sh 2023/4/13 1.5.1,所以这里的version变量就是1.5.1

再看第二行,作用是为了获取当前日期。date命令是Unix/Linux系统中的命令,用于显示或设置系统的日期和时间。后面的"+%Y-%m-%d"是date命令的一个参数,用于指定输出格式。其中,%Y表示四位数的年份,%m表示两位数的月份,%d表示两位数的日期。因此,该格式表示输出的日期将以 "年-月-日" 的形式展示,例如 "2023-04-21"。所以这里的today变量是"2023-04-21"。

于是第三行的命令就可以进行一个变量名的替换:

-e 参数使得 echo 可以解析转义字符。如果不添加 -e 则会原样输出,添加了 -e 输出则会换行

bash 复制代码
todayChangeLog=$(echo -e "# v1.5.1\n\`2023-04-21\`\n\n$log")

这个时候我们再来看一下todayChangeLog变量输出的结果:

6.输出结果追加到CHANGELOG.md文件顶部

代码如下:

bash 复制代码
oldChangeLog=$(cat ./CHANGELOG.md)
echo -e "$todayChangeLog\n\n\n$oldChangeLog" > ./CHANGELOG.md

cat很好理解就是读取./CHANGELOG.md文件内容赋值给oldChangeLog变量嘛,然后todayChangeLog变量和oldChangeLog变量进行拼接整合,最后一起追加到./CHANGELOG.md文件中,最后我们在./CHANGELOG.md就可以看到我们的输出结果。

最后我们就可以将本地CHANGELOG.md文件的输出结果,直接整体粘贴到我们的github的releases中发布就好啦~方便又高效

五、小结

通过本文,我们了解了Shell脚本如何在前端工程组件库中的应用,并且通过Shell脚本提高了我们的开发效率。

这个时候再回到文章一开始提出的疑问,作为前端工程师需要学习Shell么,学习Shell的意义与价值又在哪里呢?

👉想象一下,你在开发一个网页项目,突然遇到了一个棘手的问题。你如鱼得水地使用各种前端技术,但却被一些重复性和繁琐的任务拖延。这时候,掌握Shell脚本编写技能,就能轻松帮你解决问题!

🌟那前端工程师学习Shell脚本的意义与价值又在哪里呢?

  1. 自动化神器:Shell脚本能让你实现自动化的奇迹。一行命令,搞定繁琐的重复任务,节省你宝贵的时间,让你更专注于前端代码的优化!
  2. 跨平台大师:无论是Linux、macOS还是Windows,Shell脚本都能为你所用。只要你掌握了这门技能,随时随地解决问题不再是梦想。
  3. 与后端无缝衔接:与后端同学进行项目合作时,Shell脚本能让你更加自信。一起交流技术,一起成长,轻松搞定团队协作!
  4. 强化简历:在招聘市场竞争激烈的今天,多一项技能,就多一份竞争优势。学会Shell脚本,让你的简历更加出彩!

六、加入我们

再次期待您早日成为我们共建大军中的一员!一起共建,一起使用!做站内最优秀的开源组件库!

期待您早日成为我们共建大军中的一员!

GitHub:NutUI-VueNutUI-React

欢迎共建、使用!

相关推荐
m0_7482517229 分钟前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·vue.js·ajax
上等猿32 分钟前
Ajax笔记
前端·笔记·ajax
Amo 672934 分钟前
css 编写注意-1-命名约定
前端·css
程序猿online1 小时前
nvm安装使用,控制node版本
开发语言·前端·学习
web Rookie1 小时前
React 中 createContext 和 useContext 的深度应用与优化实战
前端·javascript·react.js
男孩122 小时前
react高阶组件及hooks
前端·javascript·react.js
m0_748251722 小时前
DataOps驱动数据集成创新:Apache DolphinScheduler & SeaTunnel on Amazon Web Services
前端·apache
珊珊来吃2 小时前
EXCEL中给某一列数据加上双引号
java·前端·excel
onejason2 小时前
深度解析:利用Python爬虫获取亚马逊商品详情
前端·python
胡西风_foxww2 小时前
【ES6复习笔记】Spread 扩展运算符(8)
前端·笔记·es6·扩展·运算符·spread