摄影艺术居

摄影艺术居

Pnpm + Turbo 搭建 Web Component Monorepo 组件库

admin 162 62
技术选型

使用Pnpm+Turbo搭建WebComponentMonorepo项目stencil-component-ui组件库

pnpm作为包管理器

Turborepo作为构建系统

Vitepress管理文档

pnpm技术什么是pnpm?它有哪些优势?

pnpm跟npm、yarn一样,都是用于管理Node包依赖的管理器,它是号称新一代的最先进包管理工具。按照官网说法,它相比其他包管理工具,可以大大节约磁盘空间并提升安装速度,创建非扁平化的node_modules文件夹,目录结构很清晰,具体介绍可以参考pnpm官网

pnpm提出了workspace的概念,内置了对monorepo的支持,那么为什么用pnpm取代之前的lerna呢?

这里总结了以下几点原因:

lerna已经不再维护,后续有任何问题社区无法及时响应

pnpm装包效率更高,并且可以节约更多磁盘空间

pnpm本身就预置了对monorepo的支持,不需要再额外第三方包的支持

pnpm搭建menorepo工程

在工程根目录下新建packages目录,并且在packages目录下创建components和icons两个子项目,这里使用stencil脚手架,进入packages目录,根据Stencil官网创建项目

shell复制代码pnpmcreatestencil

有三个选项,直接回车选择第一个components是创建组件库项目的,输入项目名称即可创建项目

分别使用stencil创建了components和icons项目,components是来开发组件库源码的,icons是用来开发编译svg图片和组件的,目录如下

在工程根目录建一个,用于启用workspace:

makefile复制代码packages:-"packages/*"-"docs"

以上指定工作空间内的包依赖关系,packages用于管理源码,docs编写文档,然后执行pnpminstall安装依赖

由于工程根目录不需要发包,需要配置"private":true

在项目中安装包

Pnpm启用了workspace,用Pnpm安装依赖必须指定安装的位置。-w是--workspace-root的别名,即安装到工程根目录,作为所有子模块的公共依赖。也可以用-r递归给每个子模块安装,或者用--filterpackage_name给指定子模块安装。-D是--save-dev的别名,即安装依赖到devDepencies节点下,不指定参数默认安装到depencies节点。

给每个项目起个包名,修改components和icons项目中的name字段为@swc-ui/components和@swc-ui/icons,docs使用vitepress搭建,包名直接用docs

图标库、组件库包安装到docs使用,图标库包安装到组件库项目中使用,使用--filter指定安装包的位置

bash复制代码pnpmadd@swc-ui/components@swc-ui/icons--filter=docspnpmadd@swc-ui/icons--filter=@swc-ui/components

components安装@swc-ui/icons后,新增了"@swc-ui/icons":"workspace:^"

json复制代码"depencies":{"@swc-ui/icons":"workspace:^"}

通过Pnpm提供的WorkspaceProtocol,可以很方便地实现子模块互相引用。在开发的时候,也推荐使用workspace:^,这样可以确保依赖的是最新版本代码。当我们用pnpmpublish发包的时候,Pnpm会将workspace:^替换为实际的版本。

只允许pnpm

当在项目中使用pnpm时,如果不希望开发者使用yarn或者npm安装依赖,可以将下面的这个preinstall脚本添加到工程根目录下的中:

json复制代码"preinstall":"npxonly-allowpnpm"

因为在在Pnpmworkspace模式下npminstall或者yarninstall安装依赖无法兼容,整个工程很可能跑不起来,所以用only-allow库去限制包管理器,当用了其他包管理器,会直接抛异常退出进程。

Turborepo

在项目开发和打包发布,必须先启动icons和components项目编译构建,才能运行docs文档,如果使用pnpm构建,可能需要使用-r或者并行执行,如

json复制代码{"scripts":{"build":"pnpm-r--parallel--filter=./packages/*runbuild","test":"pnpm-r--parallel--filter=./packages/*runtest"}}

专业的事交给专业的工具去解决,而Turborepo就非常擅长实现任务编排

什么是Turborepo?

Turborepo是一个高性能的JavaScript和TypeScript项目构建系统,采用Go语言实现,所以在语言层面上就具有一定的性能优势,可以大大提高monorepo项目的构建速度。

在开发层面,Turborepo抽象出所有繁琐的配置、脚本和工具,减少项目配置的复杂性,可以让我们专注于业务的开发,并且支持使用Yarn、Npm、Pnpm

TurboRepo的优势

1、多任务并行处理

Turbo支持多个任务的并行运行,我们在对多个子包,编译打包的过程中,turbo会同时进行多个任务的处理

对于项目中A依赖于B,B依赖于C,构建串行顺序为C、B、A。Turbo它能够有效地安排任务类似于瀑布可以同时异步执行多个任务,而lerna一次只能执行一项任务所以Turbo的性能不言而喻。

2、更快的增量构建

如果我们的项目过大,构建多个子包会造成时间和性能的浪费,turborepo中的缓存机制可以帮助我们记住构建内容并且跳过已经计算过的内容,优化打包效率。

3、任务管道

用配置文件定义任务之间的关系,然后让Turborepo优化构建内容和时间。

4、远程云缓存

Turbo通过其远程缓存功能,团队成员、CI/CD共享远程构建缓存,以实现更快的构建。

安装到项目

1、在项目根目录下,安装turbo依赖

css复制代码pnpmiturbo--save-dev-w

2、在根目录下添加配置文件,向pipeline字段中配置npmscripts中的命令,比如dev,build命令

json复制代码{"$schema":"","pipeline":{"build":{"depsOn":["^build"],"outputs":[".next/**","!.next/cache/**"]},"dev":{"cache":false,"persistent":true}}}

3、在根目录package配置scripts

json复制代码"scripts":{"dev":"turborundev","build":"turborunbuild"}

以上Turborepo项目就简单配置完成了,Turbo和PnpmWorkspace很好的结合起来管理monorepo项目

Turbo开发环境

当执行npmrundev命令,Turbo会分析Package包的依赖关系,运行@swc-ui/icons、@swc-ui/componentsdocs开发环境,通过配置一行命令就启动了开发环境,不需要手动去执行icon、components、docs的命令

Turbo构建打包

Turbo构建提供了缓存,当执行npmrunbuild全部构建需要花费1分钟06秒,第二次构建修改了一个包,花费了30秒,第三次没有修改源码重新构建,1秒内构建完,明显可以感受到Turbo缓存构建的优势。

如对新技术开发组件库感兴趣,也欢迎加入stencil-component-ui,给个star鼓励一下