我正在参加「启航计划」

布景

公司现在基于多事务部门,许多事务组件和功用逻辑都具有较高的普适性,但与此同时各事务部分和开发人员缺少必定的交流渠道,更多的是在遇到对应需求时会简略内部评论一番,当了解到其他事务部分存在落地的计划时,再进一步进行沟通交流。

这种办法,总体来说仍是比较原始的,不论从沟通办法的功率来说,仍是关于组件事务逻辑的深化了解都是十分低效的。因而,关于探究一种高效的、简略的、现代化计划是十分有必要的。

咱们想要的结果是(任务目标):

  1. 不同的事务渠道开发的组件可以最大程度复用;
  2. 新人可以快速了解通用组件,提高开发功率

这也便是本系列文章的实在布景,也是我着手担任的项目,相关文章会依照系列方法输出,并保证文章内容都是在实在事务中的实践总结。

扼要阐明

作为本系列的榜首篇文章,其定位和效果也是相当明晰的:

  1. 搞清楚前端组件化是什么?
  2. 搞理解组件化要怎么做?
  3. 考虑怎么把组件化做的更好?

前期首要以第1、2两点作为履行方向进行探究,在根本理解了什么是组件化以及怎么完成自己的组件化之后,进一步探究、对比、研讨、考虑怎么完成高效能的组件化计划。

前端的开展路径

在互联网早期阶段,传统的开发方法中,往往是把前端的网页代码和后端的程序代码混合在一同,凭借某种模板技能(如 JSPASPPHP)来在服务器端动态生成 HTML 页面。

在这种开发方法下,网页的每次改动都需求前后端人员一同参与才干完成,网站前后端的开发人员需求很大的沟通本钱、和谐本钱。企业招人的时分,也不得不招一些既懂前端又懂后端程序员,来减少前后端开发人员的抵触。

可以发现这种方法是十分低效的。

现在盛行的前后端别离的开发方法,便是让后端只担任给前端提供数据,由前端担任整个页面的模板渲染、数据填充以及交互逻辑。

前后端别离之后,人们发现前端现已不再是传统意义上的网页了,它乃至还可以做成一个手机运用,或许做成是微信小程序那样的小型运用,它更接近于传统的 B/S(客户端/服务器)架构,且依然具有网页轻量级、无需下载和装置的优势

什么是组件化

在前后端别离的现代开发方法下,以ReactVue为例,涌现了许多优异的现代化的前端结构,得益于新技能的开展,SPA 运用现已相当老练,该开发范式也是相当普遍。

伴随着这种技能行为,组件化开发也是应运而生,作为一个十分惯例的方法,环绕几点阐明:

  1. 便利复用(许多事务代码、功用代码都不可避免有所重复,关于组件的复用运用,可谓效果很大)
  2. 便利保护(假如许多的事务代码与功用代码耦合一同,关于代码的日后保护和功用拓展都有着很大的局限性和缺乏)
  3. 功用细分、专注、责任明确(组件的中心准则便是,一个组件只做一件事,并且其不应该是有上下强相关耦合性的,可以随用随取,做到责任单一,关于日后功用迭代和代码保护优点都是清楚明了的)

就现代前端而言,我觉得组件化已不单单局限于 UI 组件层面,它涉及面更广、更全、也更系统化,相似 hooks 的功用和事务逻辑封装,东西类的运用封装,构建东西、脚本代码等,全部契合其独立思想的都可称为组件化。

为什么需求组件化

组件化的目的:

  1. 为了让各功用和事务逻辑可以被复用,以减少重复的代码。
  2. 可以更好地使团队分工协作,不同的人担任编写不同的组件,提高开发功率。
  3. 责任单一也更便利功用的迭代拓展与保护,关于接手的开发人员也能下降不少上手本钱

关于需求开发杂乱的大型运用的企业来说,组件化开发能极大地提高开发功率,它让前端开发团队能高效地完成作业,是一个十分有用的技能。

简略来说便是两个关键词:“复用”、“易保护

代码拆分也好,责任单一也好,根本都离不开这两词,这也正式组件化的中心点。咱们做这些事,便是为了之后遇到相似需求和功用的时分减少代码的开发,可以快速重复运用。而关于组件在日后随着功用和事务的开展、包含咱们关于组件代码健壮性的提高,都会进行不断的迭代,保护性的重要性也是不言而喻的了。

根本目标

环绕中心述求可以进一步细化整理,咱们希望它可以这样:

  1. 可以环绕根底组件、事务组件,以及东西类的定位进行划分
  2. 项目计划要满足简略明晰,保证新人上手本钱满足低,可以快速投入开发运用
  3. 组件的可保护性需求有保障
  4. 严格的标准和工程化保障
  5. 支撑查看API、示例的文档网站
  6. 实在开发环境的模拟调试和开发
  7. 可以以npm包的方法进行引证运用
  8. 牢靠的多包项目办理、多包版别办理
  9. 满足优异的性能体现

技能布景

首要,以公司实际项目为布景考虑,咱们的技能栈现在首要环绕 vue2 相关生态进行前端 web 后台类系统的开发。因而,首要计划规划也要以此为根底导向进行探究。

就现在而言,咱们的组件首要包含可复性较高的事务组件以及一些通用功用组件,也包含一些东西类。组件开发首要依靠于iview根底组件和lodash东西库,部分特别事务有运用到monaco-editorcodemirror等。

因而,现阶段咱们公司的技能栈相关生态首要为 vue2,本系列也会以公司的vue2项目阅历为依托进行记录。不过结合当下前端全体快速开展的实际情况下考虑,在项目施行落地之后,对相关生态具有满足明晰地把握之后,以vue3react为技能布景的探究也值得进一步探究研讨。

包依靠

咱们公司当时项目渠道首要依靠分析,如下:

  • 中心三大件:vue/vue-router/vuex
  • UI 类:view-designcodemirrormonaco-editorvue-echartsvuedraggble
  • 东西类:lodashdayjsuuid

环绕以上技能相关生态,做到对各部分及功用运用的二次封装办理

首要 API 及实际项目代码分析:

  • slot:组件拆分、UI 布局、自定义展现区域的好办法
  • props:父组件向子组件传递参数
  • ref:父组件获取子组件办法、属性
  • emit:子组件向父组件传递参数,触发父组件绑定事情办法
  • provide/inject:多级子父组件传值
  • vuex:第三方状态办理(需求考虑单一组件的可保护性)

总的来说组件封装较频频运用的属性办法为props/slot/emit/ref,也是咱们项目中许多选用的办法。

vuex 的运用需求慎重考虑,具有必定的耦合性,需求进一步探究分析。

关于更优的办法探究值得考虑,中心点为责任单一独立、耦合性低,便利保护。

功用/事务组件

事务组件不同于功用组件,其具有必定的运用布景和条件限制。以咱们运用的 iviewantd等UI组件为例,其提供了许多的功用组件,包含但不限于表单功用组件Table列表功用组件多选/单选功用组件日期功用组件等等,它只提供某一类的通用功用,并抽象封装为一个详细的功用组件。

而相关于事务组件来说就有少许不同了,事务组件首要必定聚集于一个明确的事务场景,其终究完成或许是交融了多个功用组件的组合,也或许是结合一些插件独立完成的某一特别功用。

当时项目已存在的一些事务组件分析:

  • ProTable功用组件:由单个FilterBtn组件Table组件Pagination组件,从而组合成全体的一个组件(包含列表、挑选、分页)
  • ComSqlTipTree事务组件:运用频率相当高的 ComSqlTipTree组件,也是集合了众多子组件的一个组合(涉及到对Input的高档封装、Select挑选、拼音匹配、列表展现等,该组件专门用于公司中心功用挑选类查找时的运用)

组件办理考虑

  1. 根底组件类:可以参照iviewantd等UI组件库的办法进行保护办理,聚集于功用相关,归于较小型的组件,统一保护办理。
  2. 事务组件类:可以参照pro-component高档组件的办理方法进行处理。
  3. 东西类:可以参照lodash的办法进行保护办理

pro-component的办理方法为许多基于根底组件封装而成的高档组件,如:pro-layoutpro-tablepro-form等,每个组件可以作为独立的npm包作为依靠运用,彼此独立、互不影响。

再考虑到关于东西类的办理保护,全体考虑下来,根本确认可以为多包办理的方向(Monorepo

技能调研

环绕项目技能布景和目标规划,进行相关技能调研。

相关开源项目分析

  1. 需求考虑的方向是:关于 vue2.x 版别的组件化计划,哪种更为适宜(现在市道上有许多的vue3组件库)
  2. vue2 关于 TS 的考虑 (vue2对ts的支撑性一般,是否支撑视情况而定)
  3. props 参数 API 的文档、demo演示,文档网站建造的考虑
  4. 目录规划、工程标准、构建发布流程
  • element

    • monorepo,归于比较传统的单一包办理项目
    • 比价经典的vue2组件库项目,文档网站风格很不错
    • 首要运用 js + vue开发,构建由webpack处理
    • 文档网站由自身组件开发建立,结合webpack loader完成对markdown文件的编译及demo示例的渲染
  • vuetify

    • lernajs + yarn + workspace 的计划,标准的 lernajs + yarn 用法
    • vue2.x + ts 写法,组件许多以 JSX 完成,具有很好的参考学习价值(vue2 中对 TS 的运用)
    • 文档网站由自身组件自行开发建立,项目代码较多,有必定的上手本钱
  • element-plus

    • vue3 的项目,pnpm + workspace 的计划,全体思路和规划十分现代化
    • 组件完成由 vue编写开发,相关脚本代码由 TS编写,整个项目为 TS项目
    • 多包目录规划、组件和文档目录规划合理
    • 相关构建东西包含 rollupesbuildvite
    • 文档网站由vitepress构建,并自行编写了处理markdownvue demo的插件进行处理(vitepress只支撑vue3
  • idux

    • vue3 的项目,pnpm + workspace 的计划,技能都比较新
    • 版别操控由 lerna办理
    • demodocs的目录办理很不错,需求合作脚本完成终究的网站路由和渲染
    • 文档网站由 vitepress + 自身组件构建,并合作各种脚本完成对应功用
    • 构建东西首要为 gulp
    • 组件开发首要为 tsx方法

monorepo 是什么

  • Monorepo:一切依靠库完全放入一个项目工程
  • Multirepo:多个依靠包独立进行 git 办理

monorepo 是把多个项目的一切代码放到一个 git 库房中进行办理,多个项目中会有同享的代码则可以分包引证。整个项目便是有 root 办理的 dependencies 加上多个 packages,每个 package 也可以在自己的效果域引入自己的 dependencies

该计划可以很好的帮助咱们处理不同作业区关于相同依靠的办理,以及咱们在开发时,包彼此间依靠的办理。

monorepo + lernajs + yarn

Lerna 是一种东西,针对运用 gitnpm 办理多软件包代码库房的作业流程进行优化。

Lerna 有两种办理项目的方法:

  • Fixed/Locked 方法 (默许): 一切的包共用一个版别号。
  • Independent mode:不同包独立运用自己的版别,咱们一般选用这种办法。在初始化的时分指定 --independent 参数

一般而言,在pnpm未呈现前,相关workspace概念根本是合作 yarn一同运用(yarnworkspace功用),由于 npm7.x之前是没有 workspace概念的,所以在很长的一段时间里,多包办理计划 monorepo都是与 yarn一同合作运用。

他处理了以下问题:

  • 多事务组件、彼此依靠、无法复用
  • 发包流程杂乱、版别办理痛苦

依靠办理

在作业区 packages 下面咱们有这些包:iviewpro-sqltiptreecomponents,其 package.json 中的 name 定义分别为@ah-ailpha/iview@ah-ailpha/pro-sqltiptre@ah-ailpha/components,在咱们彼此装置包时,lerna 东西可以帮咱们以用软链接的方法直接运用。(关于软链接的概念可以参考 npm link,以及pnpm的底层完成逻辑)

# 向 module-2 中添加 module-1 作为依靠
$ lerna add module-1 --scope=module-2

版别办理

关于monorepo的多包场景,lerna另一大中心功用便是可以很好的帮助咱们办理每个包的版别,经过运用 lerna version指令即可(可结合指令式交互快速办理版别)

lerna version 在背后为咱们做了这些事:

  • 辨认出自上次发布以后更新过的包;
  • 提示挑选新版别;
  • 修正包的元数据来反映最新发版(修正包的版别号),在根目录和每个包里面运行生命周期脚本;
  • 对提交打 tag;
  • 推送到长途代码库房。

monorepo + pnpm

pnpm现在也支撑workspace的概念了作业空间(Workspace),假如是常常重视技能社区论坛的,相信你对pnpm现已有过了解了,pnpm由于其优异的性能体现,以及其对monorepo的支撑也更简略便利,使得现在许多知名的开源项目都选用了该计划,如 Vue3/Vite/VueUse/Element Plus/Next.js/Astro等等。

pnpm 内置了对单一存储库(也称为多包存储库、多项目存储库或单体存储库)的支撑, 你可以创立一个 workspace 以将多个项目合并到一个库房中。

一个 workspace 的根目录下必须有 pnpm-workspace.yaml 文件, 也或许会有 .npmrc 文件。

怎么高效的运用 pnpm,需求了解几个常用的根本指令:

  • --filter:过滤,过滤答应您将指令限制于包的特定子集,一般用于 packages/* 下面的子项目。
  • -C:在 <path> 中启动 pnpm ,而不是当时的作业目录。
  • -r:装置在一切 packages 中(一般合作--filter指定项目目录)
  • -w:表明把包装置在 root 下,该包会放置在 <root>/node_modules

pnpm同样可以完成对包依靠的办理,相似lerna相同,经过软衔接的办法相关到子项目,可以极大的便利咱们关于多项目依靠的办理。

pnpm add <package-name> --filter <target-package-name>
# 比如要将lodash装到package-a下
# --filter 后边可以为目录称号也可以为 package.josn 的 name 称号
pnpm add dayjs --filter @ah-ailpha/package-a
# 向 module-2 中添加 module-1 作为依靠
pnpm add module-1 --filter module-2

lerna / changeset 版别办理分析

不论关于 yarn仍是 pnpm来说,都只是关于作业空间 woekspace的多包办理,关于多依靠办理,pnpm现在可以支撑,而yarn是需求lerna进行帮忙的。

可是关于各包的version版别操控,两者都不直接参与办理,只能运用第三方东西进行处理。

lerna

现在已知的比较老练的计划有lerna,也是运用比较频频的,优点是其功用比较全面,但也存在一些明显的问题

  1. 不能和pnpm很好的适配,lerna 自身不支撑 workspace 协议,导致基于 pnpm 开发的一些库房无法运用
  2. lerna version 根据 commit 以及 tag 更新出来的包版别不契合预期
  3. 整个包的体积很大,依靠特别多(轻量版lerna-lite)
  4. 相比较pnpm而言,lerna运用起来仍是比较的粗笨、繁琐

changeset

Changesets 是一个用于 Monorepo 项目下版别以及 Changelog 文件办理的东西(现在一些比较火的 Monorepo 库房都在运用该东西进行项目的发包例如 pnpmmobx 等)

changesets 首要关心 monorepo 项目下子项目版别的更新changelog 文件生成包的发布

一个 changeset 是个包含了在某个分支或许 commit 上改动信息的 md 文件,它会包含这样一些信息:

  • 需求发布的包
  • 包版别的更新层级(遵从 semver 标准)
  • CHANGELOG 信息

总的来说,changeset的作业内容仍是比较明确的,咱们需求直接参与的便是包版别的办理与发布,关于changelog的文件生成会由脚本自动处理,咱们无需关心(需求依照commitlint标准提交message,这儿到时咱们经过工程化的办法进行操控即可)

版别操控办理小结

  1. 运用 yarn + monorepo的项目一般运用lerna合作进行依靠和版别办理
  2. 选用 pnpm + workspace计划的 monorepo,可以挑选运用 changeset进行版别办理操控,从而快速建立一个完整的 monorepo项目。

结尾

本篇文章算得上是建立本项目的一些前期探究,在从0到1的过程仍是比较迷茫的,运用什么计划,哪种计划适宜我,在找到适宜的计划时又发现并不是我喜欢的技能方向时,怎么做出挑选,以及怎么挑选最优解等等,这些都是在我在实践的过程中所阅历的。

总的来说,我比较重视技能社区和开源项目,一般呈现了什么新的技能结构时,我也能及时的了解和测验。在针对怎么运用的这个问题上,经过结合官方文档和开源社区各种demo模板,也能略知一二,再简略上手运用对比下,大致可以有所了解,就我个人的项目而言我仍是满喜欢尝鲜的,觉得好用、不错就会直接开整,遇到问题就测验处理,也算是在这个过程中学习了。不过,关于公司的项目来说,总体偏稳定版、技能老练度高、社区活跃的进行挑选,在遇到问题时也能发现相似的处理计划。

monorepo算是我很早之前就打算研讨和测验的方向了,苦于一向没有适宜的时机(懒~),在没有项目的推动下,自己也缺少必定的动力,刚好现在公司在推动这个事情,并且仍是由我进行担任,也算得上是个不错的时机了。

在开始之前我自己之前关于lerna是有一点了解的,因而,最开始在进行技能调研的时分也是大致环绕这个方向进行的,期间也看了不少开源项目的规划和运用办法,根本上算是入门了,不过,在我自己进行demo测验以及简略运用后,发现lerna的确有许多不太便利、不易用的当地,尤其是关于多项目指令的支撑,远不及pnpm来的便利。

pnpm关于我来说并不算生疏,我在去年就开始在用了,全体仍是比较顺手的,也比较喜欢,只是关于pnpm + workspace + monorepo这种办法没有实践过,不过在此之前却是了解过不少相关的文章,形象较深的是介绍 vue生态的多包办理过渡到pnpm + workspace的文章,自己正好也一向想找时机测验来着。

因而,在运用lerna发现一些较大的短板之后,我也是顺势过渡为pnpm + workspace的计划来了,以及在后期测验了关于版别办理操控的changeset计划之后,终究确认的技能道路为pnpm + workspace + changesetmonorepo多包办理计划

实践篇相关文章见下一篇,欢迎重视(现已在写了~)。

材料

  • pnpm
  • pnpm-workspaces
  • element
  • vuetify
  • element-plus
  • idux
  • lernajs
  • Lerna 运行流程分析
  • pnpm 多包办理项目-爱代码爱编程
  • Changesets: 盛行的 monorepo 场景发包东西