从项目架构开始了解Element-Plus组件库

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"],//用于指定包含的模块,并将其包含在全局
}
相关推荐
Mintopia8 小时前
动态数据驱动的 AIGC 模型:Web 端实时更新训练的技术可行性
前端·javascript·aigc
中微子8 小时前
Vue 2 与 Vue 3 组件写法对比
前端·javascript·vue.js
Nayana8 小时前
Element-Plus源码分析--button组件
前端·前端框架
中微子8 小时前
Vue 3 JavaScript 最佳实践指南
前端·javascript·vue.js
zerosrat8 小时前
从零实现一个 JavaScript 引擎
javascript
Keepreal4968 小时前
使用 Three.js 和 GSAP 动画库实现3D 名字抽奖
javascript·vue.js·three.js
向葭奔赴♡9 小时前
HTML的本质——网页的“骨架”
前端·javascript·html
清欢ysy9 小时前
Cannot find module ‘@next/bundle-analyzer‘
开发语言·javascript·arcgis
江城开朗的豌豆9 小时前
小程序避坑指南:这些兼容性问题你遇到了几个?
前端·javascript·微信小程序