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依赖查询路径这一规律,让不同项目的代码和依赖得以共享

相关推荐
真滴book理喻几秒前
Vue(四)
前端·javascript·vue.js
蜜獾云2 分钟前
npm淘宝镜像
前端·npm·node.js
dz88i83 分钟前
修改npm镜像源
前端·npm·node.js
Jiaberrr7 分钟前
解锁 GitBook 的奥秘:从入门到精通之旅
前端·gitbook
顾平安1 小时前
Promise/A+ 规范 - 中文版本
前端
聚名网1 小时前
域名和服务器是什么?域名和服务器是什么关系?
服务器·前端
桃园码工1 小时前
4-Gin HTML 模板渲染 --[Gin 框架入门精讲与实战案例]
前端·html·gin·模板渲染
沈剑心2 小时前
如何在鸿蒙系统上实现「沉浸式」页面?
前端·harmonyos
码农爱java2 小时前
设计模式--抽象工厂模式【创建型模式】
java·设计模式·面试·抽象工厂模式·原理·23种设计模式·java 设计模式
一棵开花的树,枝芽无限靠近你2 小时前
【PPTist】组件结构设计、主题切换
前端·笔记·学习·编辑器