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

相关推荐
(⊙o⊙)~哦1 小时前
JavaScript substring() 方法
前端
无心使然云中漫步1 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者1 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_2 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
麒麟而非淇淋3 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120533 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢3 小时前
【Vue】VueRouter路由
前端·javascript·vue.js
随笔写4 小时前
vue使用关于speak-tss插件的详细介绍
前端·javascript·vue.js
史努比.4 小时前
redis群集三种模式:主从复制、哨兵、集群
前端·bootstrap·html
快乐牌刀片885 小时前
web - JavaScript
开发语言·前端·javascript