使用PNPM+Vite搭建vue3多项目并共用组件库(monorepo)

3,726 阅读3分钟

背景

  1. 之前公司一直使用npm私服去管理组件库,感兴趣的朋友可以去看一下
  1. 后续公司增加了另一个大的产品分支,与当前的产品存在比较大的差异,但是又要同步使用当前的组件库,这样就产生了一个问题: 每次需要修改组件库代码的时候,都需要上传到私服,然后两个产品线单独去拉取依赖测试组件,非常繁琐麻烦
  2. 新的产品线需要新的部门去写,lib包的文档并不健全,还是需要结合源码进行编码和微修改。

工具: pnpm vite

  • 首先pnpm能完美解决我们当前的代码库管理问题,用pnpm把两个产品线组合到一起,共用组件库代码,把共同的依赖放在一起,单独的依赖自己独立去创建即可,这样很大程度上节省空间。
  • pnpm速度比npm快的多,pnpm 分三个阶段执行安装:
  1. 依赖解析。 仓库中没有的依赖都被识别并获取到仓库。
  2. 目录结构计算。 node_modules 目录结构是根据依赖计算出来的。
  3. 链接依赖项。 所有以前安装过的依赖项都会直接从仓库中获取并链接到 node_modules
  • 可以共同启动两个项目平台,组件库也不必打包,直接使用源代码,当更改组件库时,两个平台会进行热更新,组件库的测试问题也完美解决。
  • 使用vite纯是因为之前lib库就用vite,vite对于vue3现在也已经比较成熟,其中vite的热更新速度快正好适配我们。

项目搭建

安装

  • 安装pnpm npm install -g pnpm
  • pnpm init 初始化 package.json 文件 pnpm init
  • 创建 pnpm-workspace.yaml 文件,并指定 packages
packages: 
  - 'packages/**'
  - 'product1'
  - 'product2'
  // packages目录就是存放product1和product2公共的东西,比如组件库,主题、hooks、directives、utils等等。
  // product1、product2就是两个平台
  • 在 packages 下新建 components 并初始化 package.json

创建组件库

注意:我们这里只编写一个简单的 button 组件,主要是打通整体流程

|-- button
    |-- index.ts
    |-- src
    |   |-- button.ts
    |   |-- button.vue
    |   |-- button.less
    |-- __test__

components/button/src/button.vue

<template>
  <button><slot></slot></button>
</template>

<script lang="ts" setup>
defineOptions({
  name: 'Button'
})
</script>

components/button/index.ts


import Button from './src/button.vue'
export { Button }

components/index.ts 导出

export * from './button'

使用组件库

  • 在根目录 package.json 中添加 组件的依赖
{
  "devDependencies": {
    "@cy-common/components": "workspace:*"
  }
}

这里的包名 @cy-common/components,就是我们在 packages/components/package.json 中设置的 name 属性

  • 根目录执行 pnpm i 得到如图

image.png

  • 我们可以在根目录使用vite 创建一个项目,请参考 vite 官网,名称可以叫product1
 pnpm create vite product1 --template vue
  • 创建完成后再根目录package.json的scripts中添加启动命令(可以省略,自行在product1中启动也可):
"scripts": {
  "product1:dev":  "pnpm run -F product1 dev "
},
// -F代表 匹配 过滤
  • 根目录 再次pnpm i(如果不生效,建议删除node_modules再试) 得到如下:

image.png

  • 根目录启动product1 pnm run product1:dev

image.png

  • 引用代码库代码:删除product1/src/App.vue默认代码,更改为:
<template>
  <div>
    <Button>product1-----</Button>
  </div>

</template>
<script setup>
import {Button} from '@cy-common/components'
</script>
<style scoped>
</style>

此时页面显示:

image.png

注意:@cy-common/components 是整体的组件库名称,所以所有组件都需要导出,例如在components/index.ts中export * from './button'

  • 组件库使用引用已基本完成,我们再来试一下更改组件库热更新如何: 在packages/components/button/src/button.vue中修改代码: 增加个789
<template>
  <button><slot></slot>789</button>
</template>

<script setup>


</script>

保存,此时页面显示:

image.png 大功告成!

  • 然后我们再以相同的方式去创建product2:

image.png

  • 启动:

image.png

这样两个项目就可以都使用上组件库了,而且还是热更新,而且还是源码组件库,至于打包 只需要在product1中的vite中自行配置即可,这部分后续我会再写一个敬请关注,关注关注