从0开始搭建一个Monorepo模版,基于Turborepo+pnpm+changesets+dumi

Monorepo

  • 前言
  • 开始
    • 一、使用turborepo初始化项目
    • 二、调整目录结构及文件
      • 1. 调整`package.json`文件
      • 2. 调整app目录
      • 3. 调整`eslint`包
      • 4. 调整`ui`包
      • 5. 调整eslint配置
      • 6. 调整.npmrc
      • 7. 使用commitizen规范代码提交
      • 8. 使用commitlint+husky进行 commit提交信息校验
      • 9. 使用husky进行commit前的规范校验
    • 三、dev run
    • 四、打包
      • ts与eslint
      • UI
    • 五、发版
      • 修改所有的包名
      • 使用Changesets进行版本管理并发版
  • 总结

前言

当你想要搭建一个Monorepo时,相信你已经调研过很多技术选型,之前我也使用过yarn+workspace+lerna+dumi开发过一套组件库,后续有时间把这套工具也抽一个模版。

因为pnpm本身支持workspace并且lerna已经停止维护,因此决定使用新的工具从新搭建一套Monorepo模版,那么这套工具就是:

  • pnpm—包管理器
  • turborepo—外壳
  • changesets—版本号管理、changelog管理
  • dumi—文档预览
  • 其他的规范代码的工具如:—commitizeneslintlint-stagedcommitlinthusky

你可能对Turborepo不太了解,他的官方解释是高性能的JavaScript和TypeScript代码库构建系统,他在这只是作为一个壳子用来提升开发及打包效率,不用了解太多。

开始

一、使用turborepo初始化项目

  1. pnpm dlx create-turbo@latest
  2. 选择目录(项目名)、选择包管理器
    在这里插入图片描述
  3. 项目初始化完成,具体的目录结构什么意思可以去Turborepo看一下,不看也没关系,因为后续我们要调整它。
    在这里插入图片描述

我现在这里的turbo的version是1.10.12,如果你很晚看见这篇文章,可能版本有了很大不同。

  1. 链接gitHub仓库,当然这一步不是必须的,链接它的目的只是为了测试规范代码的工具是否生效。
    git remote add origin https://github.com/Atw-Lee/monorepo-template.git

不要划走:Monorepo可以用来管理多应用工程(app目录下的各种工程),所有工程依赖相同的UI,而Turborepo初始化的项目也是这么干的。但是,我需要的是搭建一个我的UI组件库,这是与它不同的地方,app下我只需要一个文档预览工程(dumi),因此,我需要调整它的目录结构

二、调整目录结构及文件

1. 调整package.json文件

  • 安装eslint@latest(eslint提到全局,并更新到最新版本)
  • 安装@changesets/cli(版本号、changelog管理)
  • 安装commitizen cz-conventional-changelog(规范commit信息)
  • 安装@commitlint/cli @commitlint/config-conventiona husky(检验commit信息)
  • 安装lint-staged stylelint(校验规范格式)
  • 安装father(打包)
  • 增加"preinstall": "npx only-allow pnpm"只允许使用pnpm包管理器

pnpm i -Dw eslint@latest @changesets/cli commitizen cz-conventional-changelog @commitlint/cli @commitlint/config-conventional husky lint-staged stylelint father


2. 调整app目录

  • 删除web及docs目录的所有内容
  • 新建docs目录并初始化dumi项目
    在这里插入图片描述
  • 进入docs目录执行git init
  • 删除.fatherrc.ts文件(不需要在这打包组件)
  • .gitignore文件增加docs-dist(该目录为dumi的build产物)
  • 修改package.json文件:
    • 删除docs:build
    • 修改build:dumi build(打包直接是该文档工程打包,不打包组件)
    • 删除moduletypesfiles配置(用不着)
    • 依赖删除与外边重复的(commitlint、eslint、father、husky、lint-staged、stylelint等)

3. 调整eslint

我不准备使用它默认的eslint,因为我用不到nextjs相关的内容,我选择使用Tencent的eslint-config-alloy

  • 进入packages/eslint-config-custom目录,手动删除不需要的依赖,pnpm i eslint-config-alloy安装alloy
  • 更新eslint-plugin-react(后续补充,不是最新的出错了)

  1. 调整tsconfig
  • 删除package.json的private属性(为了后续可以正常发版)
  • 删除nextjs.js文件(不需要next的ts配置)

在这里插入图片描述


4. 调整ui

  • 删除turbo目录(用不着)
  • package.json文件删除generate脚本(用不着)
  • package.json文件删除eslint依赖(外边已经有了)
  • package.json文件新增脚本"build": "father build"(打包组件,app里的docs不需要了,因为UI组件包的开发在这里)
  • package.json文件修改main属性"main": "./src/index",
  • package.json文件修改types属性"main": "./src/index",
  • 新建src目录,增加button组件
    在这里插入图片描述
  • 修改tsconfig.json文件
{
  "extends": "tsconfig/react-library.json",
  "include": ["src"],
  "exclude": ["lib", "dist", "es", "node_modules"]
}
  • 新增.fatherrc.ts文件
import { defineConfig } from "father";
export default defineConfig({
  // more father config: https://github.com/umijs/father/blob/master/docs/config.md
  esm: { output: "es" },
  cjs: { output: "lib" },
});
  • .gitignore文件增加lib及es(该目录为ui通过father打包产物,具体名称还是根据上一步的配置来)
  • .gitignore文件删除next相关的(用不到)

5. 调整eslint配置

module.exports = {
  root: true,
  extends: ["custom"],
};

6. 调整.npmrc

  • 增加registry=你公司的私有源,开发的UI组件库发布到这(在这直接定义注册地址就比较方便了)

7. 使用commitizen规范代码提交

  • package.json文件增加"commit": "cz"脚本
  • package.json文件增加config属性
  "config": {
    "commitizen": {
      "path": "node_modules/cz-conventional-changelog"
    }
  }
  • 执行 pnpm commit测试
    在这里插入图片描述

8. 使用commitlint+husky进行 commit提交信息校验

  • 根目录新增commitlint.config.js文件
module.exports = { extends: ["@commitlint/config-conventional"] };
  • package.json文件增加"postinstall": "husky install"
  • 执行pnpm i生成.husky文件,初始化husky。完成后可删除postinstall属性
  • 执行npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'生成commit-msg的hook
  • package.json文件增加commitlintlint-staged属性
	"commitlint": {
    "extends": [
      "@commitlint/config-conventional"
    ]
  },
	  "lint-staged": {
    "*.{md,json}": [
      "prettier --write --no-error-on-unmatched-pattern"
    ],
    "*.{css,less}": [
      "stylelint --fix",
      "prettier --write"
    ],
    "*.{js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{ts,tsx}": [
      "eslint --fix",
      "prettier --parser=typescript --write"
    ]
  },
  • 执行错误的commit信息测试
    在这里插入图片描述

9. 使用husky进行commit前的规范校验

  • 执行npx husky add .husky/pre-commit "npx --no-install lint-staged"
  • 上一步已经添加完成了lint-staged属性
  • 执行commit进行校验
    在这里插入图片描述

三、dev run

  • 执行pnpm dev:页面正常打开dumi运行的应用
  • docs的package.json增加ui的依赖"ui": "workspace:*"
  • 页面中使用ui包中的button组件
    在这里插入图片描述
    到这我们的运行时的组件与文档预览已经ok了,接下来就是ui组件的打包

四、打包

ts与eslint

他俩不需要打包,都是些配置项

UI

上文我们已经设置好了father打包的配置文件,直接执行pnpm build
在这里插入图片描述
生成了对应的lib和es文件夹,docs也跟着打包了,这里是turborepo的操作逻辑,我们不用关心它

  • ui的package.json中新增files属性
  • ui的package.jsonmain、types属性也要做一个修改,之前是./src
  "main": "./lib/index",
  "types": "./lib/index",
  "files": [
	  "es",
	  "lib",
	  "dist"
	],

五、发版

接下来就需要把我们的包发布到我们的私有源上了,当然开源也没有问题

我们现在有三个包,分别是eslint、typescript、ui
我们的包肯定不能叫这个名字,那我们给他们改下名字,加上组织的前缀,我这里以@you-org为例

修改所有的包名

在这里插入图片描述
该变更中的文件均有需要修改

使用Changesets进行版本管理并发版

  • 执行pnpm changeset init生成.changeset文件
  • 执行pnpm changeset选择要发布的包
    在这里插入图片描述
  • 选择版本(一版fix是patch,feat是minor)
    在这里插入图片描述
  • 执行changeset version增加版本号
    在这里插入图片描述
  • commit提交
  • 执行pnpm -r publish --tag alpha0.1.0发布版本
    在这里插入图片描述
    OK到这里就结束了~

总结

收获:从0开始搭建了一个多包(Monorepo)的UI组件模版,了解了一个简单开源UI工程应该具有的工具及搭建步骤。

不足之处在于:

  • 组件库的打包使用rollup可能会更好,但是因为额外的学习成本,还是使用了dumi上自带的father
  • 除了ui包,应该在添加一个utils包,这样才更加具有Monorepo的特性
  • tsconfigeslint包不确定是否有必要单独提成一个包,如果项目很复杂的话,eslint和tsconfig需要灵活配置的话,可能会更有用吧
  • 缺少了一些脚本,通过脚本来减少复杂的原生命令
  • 需要额外的脚手架来协调模版工作,以便不需要更改额外的package.json文件,后续也会做这方面的工作

参考文章

  • 打造高效Monorepo:Turborepo、pnpm、Changesets实践
  • pnpm + workspace + changesets 构建你的 monorepo 工程
  • 在 pnpm 中使用 Changesets
  • Creating a new monorepo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/67803.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Pod进阶

目录 一、资源限制 1. CPU 资源单位 2.内存 资源单位 3.示例 二、重启策略 三、健康检查(探针) 1.探针的三种规则: 1.1就绪探测 2.Probe支持三种检查方法: 2.1exec检查方式 2.2httpGet方式 2.3tcpSocket方式 3. 启动、退出动作…

pyscenic分析:视频教程

我们之前更新过pyscenic的教程:pySCENIC单细胞转录因子分析更新:数据库、软件更新。我们也说过,我们号是放弃R语言版的SCENIC的分析了,因为它比较耗费计算资源和时间,所以我们的单细胞转录因子分析教程都是基于pysceni…

什么是Linux,如何在Windows操作系统下搭建Linux环境,远程连接Linux系统

文章目录 什么是LinuxLinux的诞生及发展为什么要学习LinuxLinux内核Linux发行版什么是虚拟机如何在VMware虚拟机中搭建Linux系统环境远程连接 Linux 系统Linux 帮助网站 什么是Linux Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UNIX的多用户…

如何改造antd-vue的table支持虚拟列表功能

对于超大数据量的接口来说,如果前端直接一股脑的渲染出来,必然会导致渲染超时、操作卡顿、内存爆表、网页奔溃等情况,因此一般的对于大数据量的列表处理,无非就以下几种方式 采取分页的方式,减少每页的数量 比如每页1…

棱镜七彩正式加入龙蜥社区安全联盟(OASA)

近日,龙蜥社区安全联盟(OASA)正式成立,棱镜七彩成为该联盟成员单位。 龙蜥社区安全联盟是促进产业合作的非营利组织,致力于打造中立开放、聚焦操作系统信息安全的交流平台,推进龙蜥社区乃至整个产业安全生态…

【git】git常用命令总结

目录 一、流程 二、基本流程命令(从初始化到推送到远程仓库) 三、分支相关命令 四、提交代码 五、拉取主分支最新代码 六、合并远程仓库主分支代码到分支 七、撤销回退 一、流程 workspace 工作区,就是你的编辑器打开的文件 staging are…

【uniapp】uniapp打包H5(网页端):

文章目录 一、设置appid:二、设置router:三、打包:【1】[CLI 发行uni-app到H5:https://hx.dcloud.net.cn/cli/publish-h5](https://hx.dcloud.net.cn/cli/publish-h5)【2】HBuilderX 四、最终效果: 一、设置appid&…

Jupyter Notebook 未授权访问远程命令执行漏洞

漏洞描述 Jupyter是一个开源的交互式计算环境,它支持多种编程语言,包括Python、R、Julia等。Jupyter的名称来源于三种编程语言的缩写:Ju(lia)、Py(thon)和R。 Jupyter的主要特点是它以笔记本(Notebook)的形式组织代码…

lancet: 【推荐】--源码学习

一个全面、高效、可复用的go语言工具函数库; 可以学习源码的好的地方,这个是个工具库,建议最好的办法是 在项目中导入后,然后查看他的各个源代码进行学习使用 golangd中,查看导入包以及他的源代码; 中文…

【腾讯云 Cloud Studio 实战训练营】用于编写、运行和调试代码的云 IDE泰裤辣

文章目录 一、引言✉️二、什么是腾讯云 Cloud Studio🔍三、Cloud Studio优点和功能🌈四、Cloud Studio初体验(注册篇)🎆五、Cloud Studio实战演练(实战篇)🔬1. 初始化工作空间2. 安…

问道管理:信创概念走势活跃,恒银科技斩获四连板

信创概念9日盘中走势活泼,截至发稿,新晨科技、竞业达、恒银科技等涨停,宇信科技涨近10%,中孚信息涨近9%,华是科技、神州数码涨超7%。 新晨科技今天“20cm”涨停,公司昨日晚间公告,近来收到投标代…

Linux简介及基础操作

简介: 1、linux和windows都是操作系统,多任务,多用户,多线程… Linux免费使用,自由传播,开源 2、Linux 发行版(都是基于linux内核穿的外套) Ubuntu——嵌入式开发 fedora——早期嵌入…

使用 `nmcli` 在 CentOS 8 上添加永久路由

CentOS 8 使用 NetworkManager 作为默认的网络管理工具,因此我们可以使用 nmcli 工具来实现相同的目标。使用 nmcli 可以更加直观地管理路由,并且更符合 CentOS 8 的默认网络管理方式。 以下是使用 nmcli 在 CentOS 8 上添加永久路由的步骤:…

JDBC学习笔记

1 JDBC简介 1.1 前言 当谈论JDBC时,我们可以将其看作是一种用于Java程序与数据库进行通信的方式。如果你想编写一个Java程序,并且希望能够连接到数据 库、执行查询或更新数据,JDBC就是你需要的工具。 JDBC提供了一组类和接口,…

c++ boost circular_buffer

boost库中的 circular_buffer顾名思义是一个循环缓冲器,其 capcity是固定的当容量满了以后,插入一个元素时,会在容器的开头或结尾处删除一个元素。 circular_buffer为了效率考虑,使用了连续内存块保存元素 使用固定内存&#x…

pdf怎么拆分成一页一页?了解这几招就够了

pdf怎么拆分成一页一页?PDF文件是一种通用的文件格式,它可以保留文档的原始格式和内容。然而,有时候我们需要将一个PDF文件拆分成一页一页的单独文件,比如需要将一份报告分发给不同的人员,或者需要将PDF文件的某些页面…

leetcode 399-除法求值

法一:并查集 分析示例1: a / b 2.0 a/ b 2.0 a/b2.0,说明 a 2 b a2b a2b, a a a和 b b b在同一个集合中 b / c 3.0 b/c3.0 b/c3.0,说明 b 3 c b3c b3c, b b b和 c c c在同一个集合中 求 a / c a/…

PyCharm新手入门指南

安装好Pycharm后,就可以开始编写第一个函数:Hello World啦~我们就先来学习一些基本的操作,主要包含新建Python文件,运行代码,查看结果等等。 文章主要包含五个部分: 一、界面介绍 主要分为菜单栏、项目目录…

初阶C语言-操作符详解(下)

🌞 “等春风得意,等时间嘉许!” 接下来,我们把操作符没学完的继续学完! 操作符详解 6.2sizeof和数组 7.关系操作符8.逻辑操作符9.条件操作符10.逗号表达式11.下标引用、函数调用和结构成员12.表达式求值12.1隐式类型转…