likes
comments
collection
share

👊rollup实战(五)之用monorepo搭建组件库开发环境

作者站长头像
站长
· 阅读数 13

这是一个系列专栏,将会更新一系列rollup的实战内容,主要围绕着用rollup构建组件库、构建测试环境、搭建单元测试、构建过程的再优化等内容

本篇文章曾用名:《🙋你知道,如何结合monorepo搭建组件库开发环境吗?》

前言

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

不过用 monorepo 似乎逼格更高点哈哈,所以这篇文章来分享下

准备 monorepo

首先准备一个空文件夹,终端执行npm init -y:👊rollup实战(五)之用monorepo搭建组件库开发环境

是的,这是基于 npm 使用 monorepo

然后创建 components 文件夹存放组件库代码👊rollup实战(五)之用monorepo搭建组件库开发环境进到 components 文件夹,用 npm 初始化一下npm init -y, 生成了一个 package.json:

{
  "name": "components",
	"version": "1.0.0",
}

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

{
  "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 组件库安装依赖了, 在根目录执行:

npm i rollup -w components

这个命令的意思是向 components 项目安装一个 rollup 依赖,-w指定项目。执行完安装命令之后,就是这样:👊rollup实战(五)之用monorepo搭建组件库开发环境在项目根目录中生成了一个 node_modules 文件夹,里面有刚才安装的 rollup 依赖。这就是 monorepo 于普通项目的不同之处了--多个项目共享一个 node_modules,并不会在项目目录里面生成 node_modules。

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

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

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

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 组件:👊rollup实战(五)之用monorepo搭建组件库开发环境这是 Button 组件的内容:👊rollup实战(五)之用monorepo搭建组件库开发环境这是 Search 组件的内容:👊rollup实战(五)之用monorepo搭建组件库开发环境index.ts 作为整个组件库的入口和出口,内容是这样的:

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 }),
	],
};

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

{
  "name": "components",
	"version": "1.0.0",
	"scripts": {
		"build": "rollup -c rollup.config.js"
	},
}

添加了一个 build script,在 components 目录中执行npm run build后,目录中多了一个 dist 文件夹:👊rollup实战(五)之用monorepo搭建组件库开发环境内容没问题

也可以在 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。执行完后,就可以在可以根目录中看到生成了一个新文件夹:👊rollup实战(五)之用monorepo搭建组件库开发环境

然后将 playground 注册到根目录的 monorepo 中,在根目录中执行npm init -y -w playground。执行完后,就可以在根目录的 package.json 中看到:👊rollup实战(五)之用monorepo搭建组件库开发环境

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

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

然后在 playground 中安装 components:

npm i components -w playground

playground/package.json:

{
  "name": "playground",
  "private": true,
  "version": "0.0.0",
  "dependencies": {
    // 添加依赖项
    "components": "^1.0.0",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
}

上面的依赖项可以换成"components": "*"


下面就可以在 playground/src/App.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命令👊rollup实战(五)之用monorepo搭建组件库开发环境启动成功,打开网址看看:👊rollup实战(五)之用monorepo搭建组件库开发环境刚好是两个 button,没有问题

为什么Button可以访问components呢?因为

修改下代码:

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

保存刷新浏览器:👊rollup实战(五)之用monorepo搭建组件库开发环境

没有问题!

playground 就搭建好了

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

总结

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

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

这篇文章看完,大家有什么收获吗,欢迎在评论区留言哦

转载自:https://juejin.cn/post/7325261939431686180
评论
请登录