草庐IT

基于pnpm从0搭建Monorepo工程

ZT_Story 2023-11-24 原文
image.png

为什么使用Monorepo

公司前端项目大大小小也有数十个了,每个项目都是独立的一个仓库地址,典型的Mutiplerepo

随着项目增多,发现每次起新项目都要重新创建模板然后定义一些项目框架然后在着手开发。

痛点:

  • 每次新项目都需要重新搭建工程
    解决:
  • 用cli做了一键生成项目脚手架解放了一部分劳动力,这个是基于仓库的template模板工程

又来一个痛点:

  • 很多开发过程中的关于基础建设的idea都被封存在各自的项目里,导致template工程没有人持续维护,基本维持刚开始的样子,导致脚手架逐渐落后。

解决:

  • Monorepo 管理方案,可以很大程度改善以上的问题

也方便做很多代码风格质量以及ci相关流程的统一管理,决定也搭建一套自己的Monorepo工程模板

开始

为什么使用pnpm?

pnpm 的特点:快速、高效利用磁盘空间。

它将 workspace 的所有依赖都下载到.pnpm目录下,然后再根据各个 package 的情况,在其目录下通过软连接方式将依赖添加进来,这样所有的依赖只需要下载一次,那么不仅快,而且磁盘体积也小

而且它原生 cli 支持基本的 workspace 管理,这也是我对比下来选择 pnpm 的原因

学习成本低、简单好用

安装pnpm

npm install -g pnpm

创建workspace

pnpm init

根目录创建pnpm-workspace.yaml

packages: 
    - "libs/**"
    - "projects/**"

创建自己的目录结构

├── libs
│   ├── core
│   │   ├── package.json
│   │   └── pnpm-lock.yaml
│   ├── ui
│   │   ├── package.json
│   │   └── pnpm-lock.yaml
│   ├── util
│   │   ├── package.json
│   │   └── pnpm-lock.yaml
├── projects
│   ├── demo
│   │   ├── package.json
│   │   └── pnpm-lock.yaml
├── package.json
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

现在基本上我们已经有一个 mini 版的 workspace 了,至少整个目录结构看上去像那么回事。

使用pnpm cli 管理 workspace

1、配置依赖

比如我们的 core 包:

  • 各种 Base类
  • Http
    那么我们需要给 core 安装 axios 以及 qs

比如我们的 demo 工程:

  • vue
  • vite

以及我们的全局生效的依赖:

  • eslint
  • mocha
  • nyc
  • typescript
  • ...

这里因为该 Monorepo 都是 vue3 + vite 相关技术栈,所以我把相关依赖也一并安装到 root,这样以后新建的 project 就不用重新安装依赖啦!

2、安装依赖

cd libs/core && pnpm i?

No No No!

pnpm 早就帮我们考虑到了,直接根目录就可以指定安装子包的依赖

-F, --filter <package_name> 可以指定目标 package 执行任务

pnpm i -F core

那问题来了,如果多个包都配置好了依赖,想要一键安装怎么办,一个一个包去这样做吗?

还是说pnpm i -F core ui util

三个还好说,三十个呢?

这个时候我们需要了解一下 -r, --recursive 命令可以做到一键递归安装

pnpm i -r

3、根目录执行命令

除了一些全局生效的命令之外,像我们可以按需求配置执行 project 的启动和打包

// root pkg.json
"script": {
    "dev:demo": "pnpm -F demo dev",
    "build:demo": "pnpm -F demo build"
}

// demo pkg.json
"scripts": {
    "dev": "vite",
    "build": "vue-tsc --noEmit && vite build",
    "preview": "vite preview"
}

4、project 关联 libs

安装好依赖之后,我们可以简单写一点代码到core包里面,比如:

// index.ts
export function add(a: number, b: number) {
    return a + b;
}

然后我们在demo工程里执行 pnpm i @libs/core -F demo

我们会发现 demo 的 pkg.json 多了这个

{
    "dependencies": {
        "@libs/core": "workspace:*", // * 代表默认同步最新版本,正常安装完应该是 ^1.0.0
    }
}

我们尝试在文件中导入 core 中 add 方法

import { add } from "@libs/core";

console.log(add(1, 2));

我们就已经成功在项目中引入 libs/core 了

总结

我们通过以上步骤已经可以搭建出一个完整的 Monorepo 工程项目了,接下来就是不断补充内容,丰满羽翼,争取早日投入到生产实践中

有关基于pnpm从0搭建Monorepo工程的更多相关文章

  1. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  2. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  3. kvm虚拟机安装centos7基于ubuntu20.04系统 - 2

    需求:要创建虚拟机,就需要给他提供一个虚拟的磁盘,我们就在/opt目录下创建一个10G大小的raw格式的虚拟磁盘CentOS-7-x86_64.raw命令格式:qemu-imgcreate-f磁盘格式磁盘名称磁盘大小qemu-imgcreate-f磁盘格式-o?1.创建磁盘qemu-imgcreate-fraw/opt/CentOS-7-x86_64.raw10G执行效果#ls/opt/CentOS-7-x86_64.raw2.安装虚拟机使用virt-install命令,基于我们提供的系统镜像和虚拟磁盘来创建一个虚拟机,另外在创建虚拟机之前,提前打开vnc客户端,在创建虚拟机的时候,通过vnc

  4. ruby-on-rails - (Ruby,Rails) 基于角色的身份验证和用户管理...? - 2

    我正在寻找用于Rails的优质管理插件。似乎大多数现有的插件/gem(例如“restful_authentication”、“acts_as_authenticated”)都围绕着self注册等展开。但是,我正在寻找一种功能齐全的基于管理/管理角色的解决方案——但不是简单地附加到另一个非基于角色的解决方案。如果我找不到,我想我会自己动手......只是不想重新发明轮子。 最佳答案 RyanBates最近做了两个关于授权的railscast(注意身份验证和授权之间的区别;身份验证检查用户是否如她所说的那样,授权检查用户是否有权访问资源

  5. ruby - 在 Rakefile 中动态生成 Rake 测试任务(基于现有的测试文件) - 2

    我正在根据Rakefile中的现有测试文件动态生成测试任务。假设您有各种以模式命名的单元测试文件test_.rb.所以我正在做的是创建一个以“测试”命名空间内的文件名命名的任务。使用下面的代码,我可以用raketest:调用所有测试require'rake/testtask'task:default=>'test:all'namespace:testdodesc"Runalltests"Rake::TestTask.new(:all)do|t|t.test_files=FileList['test_*.rb']endFileList['test_*.rb'].eachdo|task|n

  6. ruby - 如何使用 Ruby 基于字母数字字符串生成颜色? - 2

    我想要像“嘿那里”这样的东西变成,例如,#316583。我希望将任意长度的字符串“归结”为十六进制颜色。我不知道从哪里开始。我在想,每个字符串的MD5散列都是不同的-但如何将该散列转换为十六进制颜色数字? 最佳答案 你可以只取几位前几位:require'digest/md5'color=Digest::MD5.hexdigest('Mytext')[0..5] 关于ruby-如何使用Ruby基于字母数字字符串生成颜色?,我们在StackOverflow上找到一个类似的问题:

  7. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

  8. ruby - 规范测试基于 EventMachine 的(Reactor)代码 - 2

    我正在尝试整个BDD方法并想测试AMQP基于Vanilla的方面Ruby我正在写的应用程序。选择Minitest后作为与其他名副其实的蔬菜框架不同的平衡功能和表现力的测试框架,我着手编写此规范:#File./test/specs/services/my_service_spec.rb#Requirementsfortestrunningandconfigurationrequire"minitest/autorun"require"./test/specs/spec_helper"#Externalrequires#MinitestSpecsforEventMachinerequire

  9. ruby - JSON的基于流的解析和写入 - 2

    我分1,000个批处理从服务器获取大约20,000个数据集。每个数据集都是一个JSON对象。坚持这会产生大约350MB的未压缩明文。我的内存限制为1GB。因此,我以追加模式将每1,000个JSON对象作为一个数组写入到一个原始JSON文件中。结果是一个包含20个需要聚合的JSON数组的文件。无论如何我都需要触摸它们,因为我想添加元数据。一般RubyYajlParser使这成为可能:raw_file=File.new(path_to_raw_file,'r')json_file=File.new(path_to_json_file,'w')datasets=[]parser=Yajl::

  10. ruby-on-rails - Rails/Ruby 的痛苦 - 如何检查 gem 是否基于 UNIX/类 UNIX? - 2

    有什么方法可以查看gem是否仅在UNIX/类UNIX系统上受支持?是否有任何gem可以“筛选”所有gem并查看在Windows上使用它是否有任何问题。 最佳答案 简短回答:否。老实说,Windows在Ruby世界里是二等公民。这主要是因为Linux、BSD、OSX和几乎所有其他基于POSIX的系统都同意一件事,而Windows将去做完全不同的事情。即使是用于Windows的gem也可能偶尔会由于开发人员的疏忽而损坏。大多数gem作者没有针对Windows运行并依赖于用户错误报告的持续集成服务器。支持Windows很困难,不仅因为AP

随机推荐