当前位置: 首页 > news >正文

pnpm+monorepo实现前端公共函数、组件库

一、前言

1. pnpm

pnpm 是前端包管理工具之一,常见的还有npm、yarn等,但pnpm由于安装速度快、磁盘占用低、内置支持monorepo等优势,所以更推荐使用。

1-1 包管理工具核心特点对比

特性pnpmnpmyarn
安装速度🚀 快(基于硬链接和缓存)⏳ 较慢(全量复制)🚀 快(全量复制+缓存优化)
磁盘占用📉 低(共享 node_modules 依赖)📈 高(每个项目完整安装)📈 高(和 npm 类似)
包管理机制硬链接+全局存储直接安装到 node_modules直接安装到 node_modules
严格性🔒 严格模式(默认不可创建隐式依赖)🔓 允许隐式依赖🔓 允许隐式依赖
Monorepo 支持✅ 内置(pnpm workspaces❌ 需要 npm workspacesyarn workspaces
离线安装✅ 支持❌ 不支持✅ 支持
自动并行安装✅ 默认并行安装❌ 串行安装(npm 6)✅ 并行安装(npm 7+✅ 并行安装
Hoisting(提升依赖)🚫 默认不提升(更符合依赖层级)✅ 允许✅ 允许
Lockfilepnpm-lock.yamlpackage-lock.jsonyarn.lock

1-2 简单命令对比

操作pnpmnpmyarn
安装依赖pnpm installnpm installyarn install
添加依赖pnpm add <pkg>npm install <pkg>yarn add <pkg>
移除依赖pnpm remove <pkg>npm uninstall <pkg>yarn remove <pkg>
运行脚本pnpm run <script>npm run <script>yarn <script>
全局安装pnpm add -g <pkg>npm install -g <pkg>yarn global add <pkg>
初始化项目pnpm initnpm inityarn init

2. monorepo

2-1 概念

所有模块在同一仓库下,代码共享和协作更方便,无需发布到 npm 才能使用。

2-2 优势

  • 代码共享更容易

    • 所有模块在同一仓库下,代码共享和协作更方便,无需发布到 npm 才能使用。
  • 一致的依赖管理

    • 可以使用 pnpm/yarn/npm workspaces 统一管理依赖,避免每个模块单独安装,减少重复安装的依赖包。
  • 更容易的跨模块修改

    • 在此之前,多采用 Multi-repo 模式,即多个项目分别单独管理,这会导致一些问题,如修改 A 项目 API 需要:
      1. 更新 A 项目代码
      2. 发布新版本到 npm
      3. 更新 B 项目的依赖
    • 在 Monorepo 中,只需在同一个仓库内修改 A 和 B,避免复杂的版本管理。
  • 简化 CI/CD 流程

    • 只需配置一个 CI/CD 流程,即可管理多个模块的构建、测试和发布。
  • 原子性提交

    • 允许一次 PR 修改多个模块,保证所有变更一次性生效,避免版本不兼容问题。

2-3 缺点

  • 首次配置繁琐
  • Git 仓库规模较大,所有项目都在一个仓库中,随着时间推移,Git 历史可能变得庞大。
  • 不方便对项目做权限划分

2-4 Monorepo vs Multi-repo

对比项Monorepo(单仓库)Multi-repo(多仓库)
代码存储单个 Git 仓库每个模块独立 Git 仓库
依赖管理共享 node_modules,统一管理每个模块单独管理
版本管理可以使用 workspace:*每个模块单独发布版本
跨模块修改统一 PR 提交,改动同步需要更新多个仓库,发布新版本
CI/CD统一 CI/CD 流程每个仓库需要独立 CI/CD
适用场景内部共享库、组件库、前端+后端一体化需要独立发布、独立管理的项目

二、实现流程

1. 构建项目结构

根目录下执行 pnpm init 初始化项目

使用pnpm进行work-space,根据 pnpm官方文档,项目根目录下创建 pnpm-workspace.yaml,基本内容如下:

packages:
  # 指定根目录直接子目录中的包
  - 'my-app'
  # packages/ 直接子目录中的所有包 - 所有前端项目存储的目录
  - 'packages/*'
  # components/ 子目录中的所有包 - 给所有项目使用的公共组件
  - 'components/**'
  # utils/ 子目录中的所有包 - 给所有项目使用的公共工具库
  - 'utils/**'
  # 排除测试目录中的包
  - '!**/test/**'

根目录下创建 .npmrc,用于确保后续下载依赖时,优先从本地查找,而非远程npm。

# 解决pnpm add时优先在本地查找依赖
link-workspace-packages=true 

根据 pnpm-workspace.yaml 中声明的目录创建结构,此时项目目录如下:

在这里插入图片描述

2. 测试本地依赖

通过 utils、packages/web 测试本地依赖

2-1 utils

utils目录 下,执行pnpm init,此时出现 package.json,修改name为 @xxx/utils 格式,并加入 "private": true,

{
  "name": "@tbc/utils",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {}
}

utils目录下创建 text.js

const testFn1 = () => { console.log("fn1"); }
const testFn2 = () => { console.log("fn2"); }

export default {
  testFn1,
  testFn2
}

utils目录下创建 index.js注意: 文件名要与 package.json 中的 main 字段一致,默认为 index.js

在这里插入图片描述
index.js 中整合所有方法并导出

export * from "./test"

2-2 packages/web

packages目录下,创建项目 web 模拟真实项目,执行npm create vitepnpm i
执行pnpm add @tbc/utils安装 utils目录的依赖

在这里插入图片描述
npm run dev启动项目,并在 App.vue 中使用 utils下 的公共方法

import { testFn1 } from '@tbc/utils'
console.log(testFn1(),"===");

查看控制台打印
在这里插入图片描述
此时直接修改 utils目录 下的公共方法(加入return)
在这里插入图片描述
web项目中无需更新依赖,自动使用最新公共方法,查看打印
在这里插入图片描述

3. 组件库

3-1 封装简易组件

组件库与utils同理,在components目录下创建组件库项目,如npm create vite。修改 package.json 的name字段为 @tbc/ui

组件库项目根目录下,创建 dir 目录,用于存储组件。
dir/MyButton.vue

<template>
  <button style="background-color: antiquewhite;width: 150px;border-radius: 8px;">自定义组件</button>
</template>

组件库项目根目录下,创建 index.js 文件,用于对外暴露组件
index.js

import 'element-plus/dist/index.css'; 
import MyButton from "./dir/MyButton.vue"

export { MyButton }

3-2 其他项目中使用组件库

packages目录下其他项目中通过 pnpm add @tbc/ui 安装依赖,依赖详情为 "workspace:^"

使用组件库

<template>
  <MyButton>自定义组件库</MyButton>
</template>

<script setup>
import { MyButton } from "@tbc/ui"
</script>

在这里插入图片描述

相关文章:

  • 千兆网络测试仪使用全解析:从线序检测到性能压测实战
  • MySql基础以及安装
  • Ubuntu20.04双系统安装及软件安装(十一):向日葵远程软件
  • 如何在 C# 中检查两个对象是否完全相同?
  • 山东大学计算机科学与技术学院软件工程实验日志
  • python及pycharm安装配置
  • Pytorch构建LeNet进行MNIST识别 #自用
  • leetcode日记(76)格雷编码
  • DAIR-V2X-R数据集服务器下载
  • 机器学习之逻辑回归
  • 用CLI操作MySQL 92数据库的命令
  • 安装mysql
  • 解码未来!安徽艾德未来智能科技有限公司荣获“GAS消费电子科创奖-产品创新奖”!
  • Netty笔记5:Netty开发实例
  • 机器学习校招面经二
  • 【JavaScript—前端快速入门】JavaScript 综合案例 — 猜数字
  • 串口通讯基础
  • 【四.RAG技术与应用】【11.阿里云百炼应用(上):RAG在云端的实践】
  • 认识时钟树
  • Non-Homophilic Graph Pre-Training and Prompt Learning
  • 恩施网站设计/怎么样关键词优化
  • 工程公司有哪些/如何做好seo基础优化
  • 做网站 违法/河南网站优化
  • 三亚网站怎么制作/宁波seo网络推广主要作用
  • 学网站建设 赚钱/郑州网站优化软件
  • 网站建设进度表 免费下载/网站建设合同模板