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

相关推荐
桂月二二31 分钟前
探索前端开发中的 Web Vitals —— 提升用户体验的关键技术
前端·ux
hunter2062062 小时前
ubuntu向一个pc主机通过web发送数据,pc端通过工具直接查看收到的数据
linux·前端·ubuntu
qzhqbb2 小时前
web服务器 网站部署的架构
服务器·前端·架构
刻刻帝的海角2 小时前
CSS 颜色
前端·css
浪浪山小白兔3 小时前
HTML5 新表单属性详解
前端·html·html5
lee5763 小时前
npm run dev 时直接打开Chrome浏览器
前端·chrome·npm
2401_897579653 小时前
AI赋能Flutter开发:ScriptEcho助你高效构建跨端应用
前端·人工智能·flutter
limit for me4 小时前
react上增加错误边界 当存在错误时 不会显示白屏
前端·react.js·前端框架
浏览器爱好者4 小时前
如何构建一个简单的React应用?
前端·react.js·前端框架
qq_392794484 小时前
前端缓存策略:强缓存与协商缓存深度剖析
前端·缓存