前言
相关文章链接:
开发环境配置
下文中的pnpm i在任何目录下都可以执行,pnpm会识别所有的子包。(如果文章中有错误内容,欢迎大家交流指正。)
typescript
- 打开根目录的package.json文件。
- 然后在devDependencies字段中添加typescript以及最新的版本号。
// 根目录 package.json
{
"devDependencies": {
...
"typescript": "5.6.2"
}
}
- 在命令行中运行pnpm i, 下载安装typescript的依赖。
- 在根目录中新建一个ts.config.json文件,用来配置typescript的基本内容(子包的ts继承于根目录tsconfig即可)。
// 根目录 tsconfig.json
{
"compilerOptions": {
"target": "ES2015",
"lib": ["DOM", "ESNext"] ,
"module": "CommonJS",
"moduleResolution": "node",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"jsx": "react-jsx",
},
}
react
- 打开命令行,进入packages/ui的目录下。
- 通过命令
npm init -y生成package.json文件。 - 修改package.json文件的内容。
- 主要增加react和react的类型的依赖,注意此时react的依赖添加值peerDependencies, 表明对其他库的兼容声明。
- 修改name字段,将其修改为“@mini-ui/ui”。
- 具体文件内容参照下面内容:
// packages/ui/package.json { "name": "@mini-ui/ui", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@types/react": "18.3.7" }, "peerDependencies": { "react": "18.3.1" } }
- 在命令行中进入packages/ui目录下, 运行命令
pnpm i, 安装全部依赖。
less
less的配置,主要是通过esbuild的插件实现打包时的转化,具体实现参照打包方案内容。
打包方案
打包方案有很多,比如常见的webpack、vite、rollup等常见打包工具,但是在这里选用了tsup作为打包工具,首先它在对esbuild进行封装后,不仅直接支持了ts的打包,并且打包速度极快。而且tsup几乎不需要怎么配置就可以直接上手使用。
tsup
- 首先进入到packages/ui 的目录下。
- 修改package.json文件的内容。
- 这里主要是增加tsup,以及esbuild的less插件(tsup支持直接使用esbuild插件),提供对ts以及less的处理方案。
// packages/ui/package.json { "name": "@mini-ui/ui", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "tsup": "8.3.0", "esbuild-plugin-less": "1.3.9", "@types/react": "18.3.7" }, "peerDependencies": { "react": "18.3.1" } } - 下载安装tsup以及esbuild-plugin-less, 在当前目录执行
pnpm i。 - 安装之后,创建tsup.config.ts, 对当前打包以及插件进行配置。
// packages/ui/tsup.config.ts
import { defineConfig } from "tsup";
import {lessLoader} from "esbuild-plugin-less";
export default defineConfig({
entry: ["src"], // 打包入口文件
splitting: true,
sourcemap: true, // 是否开启sourcemap, 这里可以关闭。
clean: true,
outDir: "dist", // 打包文件输出目录
dts: true, // 是否打包ts类型
format: ["esm"], // 打包规范
esbuildPlugins: [
lessLoader()
]
})
-
在ui目录下新建一个src目录,并新建一个index.ts文件作为tsup打包的入口文件。
-
在package.json下增加具体的打包命令,同时声明esm规范下的项目入口,以及typescript类型的入口。
// packages/ui/package.json
{
"name": "@mini-ui/ui",
"version": "1.0.0",
"description": "",
"main": "index.js",
"module": "./dist/index.mjs", // esm规范下的项目入口
"types": "./dist/index.d.mts", // typescript类型的入口
"scripts": {
"dev": "tsup --watch",
"build": "tsup"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"tsup": "8.3.0",
"esbuild-plugin-less": "1.3.9",
"@types/react": "18.3.7"
},
"peerDependencies": {
"react": "18.3.1"
}
}
- 测试, 在packages/ui目录下,执行
pnpm run build, 即可打包出对应的dist文件。
pnpm build
测试
声明Button
-
进入ui/src目录下创建compoents/Button目录,在内部创建Button.tsx、index.ts、interface.ts、style/index.less文件,分别对应button组件文件,导出出口,类型声明, 样式文件。
- Button.tsx
// packages/ui/src/components/Button/Button.tsx import {ButtonProps} from "./interface"; import "./style/index.less" export const Button = ( props: ButtonProps ) => { return <button className="mini-btn">this is a button</button> } - index.ts
// packages/ui/src/components/Button/index.ts export * from "./Button"; - interface.ts
// packages/ui/src/components/Button/interface.ts import { ReactNode } from "react"; export interface ButtonProps { children?: ReactNode; } - style/index.less
.mini-btn { color: #1a1a1a; background-color: #fff; }
- Button.tsx
-
然后在ui/src/components目录下的新建index.ts文件中导出Button组件的内容。
// packages/ui/src/components/index.ts export * from "./Button"; -
然后在ui/src/目录下的index.ts文件(tsup配置的第5步)中导出components下的所有内容。
// packages/ui/src/index.ts export * from "./components"; -
在package/ui下运行
pnpm build命令, 重新打包。 -
最终目录结构如下图:
playground中引入组件
- 进入apps目录下,然后运行
pnpm create vite playground --template react-ts(这里使用的是vite,其他的脚手架也是一样的)创建一个新的react项目。 - 修改playground目录下的package.json, 添加组件库的包,这里使用的是pnpm-workspace的语法, 具体参考下面的内容:
// apps/playground/package.json
{
"name": "demo",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "tsc -b && vite build",
"lint": "eslint .",
"preview": "vite preview"
},
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"@mini-ui/ui": "workspace: *" // 引入刚才打包的组件库,注意需要和目标package.jsonname保持一致
},
"devDependencies": {
"@eslint/js": "^9.9.0",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^9.9.0",
"eslint-plugin-react-hooks": "^5.1.0-rc.0",
"eslint-plugin-react-refresh": "^0.4.9",
"globals": "^15.9.0",
"typescript": "^5.5.3",
"typescript-eslint": "^8.0.1",
"vite": "^5.4.1"
}
}
- 在playground目录下运行
pnpm i命令,更新安装包。 - 启动react项目的服务,然后在playground的目录下,引入组件库的文件, 若无报错,像下图button组件正常展示,即说明目前配置正常。
// apps/playground/src/App.tsx
import { Button } from "@mini-ui/ui"
import "@mini-ui/ui/dist/index.css"
function App() {
return (
<>
<Button></Button>
</>
)
}
export default App
项目地址
未完待续
后续补充文档方案(rspress)。