Monorepo风格的组件工程搭建示例详解

 更新时间:2023年02月01日 14:18:15   作者:Fone丶峰  
这篇文章主要介绍了Monorepo风格的组件工程搭建示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Monorepo概念

随着各种技术的发展和超级应用的出现,人们开始考虑怎么才能将所有的小应用都集成在一个大项目中,特别是在这些项目互相影响时,在实现过程中,工程师们最关注的两点是:项目功能分离 和 避免重复代码

如果将每个功能作为独立的项目打包,随着业务的发展,项目会越来越多,根本没法管理,项目与项目之间的协作也会越来越困难,所以Monorepo的概念并产生了。

Monorepo中我们可以在一个项目下进行功能拆分,他们互相独立不影响,但是又可以通过引用来达到互相协助。

Monorepo的优缺点

优点:

  • 简化依赖的管理。
  • 跨组合作更加方便。
  • 代码复用简单。

缺点:

  • 项目构建时间过长。
  • 版本信息杂糅不清晰。

我也会基于Monorepo的方式搭建属于自己的组件库工程。

项目工程的搭建

技术选型

  • 基于pnpmMonorepo工程,项目打包工具vitegulp,使用sass处理样式。
  • Vue组件写法会支持Jsxtemplate的方式。项目支持Typescript
  • lint规范的接入,prettier的格式化统一,husky的卡点校验。
  • 组件单元测试使用vitest+happy-dom

基于以上的技术开始搭建我们的项目。

项目的大概结构

// vb-design
|—— config        //放置一些脚本
|—— examples      //存放演示包
    |—— demo
    |—— taro-demo 
    ...
|—— packages      //存放npm库的包
    |—— hooks
    |—— icon
    |—— ui-h5
    |—— ui-taro
    ...
.eslintignore
.eslintrc.js
.gitignore
.lintstagedrc.cjs
.npmrc
.prettierrc.cjs
package.json
pnpm-workspace.yaml
README.md
tsconfig.root.json
...

项目配置

Monerepo工程的起步

pnpm搭建Monorepo是非常简单的,只需要我们配置pnpm-workspace.yaml文件即可。具体的配置可参考pnpm-workspace.yaml | pnpm

lint、prettier、eslint的接入

lintprettiereslint的配置大部人应该都很熟练了,在这我就不一一贴代码说明了。还不清楚的小伙伴可参考我的代码或者找篇相关的教程自己跟着试试。

统一开发环境

开发环境的统一,主要是统一Node版本和pnpm,我们可以通过在package.json中配置一些字段来统一开发环境。

1、限制Node版本和pnpm通过配置voltaengines限制Nodepnpm的版本

//package.json
"volta": {
    "node": "16.13.0"
},
"engines": {
    "node": "16.13.0",
    "pnpm": ">=6"
}

2、限制项目只能通过pnpm初始化依赖

//package.json
"scripts": {
    "preinstall": "npx only-allow pnpm",
}

packages子包搭建

对于子包的搭建,不会详细地一一讲解,需要深入了解的可以自行到源代码里看。

ui-h5搭建

  • 目录结构设计
//ui-h5
components                  //组件目录
    |—— Button
        |—— demo            //demo演示存放目录
            |—— base.vue
            ...
        |—— index.md        //组件使用文档
        |—— index.scss      //组件样式
        |—— index.ts        //vue组件
        |—— index.taro.ts   //taro组件
    |—— Icon
    ...
style          //公共样式存放
    |—— index.scss
    ...
ui.h5.ts       //vue组件对外暴露
ui.taro.ts     //taro组件对外暴露

为了开发方便,把vue端taro端的组件都放在该包下,以及examples需要的演示文档和demo也放在该包下。至于各端写好的组件demo演示文档是怎么使用,后续会说明。

  • 构建产物
// dist
components                    //单个组件
    |—— Button
        |—— index.scss
        |—— index.css
        |—— index.js
        |—— index.taro.js
    |—— Icon
    ...
style 
    |—— index.scss
    ...
types
    |—— 
    ...
style.css
vb-ui.es.js
vu-ui.umd.js
vb-ui.taro.es.js
vb-ui.taro.umd.js

ui-taro搭建

该包其实没有做更多的事情,只是初始化之后把package.json做了相关配置。最重要的地方是在根目录下的package.json配置了脚本,在ui-h5包构建之后,通过脚本copy了该包需要的东西。

  • 脚本文件都在根目录config

icon搭建

ui-h5中,Icon组件的设计支持了iconfontsvg的方式,这也是参考了element-uiIcon组件设计。所以该包主要是处理svg图标,把图标转化成vue组件统一向外暴露的过程。

另外,我并不会用设计软件,没有svg可用,所以借用了字节arco-design的图标Arco Design Icons – Figma

hooks搭建

该包主要是一些公共方法的包,目前也没有更多的想法,所以也只是先放着。

examples浏览器端演示包搭建

因为搭建的是移动端组件库,所以演示包需要有两个入口,H5端和PC端。整个搭建的过程大致是:

vite-plugin-pagesvite-plugin-vue-layouts的配置

//vite.config.js
Pages({
  dirs: [
    {
      dir: resolve(__dirname, '../../packages/ui-h5/components'),
      baseRoute: 'component',
    },
  ],
  exclude: ['**/components/*.vue'],
  extensions: ['vue', 'md'],
}),
Layout({
  layoutsDirs: 'src/layouts',
  defaultLayout: 'preview',
})

项目的构建与npm包发布

这么多的子包,打包构建以及推送到npm是不是需要到每个子包下执行完打包和执推送的命令?针对这个问题pnpm官方是有解决方案的:

首先所有的子包都定义个build命令来执行当前包的所有打包构建事情,最后项目根目录package.json的配置如下:

//package.json
"scripts": {
    "build": "pnpm --filter './packages/**' run build && pnpm run build:taro",  //执行packages下所有子包的build方法
    "release": "pnpm run build && pnpm run release:only",
    "release:only": "changeset publish --tag=beta --access=publish",            //发布所有子包
    "build:taro": "node ./config/build-taro.js",
    "build:demo": "pnpm --filter './examples/**' run build"
}

上方build这个地方的配置pnpm官方有很详细的说明。再就是关于npm publish的,主要是通过@changesets/cli这个cli工具去解决。

changeset publish 只是一个很纯净的发包命令,手动提升/修改版本后再 changeset publish他会将所有包都publish一次。

  • 写到这,顺便再给大家说下这个项目的代码发布流吧。
  • 版本号是手动修改的。
  • 通过打tag的方式会触发workflows去执行打包构建,然后publish和部署演示的demo

很多开源的项目通过changeset-bot + changesets/action + @changesets/cli能玩出各种各样的工作流。

关于单元测试

单测在开源项目里是不可缺少的存在,虽然我不一定会去写单测😀,但是该有的东西还是得搭起来。

Vitest是基于vite的原生快速单元测试,完全兼容JestApi,还能共用vite的配置。所以针对当前项目使用Vitest是最快接入单元测试的方式,但是很遗憾,针对小程序端还没有更好的接入单元测试方案。

最后

写到这,组件库的搭建过程也差不多了,有什么不了解的可以留言或私信我。欢迎大家提出更好的意见或想法,还有写作水平差,有问题请轻喷。

最后因为没有一些设计规范,所以UI组件的产出并不会很理想。但是从0到1实现的过程才是重点,这能让我们以后在碰到相同问题时能快速解决。

相关文章

开篇:对于组件库的思考、技术梳理

代码仓库:vb-design

以上就是Monorepo风格的组件工程搭建示例详解的详细内容,更多关于Monorepo组件搭建的资料请关注脚本之家其它相关文章!

相关文章

  • 编写v-for循环的技巧汇总

    编写v-for循环的技巧汇总

    这篇文章主要介绍了编写更好的v-for循环的6种技巧,帮助大家更好的理解和使用vue框架,感兴趣的朋友可以了解下
    2020-12-12
  • vue.js 动态组件详解

    vue.js 动态组件详解

    这篇文章主要介绍了vue.js 动态组件详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • Vue插槽slot全部使用方法示例解析

    Vue插槽slot全部使用方法示例解析

    插槽就是子组件中的提供给父组件使用的一个占位符,用<slot></slot> 表示,父组件可以在这个占位符中填充任何模板代码,如 HTML、组件等,填充的内容会替换子组件的<slot></slot>标签,这篇文章主要介绍了Vue插槽的理解和使用,需要的朋友可以参考下
    2023-03-03
  • 在antd Table中插入可编辑的单元格实例

    在antd Table中插入可编辑的单元格实例

    这篇文章主要介绍了在antd Table中插入可编辑的单元格实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-10-10
  • Vue3封装localStorage基本使用示例详解

    Vue3封装localStorage基本使用示例详解

    localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据,localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除,本文给大家介绍Vue3封装localStorage-基本使用,感兴趣的朋友一起看看吧
    2023-12-12
  • 在 Vue 中使用 iframe 嵌套页面的步骤

    在 Vue 中使用 iframe 嵌套页面的步骤

    这篇文章主要介绍了在 Vue 中使用 iframe 嵌套页面,使用 iframe 技术可以实现多个页面之间的数据传递和交互,提高了网站的整体性能和用户体验,需要的朋友可以参考下
    2023-05-05
  • vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定

    vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定

    这篇文章主要介绍了vue3.0 CLI - 2.3 - 组件 home.vue 中学习指令和绑定的相关知识,本文通过实例代码相结合的形式给大家介绍的非常详细 ,需要的朋友可以参考下
    2018-09-09
  • vue自定义filters过滤器

    vue自定义filters过滤器

    这篇文章主要介绍了vue自定义filters过滤器的相关知识,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2018-04-04
  • Vue自定义铃声提示音组件的实现

    Vue自定义铃声提示音组件的实现

    这篇文章主要介绍了Vue中自定义一个铃声提示音组件的实现以及使用方法,文中的示例代码讲解详细,对我们学习Vue有一定帮助,需要的可以参考一下
    2022-01-01
  • 在vscode 中设置 vue模板内容的方法

    在vscode 中设置 vue模板内容的方法

    这篇文章主要介绍了在vscode 中设置 vue模板内容的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09

最新评论