从零搭建一个组件库(一)项目环境搭建

news2024/11/27 10:44:48

文章目录

    • 前言
    • monorepo架构
      • 1.monorepo架构的优势
      • 2.使用pnpm搭建monorepo架构
          • (1)全局安装pnpm
          • (2)初始化项目
          • (3)新建workspace.yaml文件
      • 4.不同包之间的相互引用
    • TypeScript支持
      • 1.安装TypeScript
      • 2.初始化TypeScript
      • 3.配置TypeScript
    • play环境搭建
    • docs环境搭建
    • 通用包和工程化工具安装
    • 总结
    • 参考资料

前言

组队大项目选择了组件库开发,一开始决定选题时候,大家都觉得这个题目会很难写,等到实际上手开发的时候,才发现这个项目确实没那么好写。

开发组件库的第一步就是要确定组件库的整体架构和技术选型,这方面我主要参考了Element-plus。架构方面使用基于pnpm实现的monorepo架构,对项目的代码进行组织和管理;css预处理器选择了Sass,定义了classname的BEM规范、cssvar变量的一系列utils和一些其他的样式处理工具;测试工具采用vitest;组件库文档采用vitepress。

monorepo架构

monorepo指的是在一个仓库中,存在多个不同的项目。这些项目可能是相关联的,但在逻辑上它们是独立的。

1.monorepo架构的优势

monorepo可以使多个项目共用一套基础配置,且有依赖的项目之间的调试会变得非常方便,并且可以统一管理第三方库的版本。

2.使用pnpm搭建monorepo架构

关于pnpm的优势在这里就不过多赘述了(用过的都说好)。这里使用pnpm的主要原因是,pnpm它内置了对monorepo的支持,并且实现方式也非常简单。

(1)全局安装pnpm
npm install pnpm -g
(2)初始化项目

在项目目录下使用pnpm init命令,初始化package.json文件。

pnpm init

删除name属性,并添加一个private属性,因为根文件夹是不需要发布的。

{
  "private": true,
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
(3)新建workspace.yaml文件

在项目根目录下创建pnpm-workspace.yaml文件,用于指定不同工作区的文件夹。

packages:
  - play # 组件测试代码
  - docs # 组件文档
  - packages/* # 组件包

packages包下通常会包含各类组件相关的文件夹,比如components、theme-chalk和utils等,以components为例,我们去到components的文件夹下使用pnpm init命令初始化工作区的package.json文件。并将package.json的name属性改为@组件名+工作区名。其他两个工作区theme-chalk和utils也是如此。

// components
{
  "name": "@voile-ui/components",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

至此,我们当前的项目目录结构如下:

image.png

4.不同包之间的相互引用

我们先将packages下的包都安装到项目的根目录中。

pnpm i @voile-ui/components -D -w
pnpm i @voile-ui/theme-chalk -D -w
pnpm i @voile-ui/utils -D -w

-w表示将包安装到公共模块,也就是根目录下。然后,我们就可以在不同的包之间相互进行引用了。

TypeScript支持

1.安装TypeScript

pnpm i typescript -D -w

2.初始化TypeScript

pnpm tsc --init

3.配置TypeScript

在tsconfig.json中,有一个顶级属性references,它可以将项目进一步划分为更小的子模块,分别进行类型检查和编译,从而提升整体的性能。

"references": [
    { "path": "./tsconfig.web.json" }, // 组件包
    { "path": "./tsconfig.play.json" } // 组件 play
  ],

然后分别创建这些配置文件。

// tsconfig.base.json
{
  "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
      "@voile-ui/*": ["packages/*"]
    }
  }
}

// tsconfig.web.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "composite": true, // 是否开启项目编译,开启该功能,将会生成被编译文件所在的目录,同时开启declaration、declarationMap和incremental,默认:false
    "jsx": "preserve", // 指定JSX代码生成用于的开发环境
    "lib": ["ES2018", "DOM", "DOM.Iterable"], // 指定项目运行时使用的库
    "types": ["unplugin-vue-define-options","unplugin-vue-define-options/macros-global"], // 用来指定需要包含的模块,并将其包含在全局范围内
    "skipLibCheck": true // 是否跳过声明文件的类型检查,这可以在编译期间以牺牲类型系统准确性为代价来节省时间,默认:false
  },
  "include": ["packages"], // 使用 include 来指定应从绝对类型中使用哪些类型
  "exclude": [
    // 提供用于禁用 JavaScript 项目中某个模块的类型获取的配置
    "node_modules",
    "**/dist",
    "**/__tests__/**/*",
    "**/gulpfile.ts",
    "**/test-helper",
    "packages/test-utils",
    "**/*.md"
  ]
}

// tsconfig.play.json
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "composite": true, // 是否开启项目编译,开启该功能,将会生成被编译文件所在的目录,同时开启declaration、declarationMap和incremental,默认:false
    "jsx": "preserve", // 指定JSX代码生成用于的开发环境
    "lib": ["ES2018", "DOM", "DOM.Iterable"], // 指定项目运行时使用的库
    "types": ["unplugin-vue-define-options","unplugin-vue-define-options/macros-global"], // 用来指定需要包含的模块,并将其包含在全局范围内
    "skipLibCheck": true // 是否跳过声明文件的类型检查,这可以在编译期间以牺牲类型系统准确性为代价来节省时间,默认:false
  },
  "include": ["packages"], // 使用 include 来指定应从绝对类型中使用哪些类型
  "exclude": [
    // 提供用于禁用 JavaScript 项目中某个模块的类型获取的配置
    "node_modules",
    "**/dist",
    "**/__tests__/**/*",
    "**/gulpfile.ts",
    "**/test-helper",
    "packages/test-utils",
    "**/*.md"
  ]
}

play环境搭建

play环境搭建其实就是在根目录下创建了一个名为play的vue项目。

pnpm create vite play --template vue

docs环境搭建

docs环境同样是在根目录下创建一个名为docs的vitepress项目

pnpm i vitepress -D -w

通用包和工程化工具安装

pnpm i vue, sass, prettier, husky, @vueuse/core, eslint, 

总结

至此,一个基本的组件库开发环境就已经搭建好了,接下来就要对代码书写规范、git提交规范、公共样式属性、命名风格等这些规定做详细的设置,然后就可以开始开发组件了。

参考资料

https://github.com/element-plus/element-plus

https://juejin.cn/post/7146183222425518093

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177532.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

http三次握手四次挥手详解

1、 TCP的三次握手和四次挥手实质就是TCP通信的连接和断开。 三次握手:为了对每次发送的数据量进行跟踪与协商,确保数据段的发送和接收同步,根据所接收到的数据量而确认数据发送、接收完毕后何时撤消联系,并建立虚连接。 四次挥…

C++6:STL-模拟实现string

string时STL中的模板库之一,类似于专门处理字符串的数据结构,在模拟实现并探讨其中构造的巧妙之处之前,我们短浅的认识一下STL是什么 目录 什么是STL STL的诞生 关于string string的模拟实现 构造函数和析构函数 实现简单的string打印 …

【蓝桥杯】简单数论2——快速幂矩阵快速幂

1、快速幂 1.1运算模 定义:模运算为a除以m的余数,记为a mod m,有a mod m a % m。 模运算是大数运算中的常用操作:如果一个数太大,无法直接输出,或者不需要直接输出,可以把它取模后&#xff0…

Android 深入系统完全讲解(37)

7.5 源码讲解 dlopen 打开动态库 dlsym 找到符号 (*print_func)(); 调用方法 我们可以看到,要使用一个 so 库的某个方法,就上面三步骤,加载 ,查找 ,使用 。我 们这里调用了 so 库中的 my_print 方法。 7.6 运行 我们把…

Linux——进程间通信

文章目录前言1. 进程间通信方式的一些标准:2. 管道2.1 什么是管道2.2 管道的原理2.3 匿名管道2.3.1 实例代码1. demo代码2. 总结管道的特点,理解以前的管道 |3. 扩展——进程池2.4 管道读写规则2.5 命名管道2.5.1 创建一个命名管道2.5.2 命名管道的打开规…

Python break用法详解

我们知道,在执行 while 循环或者 for 循环时,只要循环条件满足,程序将会一直执行循环体,不停地转圈。但在某些场景,我们可能希望在循环结束前就强制结束循环,Python 提供了 2 种强制离开当前循环体的办法&a…

路由处理及功能(实现了权限控制vue admin)

界面简化 将 template 改为&#xff1a; <template><div class"login-container"><el-formref"loginForm":model"loginForm":rules"loginRules"class"login-form"autocomplete"on"label-positio…

Mybatis遇到的脑残问题

一、MySQL的版本问题 有的教程mysql是8.0版本使用jar包不一样 <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0</version></dependency>然后我查了一下我的mysql版本是5.7版…

分支语句与循环语句

文章目录 什么是语句&#xff1f; 分支语句&#xff08;选择结构&#xff09;循环语句goto语句前言 一、什么是语句&#xff1f; C语句可分为以下五类&#xff1a; 1. 表达式语句 2. 函数调用语句 3. 控制语句 4. 复合语句 5. 空语句 控制语句用于控制程序的执行流程&#xff0…

第九层(1):初识STL

文章目录前情回顾初识STLSTL的诞生STL的基本概念STL六大组件STL中的容器、算法、迭代器容器算法迭代器容器、算法、迭代器的配合使用vector中的嵌套使用石碑倒下...后面还有石碑&#xff1f;本章知识点&#xff08;图片形式&#xff09;&#x1f389;welcome&#x1f389; ✒️…

为什么带NOLOCK的查询语句还会造成阻塞

背景客户反映HIS数据库在11点出现了长时间的阻塞&#xff0c;直到手动KILL掉阻塞的源头。请我们协助分析原因&#xff0c;最终定位到.NET程序中使用的SqlDataReader未正常关闭导致。现象登录SQL专家云&#xff0c;进入趋势分析&#xff0c;在活动会话中回溯11点一个小时内的运行…

【Ajax】防抖和节流

一、防抖什么是防抖防抖策略&#xff08;debounce&#xff09;是当事件被触发后&#xff0c;延迟 n 秒后再执行回调&#xff0c;如果在这 n 秒内事件又被触发&#xff0c;则重新计时。如果事件被频繁触发&#xff0c;防抖能保证只有最有一次触发生效&#xff01;前面 N 多次的触…

【Linux IO】文件描述符、重定向、缓冲区

1.open函数1.1第二个参数的解释&#xff1b;O_RDONLY: 只读打开 O_WRONLY: 只写打开 O_RDWR : 读&#xff0c;写打开上面三个常量&#xff0c;必须指定一个且只能指定一个 O_CREAT : 若文件不存在&#xff0c;则创建它。需要使用mode选项&#xff0c;来指明新文件的访问权限 O_…

MyBatis 连接数据库与增删改查

❤️作者主页&#xff1a;微凉秋意 ✅作者简介&#xff1a;后端领域优质创作者&#x1f3c6;&#xff0c;CSDN内容合伙人&#x1f3c6;&#xff0c;阿里云专家博主&#x1f3c6; ✨精品专栏&#xff1a;数据结构与课程设计 &#x1f525;系列专栏&#xff1a;javaweb 文章目录前…

C++设计模式(8)——命令模式

命令模式 亦称&#xff1a;动作、事务、Action、Transaction、Command 意图 命令模式是一种行为设计模式&#xff0c; 它可将请求转换为一个包含与请求相关的所有信息的独立对象。 该转换让你能根据不同的请求将方法参数化、 延迟请求执行或将其放入队列中&#xff0c; 且能…

linux基本功系列之-lsattr命令实战

文章目录一. lsattr命令实战二. 语法格式及常用选项三. 参考案例3.1 查看指定文件上的隐藏属性&#xff1a;3.2 查看目录的隐藏属性3.3 查看目录中全部文件的隐藏属性总结前言&#x1f680;&#x1f680;&#x1f680; 想要学好Linux&#xff0c;命令是基本功&#xff0c;企业中…

英语学习打卡day4

2023.1.24 1.out of curiosity 出于好奇 out of necessity 出于必要 out of interest 出于利益 out of sympathy 出于同情 out of respect 出于尊敬 out of’ fear 出于害怕 out of desperation 出于不得已/绝望 2.ashore adv.向(或在)岸上;上岸 a在… …的 shore岸- >在…

Java 23种设计模式(5.结构型模式-代理模式)

结构型模式 代理模式 结构型模式描述如何将类或对象按某种布局组成更大的结构。 它分为类结构型模式和对象结构型模式&#xff0c;前者采用继承机制来组织接口和类&#xff0c;后者釆用组合或聚合来组合对象。 由于组合关系或聚合关系比继承关系耦合度低&#xff0c;满足“合成…

分享127个ASP源码,总有一款适合您

ASP源码 分享127个ASP源码&#xff0c;总有一款适合您 下面是文件的名字&#xff0c;我放了一些图片&#xff0c;文章里不是所有的图主要是放不下...&#xff0c; 127个ASP源码下载链接&#xff1a;https://pan.baidu.com/s/1JpOFmxkovbScxmz0_MhUWg?pwd758t 提取码&#x…

算法:一维与二维最大连续子序列和(子矩阵和,c++实现 动态规划)

文章目录一维最大连续子序列和代码示例二维最大连续子序列和、代码示例一维最大连续子序列和 给你一个序列 【-1&#xff0c;-2&#xff0c;3&#xff0c;6&#xff0c;4&#xff0c;-9】的最大的连续的子序列和的值。 什么是最大连续子序列和&#xff0c;首先要满足两个条件…