搭建vue3组件库(一): Monorepo架构搭建

打印 上一主题 下一主题

主题 713|帖子 713|积分 2143

1. 以 pnpm 构建 monorepo

   monorepo 是一个项目仓库,内里可以存放多个项目,每个项目可以独立管理,而且可以共享依靠。
pnpm 全称 performant npm,意思为高性能的 npm。pnpm 由 npm/yarn 衍生而来,办理了 npm/yarn 内部潜在的 bug,极大的优化了性能,扩展了使用场景。
  1.1 全局安装 pnpm

  1.   npm install -g pnpm
复制代码
然后在项目下使用 pnpm init 举行 package.json 的初始化,得到 package.json 初始内容,然后把 package.json 中的 name 属性删掉,而且添加一个 “private”: true 属性,由于它是不必要发布的。
为了淘汰因node的版本的差异而产生开辟情况错误,在package.json中增加engines字段来限定版本
为项目指定使用指定版本的node.js,在package.json中增加peerDependencies字段来限定版本
  1.   {
  2.     "private": true,
  3.     "scripts": {},
  4.     "peerDependencies": {
  5.       "vue": "^3.2.0"
  6.     },
  7.     "engines": {
  8.       "node": ">=16"
  9.     },
  10.   }
复制代码
1.2 设置 pnpm 的 monorepo 工作区

在这个仓库下,我们必要管理多个项目,就可以采用 pnpm 的 monorepo。在仓库的根目录下创建一个 pnpm-workspace.yaml 文件,可以在 pnpm-workspace.yaml 设置文件中指定这个仓库中有多少个项目。
  1. packages:
  2. - packages/*
  3. - docs
  4. - play
  5. - internal/*
复制代码
play 目录是示例项目,在开辟的时候可以知道效果是否达到预期;
docs 目录是文档项目,展示组件的使用方法;
internal 目录是内部项目,存放一些私有组件,好比:打包方法、等;
packages 目录是所有组件的项目目录了,在 packages 目录中又可以放很多包的项目目录


  • 组件包目录:components
  1. // packages/components/package.json
  2. {
  3.   "name": "@vision-ui-vue/components",
  4.   "version": "0.0.1",
  5.   "main": "index.ts",
  6.   "module": "index.ts",
  7.   "unpkg": "index.js",
  8.   "jsdelivr": "index.js",
  9.   "peerDependencies": {
  10.     "vue": "^3.2.0"
  11.   },
  12.   "types": "index.d.ts",
  13.   "sideEffects": false
  14. }
复制代码


  • 常量目录:constants
  1. // packages/constants/package.json
  2. {
  3.   "name": "@vision-ui-vue/constants",
  4.   "private": true,
  5.   "license": "MIT",
  6.   "main": "index.ts"
  7. }
复制代码


  • 通用的基于 Composition API 的工具方法: hooks
  1. // packages/hooks/package.json
  2. {
  3.   "name": "@vision-ui-vue/hooks",
  4.   "version": "0.0.1",
  5.   "license": "MIT",
  6.   "main": "index.ts",
  7.   "module": "index.ts",
  8.   "unpkg": "index.js",
  9.   "jsdelivr": "index.js",
  10.   "types": "index.d.ts",
  11.   "peerDependencies": {
  12.     "vue": "^3.2.0"
  13.   }
  14. }
复制代码


  • 国际化包目录:locale
  1. // packages/locale/package.json
  2. {
  3.   "name": "@vision-ui-vue/locale",
  4.   "version": "0.0.1",
  5.   "license": "MIT",
  6.   "main": "index.ts",
  7.   "module": "index.ts",
  8.   "unpkg": "index.js",
  9.   "jsdelivr": "index.js",
  10.   "types": "index.d.ts"
  11. }
复制代码


  • 主题包目录:theme-chalk
  1. // packages/theme-chalk/package.json
  2. {
  3.   "name": "@vision-ui-vue/theme-chalk",
  4.   "version": "0.0.1",
  5.   "license": "MIT",
  6.   "main": "index.css",
  7.   "unpkg": "index.css",
  8.   "jsdelivr": "index.css",
  9.   "style": "index.css"
  10. }
复制代码


  • 工具包目录:utils
  1. // packages/utils/package.json
  2. {
  3.   "name": "@vision-ui-vue/utils",
  4.   "private": true,
  5.   "license": "MIT",
  6.   "main": "index.ts",
  7.   "peerDependencies": {
  8.     "vue": "^3.2.0"
  9.   }
  10. }
复制代码
至此一个初步搭建的项目目录结构如下:
  1. ├── docs
  2. ├── packages
  3. │   ├── components
  4. │   │   ├── index.ts
  5. │   │   └── package.json
  6. │   ├── constants
  7. │   │   ├── index.ts
  8. │   │   └── package.json
  9. │   ├── hooks
  10. │   │   ├── index.ts
  11. │   │   └── package.json
  12. │   ├── locale
  13. │   │   ├── index.ts
  14. │   │   └── package.json
  15. │   ├── theme-chalk
  16. │   │   └── package.json
  17. │   └── utils
  18. │   │   ├── index.ts
  19. │   │   └── package.json
  20. ├── play
  21. ├── package.json
  22. └── pnpm-workspace.yaml
复制代码
1.3 仓库项目内的包相互调用

@vision-ui-vue/components@vision-ui-vue/theme-chalk@vision-ui-vue/utils 这几个包要相互举行调用呢,就必要把它们安装到仓库根目录下的 node_modules 目录中。
在根目录下举行安装操作
  1. pnpm install @vision-ui-vue/components @vision-ui-vue/constants @vision-ui-vue/hooks @vision-ui-vue/locale @vision-ui-vue/theme-chalk @vision-ui-vue/utils -w
复制代码
-w 表示安装到共公模块的 packages.json 中,也就是根目录下的 packages.json
安装后根目录下的 package.json 的内容为:
  1. {
  2.   "dependencies": {
  3.     "@vision-ui-vue/components": "workspace:^",
  4.     "@vision-ui-vue/constants": "workspace:^",
  5.     "@vision-ui-vue/hooks": "workspace:^",
  6.     "@vision-ui-vue/locale": "workspace:^",
  7.     "@vision-ui-vue/theme-chalk": "workspace:^",
  8.     "@vision-ui-vue/utils": "workspace:^"
  9.   }
  10. }
复制代码
workspace:^ 将来发布的时候会被转换成具体的版本号。
1.4 TypeScript 初始化设置文件

安装依靠
  1. pnpm install vue typescript @types/node -D -w
复制代码
安装完成后,实验 pnpm tsc --init 初始化TypeScript设置文件tsconfig.json
2. 通用设置文件

2.1 添加 .editorconfig 编辑器格式设置文件

在根目录新建 .editorconfig 文件,内容如下
  1. # 此文件为 EditorConfig 配置文件,用于设置通用的代码格式化规则。
  2. # root = true 表明此配置文件是根配置,对整个项目生效。
  3. root = true
  4. # 此段配置适用于所有文件类型
  5. [*]
  6. # 字符编码设置为 UTF-8
  7. charset = utf-8
  8. # 使用空格进行缩进,而非制表符
  9. indent_style = space
  10. # 每个层级的缩进大小为 2 个空格
  11. indent_size = 2
  12. # 行尾换行符使用 LF (Unix) 格式
  13. end_of_line = lf
  14. # 在文件末尾自动添加新行
  15. insert_final_newline = true
  16. # 自动删除行尾的多余空格
  17. trim_trailing_whitespace = true
  18. # 引用字符串默认使用单引号
  19. quote_type = single
复制代码
2.2 添加 .gitignore git 忽略文件

在根目录新建 .gitignore 文件,内容如下
  1. # 此文件用于指定在项目中应当被忽略的文件和文件夹
  2. # 忽略的项目主要分为以下几类:
  3. # 编辑器目录和文件
  4. .idea
  5. # 包管理器相关文件
  6. node_modules
  7. .pnpm-debug.log*
  8. # 系统产生的文件
  9. .DS_Store
  10. # 打包输出的目录和文件
  11. dist
  12. coverage
  13. packages/vision-ui-vue/version.ts
  14. # 本地环境配置文件
  15. *.local
  16. .eslintcache
  17. # Cypress 测试产生的文件
  18. cypress/screenshots/*
  19. cypress/videos/*
  20. # 临时文件
  21. tmp
复制代码
2.3 添加 .npmrc npm设置文件

在根目录新建 .npmrc 文件,内容如下
  1. # shamefully-hoist=true: 允许在npm安装时跨范围提升依赖,这可能会导致某些依赖版本的不一致。
  2. shamefully-hoist=true
  3. # strict-peer-dependencies=false: 关闭对peer dependencies的严格检查,这意味着在安装时即使peer dependencies不匹配也不会报错。
  4. strict-peer-dependencies=false
  5. # shell-emulator=true: 启用shell模拟器,这可能在某些环境下用于模拟终端行为,例如在没有真实终端的环境中运行shell命令。
  6. shell-emulator=true
复制代码
2.4 工作区设置



  • 在根目录新建 .vscode 文件夹
  • .vscode 文件夹下新建 settings.json 文件,用来设置vscode编辑器和相关插件
  1. {
  2.   "editor.formatOnSave": true,
  3.   "npm.packageManager": "pnpm",
  4.   "eslint.probe": [
  5.     "javascript",
  6.     "javascriptreact",
  7.     "typescript",
  8.     "typescriptreact",
  9.     "html",
  10.     "vue",
  11.     "markdown",
  12.     "json",
  13.     "jsonc"
  14.   ],
  15.   "eslint.validate": [
  16.     "javascript",
  17.     "javascriptreact",
  18.     "typescript",
  19.     "typescriptreact",
  20.     "html",
  21.     "vue",
  22.     "markdown",
  23.     "json",
  24.     "jsonc"
  25.   ],
  26.   "i18n-ally.localesPaths": "packages/locale/lang"
  27. }
复制代码


  • .vscode 文件夹下新建 extensions.json 文件,推荐当前项目使用的插件
  1. {
  2.   "recommendations": [
  3.     "vue.volar",
  4.     "dbaeumer.vscode-eslint",
  5.     "esbenp.prettier-vscode",
  6.     "antfu.vite",
  7.     "lokalise.i18n-ally"
  8.   ]
  9. }
复制代码
2.5 添加 .gitattributes 设置git 使用的文件和路径的属性



  • 在根目录下新建 .gitattributes 文件,内容如下
  1. #
  2. # 此文件用于配置不同文件类型的属性,主要关注于语言检测设置。
  3. # 文件使用键值对的形式,其中键表示文件扩展名,值则为该文件类型的属性设置。
  4. # 属性设置可以包含多个指令,用等号分隔。这里的指令主要关注于"linguist-detectable",
  5. # 用于告诉GitHub的Linguist库是否应检测和统计特定文件类型。
  6. #
  7. # 配置所有文本文件默认的行尾字符为LF
  8. text=auto eol=lf
  9. # 接下来,对于特定的文件类型,设置其是否被Linguist库检测。
  10. # 对于CSS、SCSS和TS文件,这里设置为不进行检测。
  11. *.ts linguist-detectable=false
  12. *.css linguist-detectable=false
  13. *.scss linguist-detectable=false
  14. # 对于JS和Vue文件,设置为允许Linguist库进行检测。
  15. *.js linguist-detectable=true
  16. *.vue linguist-detectable=true
复制代码
3. play 项目搭建

3.1 使用 Vite 来创建项目

  1. pnpm create vite play --template vue-ts
复制代码
在根目录实验 pnpm install 安装依靠,进入 play 目录实验 pnpm dev 启动项目。但是每次这样实验太贫苦了,可以在根目录的 package.json 文件的 scripts 选项举行以下设置:
  1. {
  2. "scripts": {
  3.     "dev": "pnpm -C play dev"
  4.   }
  5. }
复制代码
这样就可以在根目录通过 pnpm run dev 启动 play 项目内里 package.json 文件中 scripts 选项中对应的 dev 命令了。
4. TypeScript 的 Monorepo 设置

上面通过 pnpm 提供的通过构建 pnpm-workspace.yaml 文件,举行声明对应的工作区的方式构建整个项目标结构。这种方式重要是以功能模块举行划分目录结构的,好比说,一个功能包目录内里包含了测试模块,但在最终举行生产编译打包的时候,不渴望对测试模块的文件举行打包的,所以必要在 TypeScript 编译举行划分模块,让生产的时候只举行核心模块举行编译打包。
4.1 TypeScript 项目引用

tsconfig.json 文件有一个顶级属性references,它支持将 TypeScript 的程序项目分割成更小的组成部门,进而可以进步类型检查和编译的速率。组件库已经接纳 monorepo 的方式举行管理,也就是将项目根据功能的差别拆分成多个子项目,原则上各子项目之间只管淘汰耦合度。好比说上面初步把组件库分成组件部门(packages)和展示部门(play),还有将来的测试部门(tests),测试和展示部门都是依靠组件部门的,但测试和展示部门是没有关联,所以测试或展示任何一部门发生了改变,应该只编译发生改变的部门,别的没有发生变化的部门不应该举行编译才对。
那么通过 tsconfig.json 文件的顶级属性references,就可以将组件库再举行划分,从而变得更加的公道和编译性能的进一步提升。
上面 1.3 步,已经在根目录初始化了tsconfig.json 文件,修改内容如下:
  1. {
  2.   "files": [],
  3.   "references": [
  4.     { "path": "./tsconfig.web.json" }, // 组件包部分
  5.     { "path": "./tsconfig.play.json" } // 组件 play 部分
  6.   ]
  7. }
复制代码
每个引用的 path 属性可以指向包含 tsconfig.json 文件的目录,也可以指向设置文件自己。经过上面的设置,就等于是在 TypeScript 层又把组件库项目分成了三个部门。然后通过具体设置文件举行具体每个部门的 TypeScript 编译项设置。而每个部门都有一些公共的设置项,所以又可以把公共的设置项举行抽离设置到一个公众设置文件中,再通过 extends 举行引用,这样一来就可以大大淘汰雷同的设置代码。
组件包部门设置项 tsconfig.web.json 文件:
  1. {
  2.   "extends": "./tsconfig.base.json",
  3.   "compilerOptions": {
  4.     "composite": true, // 是否开启项目编译,开启该功能,将会生成被编译文件所在的目录,同时开启declaration、declarationMap和incremental,默认:false
  5.     "jsx": "preserve", // 指定JSX代码生成用于的开发环境
  6.     "lib": ["ES2018", "DOM", "DOM.Iterable"], // 指定项目运行时使用的库
  7.     "types": ["unplugin-vue-define-options"], // 用来指定需要包含的模块,并将其包含在全局范围内
  8.     "skipLibCheck": true // 是否跳过声明文件的类型检查,这可以在编译期间以牺牲类型系统准确性为代价来节省时间,默认:false
  9.   },
  10.   "include": ["packages",],// 使用 include 来指定应从绝对类型中使用哪些类型
  11.   "exclude": [ // 提供用于禁用 JavaScript 项目中某个模块的类型获取的配置
  12.     "node_modules",
  13.     "**/dist",
  14.     "**/__tests__/**/*",
  15.     "**/gulpfile.ts",
  16.     "**/test-helper",
  17.     "packages/test-utils",
  18.     "**/*.md"
  19.   ]
  20. }
复制代码
通过 include 属性举行限定组件部门的范围
必要安装依靠 pnpm unplugin-vue-define-options -w -D
组件 play 部门设置项 tsconfig.play.json 文件:
  1. {
  2.   "extends": "./tsconfig.web.json",
  3.   "compilerOptions": {
  4.     "allowJs": true, // 是否允许编译器编译JS,JSX文件
  5.     "lib": ["ESNext", "DOM", "DOM.Iterable"] // 指定项目运行时使用的库
  6.   },
  7.   "include": [ // 使用 include 来指定应从绝对类型中使用哪些类型
  8.     "packages",
  9.     "typings/components.d.ts",
  10.     "typings/env.d.ts",
  11.     "play/main.ts",
  12.     "play/env.d.ts",
  13.     "play/src/**/*"
  14.   ]
  15. }
复制代码
通过 include 属性举行限定 play 部门的范围
公共设置项 tsconfig.base.json 文件:
  1. {
  2.   "compilerOptions": {
  3.     "outDir": "dist", // 指定输出目录
  4.     "target": "es2018", // 目标语言的版本
  5.     "module": "esnext", // 生成代码的模板标准
  6.     "baseUrl": ".", // 解析非相对模块的基地址,默认是当前目录
  7.     "sourceMap": false, // 是否生成相应的Map映射的文件,默认:false
  8.     "moduleResolution": "node", // 指定模块解析策略,node或classic
  9.     "allowJs": false, // 是否允许编译器编译JS,JSX文件
  10.     "strict": true, // 是否启动所有严格检查的总开关,默认:false,启动后将开启所有的严格检查选项
  11.     "noUnusedLocals": true, // 是否检查未使用的局部变量,默认:false
  12.     "resolveJsonModule": true, // 是否解析 JSON 模块,默认:false
  13.     "allowSyntheticDefaultImports": true, // 是否允许从没有默认导出的模块中默认导入,默认:false
  14.     "esModuleInterop": true, // 是否通过为所有导入模块创建命名空间对象,允许CommonJS和ES模块之间的互操作性,开启改选项时,也自动开启allowSyntheticDefaultImports选项,默认:false
  15.     "removeComments": false, // 删除注释
  16.     "rootDir": ".", // 指定输出文件目录(用于输出),用于控制输出目录结构
  17.     "types": [],
  18.     "paths": { // 路径映射,相对于baseUrl
  19.       "@vision-ui-vue/*": ["packages/*"]
  20.     }
  21.   }
  22. }
复制代码
4.2 TypeScript 的类型检查

对于纯 TS 文件的项目,可以通过 tsc --noEmit 命令来举行类型检查,tsc --noEmit 的意思就是只举行 TypeScript 的语法检测,而不会举行编译。在调用 tsc 命令时可以使用命令行参数 –project(或 -p )指定设置文件举行实验。
包含 SFC 单文件(.vue)组件的项目,我们则可以使用 Vue 官方提供的 vue-tsc 工具举行类型检查。
  1. {
  2.   "scripts":{
  3.            "typecheck:web": "vue-tsc -p tsconfig.web.json --composite false --noEmit",
  4.     "typecheck:play": "vue-tsc -p tsconfig.play.json --composite false --noEmit"
  5.         }
  6. }
复制代码
–composite false 不举行增量编译,增量编译指的是生成 .d.ts 和 tsconfig.tsbuildinfo 文件,使用 vue-tsc 法语检查时不能设置为 true。
–noEmit 不举行编译,只举行语法检测。
–composite false --noEmit 不举行编译,也不举行增量编译,只举行语法检测。
–composite false 只能设置为 false,不能设置为 true。
4.3 串行/并行实验脚本

上面举行 TypeScript 类型检查的时候在 package.json 的 script 中设置了多个模块的命令,如果必要同时全部实验所有的命令,必要举行以下的设置:
  1. {
  2.   "scripts":{
  3.     "runall":"pnpm run typecheck:web && pnpm run typecheck:play"
  4.   }
  5. }
复制代码
以上方式属于通过 && 符号来串行实验脚本。
如果必要并行实验脚本,可以使用 & 符号。
npm-run-all 是一个可并行或串行运行多个 npm-scripts 的 CLI 工具。
安装 npm-run-all 工具,安装命令为:
  1. pnpm install npm-run-all -D -w
复制代码
npm-run-all 提供三个命令,分别是 npm-run-all run-s run-p,后两个是 npm-run-all 带参数的简写,分别对应串行和并行。
有了这个包,就可以举行以下设置了:
  1. {
  2.   "scripts":{
  3.     "typecheck": "run-p typecheck:web typecheck:play"
  4.   }
  5. }
复制代码
串行命令和并行命令实验规则:
一个 & 是代表并行实验左指令和右侧指令
两个 && 是代表串行实验,先实验左侧指令,再实验右侧命令
如果一个命令中既包含 & ,也包含 &&。&并行的级别要高一些,首先会实验&左右两侧的命令,然后再根据左右两侧指令情况举行实验。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

东湖之滨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表