Element-Plus 是基于TS+Vue3.0 对Element-UI重构的全新项目
优点:
- TypeScript通过静态类型检查,在编码阶段发现潜在类型错误,避免运行时异常。TS的强制变量类型匹配可减少因隐式类型转换导致的逻辑错误,增强代码的可读性和可维护性。
- Vue3.0 Composition API 更灵活的状态管理,更好的逻辑复用 降低耦合,简化逻辑。
从Element-Plus源码解析中我更关注的点是:
- 组件库的代码架构;
- 学习组件的实现方法;
- 如何设计可复用,可配置的高质量UI组件;
- 如何优化组件;
从组件的代码架构方面来看项目的整个目录:

主要目录是:
packages/components/
:核心组件功能模块。包括packages
目录下的components (组件源码)
、constants (全局常量)
、directives (组件自定义指令)
、hooks (全局hooks)
、local (组件全局语言)
、test-utils (测试工具函数)
、theme-chalk (组件全局样式)
、utils (全局工具函数)
。packages
目录下所有的文件夹对应的都是一个独立的模块。packages/theme-chalk/
:样式文件(SCSS)。docs/
:官方文档模块它由vitepress
构建的。scripts/
:构建和开发脚本。tests/
:单元测试和集成测试。play/
:用于开发自定义组件并调试的模块。examples/
:示例项目,展示组件用法。internal/
:目录下可能包含一些未公开的组件,这些组件可能在库的某些内部功能中使用,例如特定的过渡效果、布局组件等。
可以看出项目库为monorepo 模式,其中docs internal/* packages/* play 都是子项目,在monorepo 模式下只需要关注管理子项目下的pakckage文件,在根目录进行npm操作即可。element-plus 使用的是pnpm ,pnpm会将子项目重复下载的库提取到根目录的node_modules里避免重复下载依赖
什么是 monorepo 项目管理模式
monorepo
是项目管理的一种模式叫做单仓多模块,多个项目放在一个仓库里面。用统一的本地关联、构建、发布流程,来消费业务域下所有管理的组件模块。
项目管理模式还有:
Monolithic
(单体应用架构)一个代码仓库承接一个应用.随着迭代业务复杂度的提升,项目代码会变得越来越多,越来越复杂,大量代码构建效率也会降低,最终导致了单体巨石应用。Multirepo
(多仓多模块管理)将项目拆解成多个业务模块,并在多个 Git 仓库管理,模块解耦,降低了巨石应用的复杂度,每个模块都可以独立编码、测试、发版。
以下是3种项目管理模式的示例图:
monorepo 环境搭建过程
以 pnpm 构建 monorepo 首先进行全局安装 pnpm
js
npm install pnpm -g
pnpm init
配置monorepo 工作区
在仓库根目录下新建pnpm-workspace.yaml文件,并制定多个模块。

子模块的components包package.json示例
js
{
"name": "@element-plus/components",
"version": "0.0.5",
"description": "all components are settled here",
"main": "index.ts",
"module": "index.ts",
"unpkg": "index.js",
"jsdelivr": "index.js",
"peerDependencies": {
"vue": "^3.2.0"
},
"types": "index.d.ts",
"sideEffects": [
"*/style/*"
],
"gitHead": "c69724230befa8fede0e6b9c37fb0b7e39fd7cdd"
}
由于仓库内的包需要相互调用 @element-plus/components"、@element-plus/constants"、@element-plus/directives"、 @elementplus/utils"等子包需要相进行调用,就需要把它们安装到仓库根目录下的 node_modules
目录中。
js
pnpm install @element-plus/components -w
pnpm install @element-plus/constants -w
pnpm install @element-plus/utils -w
***
根目录的package.json的内容会新增

TypeScript 初始化配置文件
安装tS依赖示例
js
pnpm install vue typescript @types/node -D -w
pnpm tsc --init //代码提示初始化配置
TypeScript 的 Monorepo 设置
上述pnpm 提供的通过构建 pnpm-workspace.yaml 文件,进行声明对应的工作区的方式构建整个项目的结构。这种方式主要是以功能模块进行划分目录结构的,比如说,一个功能包目录里面包含了测试模块,但在最终进行生产编译打包的时候,我们是不希望对测试模块的文件进行打包的,所以我们需要在 TypeScript 编译进行划分模块,让生产的时候只进行核心模块进行编译打包
TypeScript 项目引用 (project references)
通过 tsconfig.json 文件的顶级属性"references",就可以将我们的组件库再进行划分,从而变得更加的合理和编译性能的进一步提升。 以下为tsconfig.json示例
公共配置项 tsconfig.base.json 文件:
js
{
"compilerOptions": {
"outDir": "dist", // 指定输出目录
"target": "es2018", // 目标语言的版本
"module": "esnext", // 生成代码的模板标准
"baseUrl": ".", // 解析非相对模块的基地址,默认是当前目录
"sourceMap": false, // 是否生成相应的Map映射的文件,默认:false
"moduleResolution": "node", // 指定模块解析策略,node或classic
"allowJs": false, // 是否允许编译器编译JS,JSX文件
"strict": true, // 是否启动所有严格检查的总开关,默认:false,启动后将开启所有的严格检查选项
"noUnusedLocals": true, // 是否检查未使用的局部变量,默认:false
"resolveJsonModule": true, // 是否解析 JSON 模块,默认:false
"allowSyntheticDefaultImports": true, // 是否允许从没有默认导出的模块中默认导入,默认:false
"esModuleInterop": true, // 是否通过为所有导入模块创建命名空间对象,允许CommonJS和ES模块之间的互操作性,开启改选项时,也自动开启allowSyntheticDefaultImports选项,默认:false
"removeComments": false, // 删除注释
"rootDir": ".", // 指定输出文件目录(用于输出),用于控制输出目录结构
"types": [],
"paths": { // 路径映射,相对于baseUrl
"@element-plus/components": ["packages/components"],
"@element-plus/utils": ["packages/utils"],
"@element-plus/hooks": ["packages/hooks"],
"@element-plus/directives": ["packages/directives"],
"@element-plus/constants": ["packages/constants"],
"@element-plus/locale": ["packages/locale"],
"element-plus": ["packages/element-plus"]
},
"preserveSymlinks": true
}
}
子项目包的配置tsconfig.web.json
:
js
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"composite": true,
"jsx": "preserve", // 指定JSX代码生成用于的开发环境
"lib": ["ES2018", "DOM", "DOM.Iterable"],// 指定项目运行时使用的库
"types":["unplugin-vue-macros/macros-global"],//用于指定包含的模块,并将其包含在全局
}