monorepo搭建playgroun

应网友的建议,加更一篇使用 monorepo 搭建组件库的 playground,也就是本地的组件库测试环境

之前也有一篇专门讲搭建组件库测试环境的:👊承接上文,用vite搭建rollup组件库的开发环境 - 掘金

不过用 monorepo 似乎逼格更高点哈哈,所以这篇文章来分享借助 monorepo 搭建组件库的 playground

准备 monorepo

首先准备一个空文件夹,终端执行npm init -y:

是的,这是基于 npm 使用 monorepo

然后创建 components 文件夹存放组件库代码

进到 components 文件夹,用 npm 初始化一下npm init -y, 生成了一个 package.json:

json 复制代码
{
  "name": "components",
	"version": "1.0.0",
}

我们可以把 components 当成一个变量空间,在根目录 package.json 中添加 workspace 属性:

json 复制代码
{
  "name": "monorepo-demo-2",
  "workspaces": [
		"components"
	],
}

没错,npm 就是通过workspace属性来管理同一文件夹下的不同项目的。

每加一个项目,都需要往 workspace 中添加一个路径,表示向 npm 注册一个项目。每个项目中含有一个 package.json, npm 就是靠 json 中的 name 属性来识别不同项目


上面我们完成了在一个 monorepo 中,创建并注册一个项目,主要有三步:

  1. 创建文件夹 components
  2. components 下执行 npm 初始化
  3. 在根目录中的 packagejson 注册 components

这三步可以简化成一个命令npm init -w components -y。如果 components 文件夹已经存在,并且已经 npm 初始化,那么这个命令就只会执行第三步

你可以将所有项目放在一个叫 packages 文件夹下面,然后在workspace 添加一个 package/*, 表示 packages 文件夹下面有多个项目,npm 靠不同项目的 package.json 中的 name 属性来识别不同项目

安装依赖

接下来就可以向 components 组件库安装依赖了, 在根目录执行:

shell 复制代码
npm i rollup -w components

这个命令的意思是向 components 项目安装一个 rollup 依赖,-w指定项目。执行完安装命令之后,就是这样:

在项目根目录中生成了一个 node_modules 文件夹,里面有刚才安装的 rollup 依赖。这就是 monorepo 于普通项目的不同之处了--多个项目共享一个 node_modules,并不会在项目目录里面生成 node_modules。

而且 node_modules 中还有一个 components 文件夹的软连接,也就是说 components 本身也被提升到 node_modules 中了,这是多个项目之间互相共享代码的关键。

node 环境中查找依赖的顺序是,先在当前文件夹的 node_modules 查找依赖,如果没有,就往父级目录的 node_modules 中查找。逐级往上,直到查询到为止,或者查询到根目录为止

然后接着安装 rollup 构建需要的其他依赖:

shell 复制代码
npm i @rollup/plugin-commonjs @rollup/plugin-node-resolve -w components

npm i rollup-plugin-node-external rollup-plugin-postcss -w components

npm i typescript @rollup/plugin-typescript tslib -w components

npm i @babel/core @babel/preset-env @babel/preset-react @rollup/plugin-babel -w components

npm i react react-dom @types/react @types/react-dom -w components

不得不说,rollup 组件库的依赖是真滴多

编写组件库

为了方便掩饰,只写一个简单的组件和构建配置文件:

组件很简单,只有一个 Button,还有依赖于 Button 的 Search 组件:

这是 Button 组件的内容:

这是 Search 组件的内容:

index.ts 作为整个组件库的入口和出口,内容是这样的:

typescript 复制代码
import resolve from "@rollup/plugin-node-resolve";
import commonjs from "@rollup/plugin-commonjs";
import { babel } from "@rollup/plugin-babel";
import { DEFAULT_EXTENSIONS } from "@babel/core";
import typescript from "@rollup/plugin-typescript";
import nodeExternals from "rollup-plugin-node-externals";

/**  @type {import('rollup').RollupOptions} */
export default {
	input: "./src/index.ts",
	output: {
		dir: "./dist",
		format: "esm",
		sourcemap: true,
		preserveModules: true,
	},
	plugins: [
		resolve(),
		commonjs(),
		typescript(),
		babel({
			presets: [
				"@babel/preset-react",
				[
					"@babel/preset-env",
					{
						targets: ">0.2%, not dead, not op_mini all",
					},
				],
			],
			exclude: /node_modules/,
			extensions: [...DEFAULT_EXTENSIONS, ".ts", ".tsx"],
			babelHelpers: "bundled",
		}),
		nodeExternals({ devDeps: true }),
	],
};

配置项的意思就不介绍了,感兴趣可以查看我专栏的其他文章:rollup构建组件库系列

试一下构建功能是否 ok。添加一个 npm script:

json 复制代码
{
  "name": "components",
	"version": "1.0.0",
	"scripts": {
		"build": "rollup -c rollup.config.js"
	},
}

添加了一个 build script,在 components 目录中执行npm run build后,目录中多了一个 dist 文件夹:

内容没问题

也可以在 monorepo 根目录中执行构建命令:npm run build -w components。这个命令的意思是执行 components 项目的 npm run build 命令

如果根目录中有多个项目需要执行 npm run build 命令,可以在根目录执行npm run build -w ./表示执行当前目录下所有项目的npm run build命令

准备 playground

上面准备好了 rollup 组件库,还需要一个本地的开发环境 playground。为了方便,直接用 vite 脚手架搭建的 react-ts 模版。

在项目根目录中执行 npm create vite playground -- --template react-ts。执行完后,就可以在可以根目录中看到生成了一个新文件夹:

然后将 playground 注册到根目录的 monorepo 中,在根目录中执行npm init -y -w playground。执行完后,就可以在根目录的 package.json 中看到:

基本环境准备好了,接下来就可以在 playground 中引用组件库中的组件了。不过还有件事:在 components 目录下的 packagejson 中注册组件库的入口:

json 复制代码
{
  "name": "components",
	"version": "1.0.0",
	"description": "",
  // 注册入口
	"module": "./src/index.js",
}

在 playground/src/App.tsx 中引用组件库组件:

tsx 复制代码
import { Button } from "components";
import "./App.css";

function App() {
  return (
    <>
      <Button.Search />
      <Button content='button from playground' />
    </>
  );
}

export default App;

引用了 Button,以及 Search。启动项目看看效果吧。在根目录中执行npm run dev -w playground表示执行 playground 项目下面的npm run dev命令

启动成功,打开网址看看:

刚好是两个 button,没有问题

修改下代码:

tsx 复制代码
function App() {
  return (
    <>
      <Button.Search />
      <Button content='button from playground 1' />
      <Button content='button from playground 2' />
    </>
  );
}

保存刷新浏览器:

没有问题!

playground 就搭建好了

这是项目代码:zenos / monorepo-demo 刚兴趣的宝子们可以去瞅瞅😄

总结

这篇文章分享了如何使用 monorepo 来搭建组件库的 playground,本文的 monorepo 也是基于 npm 来使用的。除了 npm,也可以使用 pnpm,yarn 来搭建 monorepo,都是没有问题的。

虽然本文的组件库是基于 rollup,但不限于 rollup,其他的工具也是可以的。归根结底,monorepo 就是借用了 node_modules依赖查询路径这一规律,让不同项目的代码和依赖得以共享

相关推荐
tedcloud1231 小时前
UI-TARS-desktop部署教程:构建AI桌面自动化系统
服务器·前端·人工智能·ui·自动化·github
Mahir084 小时前
Redis 与 MySQL 数据同步:一致性保证的完整解决方案
数据库·redis·mysql·缓存·面试·数据一致性
UXbot4 小时前
AI原型设计工具如何支持团队协作与快速迭代
前端·交互·个人开发·ai编程·原型模式
ZC跨境爬虫5 小时前
跟着MDN学HTML_day_48:(Node接口)
前端·javascript·ui·html·音视频
刀法如飞6 小时前
Go 字符串查找的 20 种实现方式,用不同思路解决问题
算法·面试·程序员
PieroPc6 小时前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控
巴巴博一7 小时前
2026 最新:Trae / Cursor 一键接入 taste-skill 完整教程(让 AI 前端告别“AI 味”)
前端·ai·ai编程
kyriewen7 小时前
半夜三点线上崩了,AI替我背了锅——用AI排错,五分钟定位三年老bug
前端·javascript·ai编程
kyriewen8 小时前
我让 AI 当了 24 小时全年无休的“毒舌考官”
前端·ci/cd·ai编程
hexu_blog8 小时前
vue+java实现图片批量压缩
java·前端·vue.js