前端实战:从 0 开始搭建 pnpm 单一仓库(1)

在过去的 1 年多时间里,我们一直在使用 pnpm 单一仓库来管理项目。随着项目数量的不断增加,深刻体会到了单一仓库的强大优势。通过 pnpm,不仅实现了公共物料的复用,还显著节省了开发时间,提升了开发效率。当然,在开发过程中也遇到了不少挑战,但这些经历都促使自己不断优化和改进。

通过记录这些实践和经验,希望能够更好地发现问题、解决问题,并在此过程中不断成长。

直接进入主题------从 0 搭建一个 pnpm 单仓:

1. 创建项目目录

首先创建一个根目录 mocha-monorepo,用于存放整个单一仓库的代码

bash 复制代码
mkdir mocha-monorepo && cd mocha-monorepo

2. 初始化项目

在根目录下初始化项目,创建 package.json 文件,运行命令:

csharp 复制代码
pnpm init

生成的package.json文件,手动添加 "private": true

bash 复制代码
{
  "name": "mocha-monorepo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo "Error: no test specified" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "private": true
}

3. 配置 pnpm-workspace.yaml

单一仓库(Monorepo)的目录结构并没有固定的模式,完全可以根据项目的实际需求和团队的习惯进行设计。在此我采用 packagesapps 这样的目录结构,这是比较常见且推荐的方式,它能够很好地平衡模块化和集中管理的需求,当然,随着开发的深入,你可以随时优化目录结构以适应自己的开发习惯。

bash 复制代码
mocha-monorepo/
├── packages/
│   ├── components/      # 公共组件库
│   ├── directives/      # 公共指令
│   ├── composables/     # 公共composables
│   ├── utils/           # 公用工具函数
│   └── apis/      			 # API 客户端库
│   └── assets/      		 # 公共静态资源
├── apps/
│   ├── web-app/         # Web 应用
│   ├── mobile-app/      # 移动应用
│   └── admin-dashboard/ # 管理后台
├── scripts/             # 构建、部署等脚本
├── docs/                # 文档
├── package.json         # 根级依赖管理
├── pnpm-workspace.yaml  # pnpm 工作空间配置(如果使用 pnpm)
└── README.md            # 项目说明
└── ...									 

根据以上目录机构,在根目录下创建 pnpm-workspace.yaml 文件,定义工作区中的包路径。这表示所有位于 packages/app/docs/ 下的目录都被视为独立的包

vbnet 复制代码
packages:
  - 'packages/*'   
  - 'apps/*'       
  - 'docs/**'      

4. 创建子项目

apps/ 目录下创建子项目。例如

java 复制代码
cd apps
pnpm create vite@latest 

// 按照提示选择,并创建项目

pnpm i
pnpm dev

和我们创建一个普通 Vite 应用是一样的,创建完成后,安装依赖并运行,可以看到熟悉的 Vite+Vue 页面。

到此为止,这个 pnpm 的单一仓库(mono-repo)和普通多仓库(muti-repo) 差不多。接下来,我们会逐步配置和优化这个单仓,发挥单仓的优势。

5. 实现一个简单的公共方法

照例从最简单的入手,我们在packages/utils/文件下创建一个index.ts文件

bash 复制代码
cd packages/utils
touch index.ts

创建一个简单的方法并导出

javascript 复制代码
export const hello = () => {
  return 'hello world'
};

接下来,就是在 apps/app1 中使用这个 hello 方法,显然直接引用是做不到的,我们需要建立各个包/项目的相互联系。

6. 初始化 packages/utils 为一个 npm 包

为了让 packages/utils 能够作为一个可复用的包被其他项目引用,我们需要为其创建一个 package.json 文件。在packages/utils 下运行

csharp 复制代码
pnmp init

编辑生成的 package.json 文件,修改 "name" 为 "@mocha-monorepo/utils"

perl 复制代码
{
  "name": "@mocha-monorepo/utils",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "keywords": [],
  "author": "",
  "license": "ISC"
}

7. 安装utils 到 app1中

这里有一个小小的坑,如果直接使用下面的命令安装,很可能会失败

sql 复制代码
pnpm add @mocha-monorepo/utils

这里需要修改一下命令,增加@workspace:^ ,明确告诉终端我们是从workspace中安装。

ruby 复制代码
pnpm add @mocha-monorepo/utils@workspace:^ 

查看app1/package.jsondependencies 已经有了utils

8. 在 app1 中使用utils的方法

修改 app1/App.vue 的代码

xml 复制代码
<script setup lang="ts">
  import {hello} from '@mocha-monorepo/utils'

  const str = hello()
</script>

<template>

  <div> 这是来自utils的: {{ str }}</div>
</template>

运行到浏览器,查看效果:

OK,成功的第一步已经迈出了~

在后续的文章中,将继续深入探讨单一仓库的配置和优化,分享更多实践经验,帮助大家更好地利用 pnpm 单一仓库提升开发效率。

有任何问题或者兴趣也可以在公众号:自由前端之路 找到我。

相关推荐
像风一样自由202025 分钟前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem1 小时前
基于Flutter的web登录设计
前端·flutter
浪裡遊1 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
why技术1 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
GISer_Jing1 小时前
0704-0706上海,又聚上了
前端·新浪微博
止观止2 小时前
深入探索 pnpm:高效磁盘利用与灵活的包管理解决方案
前端·pnpm·前端工程化·包管理器
whale fall2 小时前
npm install安装的node_modules是什么
前端·npm·node.js
烛阴2 小时前
简单入门Python装饰器
前端·python
ai小鬼头2 小时前
AIStarter如何助力用户与创作者?Stable Diffusion一键管理教程!
后端·架构·github
袁煦丞3 小时前
数据库设计神器DrawDB:cpolar内网穿透实验室第595个成功挑战
前端·程序员·远程工作