从零到一构建并打包 React + TypeScript + Less组件库教程(一、项目初始化搭建+代码规范集成)

news/2025/1/11 18:42:43/文章来源:https://www.cnblogs.com/jsonq/p/18538403

本系列涉及的内容如下:

  1. 组件库基础搭建,react + ts + less
  2. 项目规范,包括但不限于 prettier、eslint、stylelint、husky、lint-staged、commitlint
  3. pnpm monorepo + turborepo 集成
  4. gulp + webpack 构建 esm、cjs 和 umd
  5. storybook 文档集成

此系列不包含发布 npm 和构建 CI 流程。

此系列不是所谓的最佳实践,流行组件库经过迭代都非常完善,不是一人力能完成的,而本系列只是将功能上的核心进行了总结

  • 阅读本系列需要对组件库的构成有一定的了解,不多,一点点即可,纯小白可能会有点难入手。
  • 后续有时间会追加一篇 React Icon 组件库的构建。

本篇的内容可直接查看 commit:https://github.com/json-q/rc-library-templete/commit/edaa1adb6772babf475612a754566f0dbefa52fb

初始化项目

mkdir react-library-templete
cd react-library-templete
pnpm init

package.json 初始化工作

由于是 pnpm monorepo 项目,必须使用 pnpm,可以在 package.json 中做一下限制

  "scripts": {"preinstall": "npx only-allow pnpm",},"packageManager": "pnpm@9.12.3","engines": {"node": ">=20"},
  • packageManager 可以不写,主要作用是为了约束开发都是用这个版本,避免包管理工具版本不一致导致的兼容问题
  • engines 指定项目使用的 node 版本

注意: 一旦声明 packageManager,在执行 install 时,会提示你是否替换成指定版本,此替换为全局的版本替换,之前的安装版本将被覆盖

安装基础依赖

使用 TypeScript + Less 编写,肯定要安装 typescript 和 less,如果涉及到 node 相关的,还可以再安装一个 @types/node 类型提示

pnpm i typescript less @types/node -D

项目规范

集成 eslint

需提前安装 ESLint 插件

pnpm dlx @eslint/create-config

image

eslint 基本结构有了,再装一些辅助插件

pnpm i eslint-plugin-react-hooks eslint-plugin-jsx-a11y eslint-plugin-react-refresh -D
  • eslint-plugin-jsx-a11y 是一个无障碍访问的 eslint 检测,可按需安装
  • eslint-plugin-react-refresh 检测 react 组件是否可以安全刷新,可按需安装

eslint.config.mjs 中添加这几个插件

import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginReact from "eslint-plugin-react";
import reactRefresh from 'eslint-plugin-react-refresh';
import jsxA11y from 'eslint-plugin-jsx-a11y';
import reactHooks from 'eslint-plugin-react-hooks';/** @type {import('eslint').Linter.Config[]} */
export default [{files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"]},{languageOptions: { globals: globals.browser}},pluginJs.configs.recommended,...tseslint.configs.recommended,pluginReact.configs.flat.recommended,jsxA11y.flatConfigs.recommended,{plugins: {'react-hooks': reactHooks,'react-refresh': reactRefresh,},rules: {...reactHooks.configs.recommended.rules,'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],},},{ignores: ['**/dist/*','**/es/*','**/lib/*','node_modules','*.woff','.ttf','.vscode','.idea','.husky','.local','/bin','.eslintcache','.stylelintcache',],},
];

eslint 配置过程中,可以新建一个 ts 文件,写一些不规范代码,时刻查看 eslint 的检测是否会失效,因为由于写法错误也会导致 eslint 的配置失效。

集成 Prettier

需提前安装 Prettier 插件

pnpm i prettier eslint-plugin-prettier eslint-config-prettier -D

新建 .prettierrc.cjs

/** @type {import("prettier").Config} */
module.exports = {printWidth: 120,useTabs: false,singleQuote: true,proseWrap: 'never',
};

新建 .prettierignore

**/dist/*
**/es/*
**/lib/***/.local
**/node_modules/****/*.svg
**/*.sh.eslintcache
.stylelintcache

此时你可以发现 .prettierrc.cjs 被 eslint 报错了

image

这是由于 module 是 node 环境的全局变量,而 eslint 不识别 node 环境。在 eslint.config.mjs 中的 globals 属性添加 node 全局变量

export default [// ...{languageOptions: { globals: {...globals.browser,...globals.node}}},// ...
];

此时就没问题了

prettier 和 eslint 的集成

前边写过的都省略掉了,只列出更改的部分。该部分让 eslint 和 prettier 做了集成,并添加了一项 eslint 关闭校验的规则 @typescript-eslint/no-explicit-any,即此时是允许使用 any 的(默认禁止使用 any)

// ...
import eslintConfigPrettier from 'eslint-config-prettier';
import prettierRecommended from 'eslint-plugin-prettier/recommended';/** @type {import('eslint').Linter.Config[]} */
export default [// ...eslintConfigPrettier,prettierRecommended,{// ...rules: {// ...'@typescript-eslint/no-explicit-any': 'off',},},
];

不出意外的话,此时就能看到 eslint.config.mjs 中存在大量的 prettier 报错提示。

image

在根目录新建一个 .vscode 文件夹,在文件夹内部新建 settings.json 文件

{"search.exclude": {"**/node_modules": true,"dist": true,"es": true,"lib": true,"storybook-static": true,"pnpm-lock.yaml": true},"editor.codeActionsOnSave": {"source.fixAll": "explicit"},"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","stylelint.validate": ["css", "less", "scss", "sass", "html"]
}

其实主要就是自动保存格式化,然后回到 eslint 的文件,保存就会自动格式化,如果格式化后依然报错,可以尝试重启 vscode。

编码问题

在 windows 上默认是 CRLF 编码,而 prettier 认为这是一种错误的编码方式,格式化也不行。

image

  • 安装 EditorConfig for VS Code 插件
  • 根目录新建 .editorconfig,写入内容,再次保存,就可以看到编码已经变成 LF
# http://editorconfig.org
root = true[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true[*.md]
trim_trailing_whitespace = false[Makefile]
indent_style = tab

使用 .gitattributes 解决多环境编码不一致问题

editconfig 只是解决本地开发的编码问题,当你提交到 git 后,再拉取一个全新的,如果是 win 系统,依然是 CRLF。

为了解决这个问题,可以在代码提交时做格式上的统一,在根目录新建 .gitattributes,统一编码为 LF,且文件类的不做处理

* text=auto eol=lf*.{ico,png,jpg,jpeg,gif,webp,svg,woff,woff2} binary

Stylelint 集成

由于使用 less 开发,所以就额外安装了 less 的解析和校验插件

pnpm i stylelint stylelint-config-recommended stylelint-config-standard-less stylelint-prettier stylelint-order stylelint-config-recess-order postcss-less -D

这几个我就不过多介绍了,其中 stylelint-orderstylelint-config-recess-order 就是 css 排序插件和排序规则,两个结合使用(可选安装)。

根目录新建文件 .stylelintrc.cjs

/** @type {import("stylelint").Config} */
module.exports = {plugins: ['stylelint-order'],customSyntax: 'postcss-less',extends: ['stylelint-config-recommended','stylelint-prettier/recommended','stylelint-config-recess-order','stylelint-config-standard-less',],rules: {// 规则自定义即可'color-function-notation': null,'less/no-duplicate-variables': null,},ignoreFiles: ['**/.js', '/*.jsx', '/.tsx', '**/.ts', '**/dist/**', '**/es/**', '**/lib/**', '**/node_modules/**'],
};

完毕之后可以随便建一个测试的 less 文件,写一些内容来测试插件是否生效

image

由此可见,排序插件是生效了,此时保存代码就可以自动修复排序规则,那这个 stylelint 的配置应该也没什么问题。

如果没有生效,尝试重启 vscode,且每次更改 stylelint 的配置后,都建议重启验证

scripts 添加 fix 命令(可忽略)

package.json 添加 script 命令

  "scripts": {"preinstall": "npx only-allow pnpm","lint:eslint": "eslint . --fix --cache","lint:stylelint": "stylelint \"**/*.{less,css}\" --fix --cache"},

monorepo 基本结构搭建

这里不介绍 monorepo 单体仓库的作用,能看到该文章的应该都对其有一定的了解。

该项目的多包仓库思路是:

  • packages 文件夹作为组件开发的核心模块
    • 多个子包都需要 tsconfig 的配置,那就可以把这个配置抽离出来
    • icon 组件库作为一个单独的包
    • 其它广泛使用的组件为组件库核心包(常用 util hook 什么的也可以抽离,这里不再做更细致划分)
  • storybook 文档作为单独的模块
  • site 组件库网站作为单独模块(可选)

此时结构目录应该是

- packages- components- icons- tsconfig
- site
- storybook

目录新建完毕后,根目录新建 pnpm-workspace.yaml

packages:- packages/*- site- storybook

此时 monorepo 的基本目录结构就已经搭建好了

初始化 packages 目录的子包

其中 sitestorybook 先设为 TODO(待办),优先整理 packages 下的子包

packages 下的包统一初始化执行 pnpm init 命令

tsconfig

进入 tsconfig 目录,将 package.json 中的 name 修改为你喜欢的包名,后续都是以 name 字段的名字安装依赖,由于项目内使用,设置成 private 即可,我设置的 rclt 就是 react-component-library-templete 的简写。

{"name": "rclt-tsconfig","version": "0.0.1","description": "","keywords": [],"author": "",
}

json 内容仅供参考

新建 base.json 文件

{"$schema": "https://json.schemastore.org/tsconfig","compilerOptions": {"strict": true,"composite": false,"declaration": true,"esModuleInterop": true,"forceConsistentCasingInFileNames": true,"allowSyntheticDefaultImports": true,"allowImportingTsExtensions": true,"allowJs": true,"inlineSources": false,"isolatedModules": true,"module": "ES2020","moduleResolution": "Bundler","noUnusedLocals": true,"noUnusedParameters": true,"preserveWatchOutput": true,"skipLibCheck": true,"strictNullChecks": true},"exclude": ["dist", "build", "es", "lib", "node_modules"]
}

新建 react-library.json 文件

{"$schema": "https://json.schemastore.org/tsconfig","extends": "./base.json","compilerOptions": {"module": "ES6","target": "ES5","jsx": "react","lib": ["DOM", "ES2015"]}
}

此时就可以在根目录添加 rclt-tsconfig 依赖

  "devDependencies": {"rclt-tsconfig": "workspace:*",}

执行 pnpm i 安装,新建一个 tsconfig.json 来使用这个包

{"extends": "rclt-tsconfig/base.json","compilerOptions": {"noEmit": true},"include": ["packages/**/*.tsx", "packages/**/*.ts"]
}

不要问我为什么不使用命令安装,问就是没找到根目录安装子包的命令(不会)

components

rclt-tsconfig 链接到 components 包下,以下命令的意思就是从本地找 rclt-tsconfig 安装到 rclt-components

  • rclt-components 是 components 包 package.json 中的 name
  • -workspace 是从本地查找
  • 暴力一点的话直接在 package.json 中写入包依赖,比如 "rclt-tsconfig": "workspace:*",再执行 pnpm install 即可。
pnpm --filter rclt-components add rclt-tsconfig -D -workspace

新建 tsconfig.json

{"extends": "rclt-tsconfig/react-library.json","compilerOptions": { "emitDeclarationOnly": true }, // 只生成声明文件"include": ["src"]
}

没问题的话,点 extends 的路径链接是可以跳到 json 文件的

提交规范

这些依赖的集成都是在根目录进行的,记得安装的时候带上 -w 来指定在根工作区安装。

husky + lint-staged 集成

安装依赖之前的准备工作

在此之前,先把我们的项目 git 初始化一下,执行 git init 命令,最好再建一个 git 仓库,关联本地代码,这部分我就不赘述了,大家应该都会。

根目录新建 .gitignore,以下是我的文件内容,大家可自行修改忽略文件(我个人习惯不上传 lock 依赖,除非特殊情况需要锁定版本)

# Dependencies
node_modules
.pnp
.pnp.js# Local env files
.env
.env.local
.env.development.local
.env.test.local
.env.production.local# Testing
coverage# Turbo
.turbo# Vercel
.vercel# Build Outputs
.next/
out/
build
dist
es
lib# Debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*# Misc
.DS_Store
*.pem# cache
.eslintcache
.stylelintcache# lock
pnpm-lock.yaml

集成依赖

安装并初始化 husky

pnpm i husky lint-staged -D -w
# 初始化 husky
npx husky init

执行完毕 script 中会添加一个 husky 命令,根目录会生成 .husky 文件,其中有一个 pre-commit 脚本文件,写入以下内容

npx lint-staged

这件事就是在代码 commit 之前,执行 lint-staged 做一些事情,比如检测代码规范,格式化代码等,接下来就干这个事。

根目录新建 .lintstagedrc

{"packages/**/*.{js,jsx,ts,tsx}": ["eslint --fix --cache", "prettier --write"],"packages/**/package.json": ["prettier --write"],"packages/**/*.{css,less}": ["stylelint --fix --cache", "prettier --write"],"**/*.md": ["prettier --write"]
}

内容应该都能看得懂,就是匹配到的文件执行相应的命令

commitlint 集成

pnpm i @commitlint/cli @commitlint/config-conventional -D -w

根目录新建 commitlint.config.js

module.exports = {ignores: [(commit) => commit.includes('init')],extends: ['@commitlint/config-conventional'],
};

.husky 文件夹下新建 commit-msg

npx --no-install commitlint --edit $1

测试集成是否正常工作

我们把 lint-staged 和 commitlint 准备工作都完成了,如何测试呢?

首先测试 lint-staged,即写一段被 eslint 警告的代码进行提交:

// pakcgaes/components/src/index.tsconst a = 1; // 'a' is assigned a value but never used.

然后执行 commit(初次执行代码校验时间可能较长)

image

lint 校验没通过,无法 commit,此时再把 const a = 1; 删除掉,消除 eslint 的报错,再次执行 commit

image

这次可以看到代码的校验已经通过,但是 commitlint 抛出了错误,提示 commit 信息不规范,此时修改一下再提交

image

此时提交就可以正常通过了,接下来推送到远程仓库即可。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分区Partition

理解Partition 向量检索服务DashVector的Collection具有分区(Partition)的能力,同一个Collection下的Doc可通过不同的Partition进行物理和逻辑上的分区。各种Doc操作(如插入Doc、检索Doc等。若指定Partition,则该操作将限定在该指定的Paritition内进行。通过合理的Partiti…

PGsql 大写字段名,flink目前不支持读取

flink1.20 连接 postgres_flink postgresql-CSDN博客[FLINK-23324] Postgres of JDBC Connector enable case-sensitive. - ASF JIRA

成本减半 + 效率翻倍:这家企业用 11 天实现数据处理飞跃

伴随着云计算和数字化浪潮的推进,越来越多行业数据实时性的权重正在被加速提升,对企业而言,如果想要保证业务的持续发展,其底层数据库必须要能满足数据的实时性和高并发要求。 除此之外,在降本增效的大潮下,“高性价比”也成为企业选择一款数仓的重要因素。 那么,企业应…

Windows激活神器HEU KMS Activator v42.3.1

软件介绍 HEU KMS Activator,简洁高效的全能KMS/OEM激活工具,适用所有Windows, Office版本,无需联网即可一键激活,支持UEFI的KMS激活工具。KMS服务是微软对Windows, Office等产品的批量许可服务,利用KMS可以激活局域网内的产品。该工具利用KMS机制在系统搭建KMS服务器,从…

如何远程实时监控员工的电脑屏幕?60教会你,五个妙招轻松搞定!

https://mbd.baidu.com/newspage/data/landingsuper?context=%7B%22nid%22%3A%22news_9073269535369745774%22%7D&n_type=1&p_from=4 使用远程桌面协议(RDP)远程桌面协议(RDP)是一种允许用户远程连接到另一台计算机的技术。通过配置RDP,管理员可以实时访问员工的…

终端ssh终端模拟软件:Termius激活安装包

Termius是一款功能强大的跨平台终端管理工具,提供了友好的用户界面,支持SSH、Telnet、SFTP等多种连接协议,方便用户远程连接和管理服务器。此外,Termius还支持多平台同步、文件传输、批量操作、脚本自动化等进阶功能,且具备强大的数据加密和安全性保障。无论是开发人员、系…

解读Karmada多云容器编排技术,加速分布式云原生应用升级

Karmada提供了一个全局的控制面板,使得用户能够像操作单一集群一样管理多云上的Kubernetes集群。本文分享自来源:《华为云DTSE》第五期开源专刊,作者:任洪彩 华为云高级软件工程师,Karmada社区Maintainer。管理和协调跨多个云平台的容器化应用是当前企业面临的复杂性挑战之…

京东零售广告创意:基于人类反馈的可信赖图像生成

作者:京东零售 冯伟ECCV2024: Towards Reliable Advertising Image Generation Using Human Feedback 链接:https://arxiv.org/abs/2408.00418 摘要:在电商领域,吸引顾客注意力的广告图片至关重要。尽管生成模型可以自动生成图像,但它们往往会产生不符合广告标准的图片,可…

如何分发APP供用户使用?

​在移动互联网时代,APP(应用程序)已成为人们日常生活中不可或缺的一部分。无论是购物、社交、娱乐还是工作,APP都提供了极大的便利。然而,开发一款APP只是第一步,如何将其有效地分发到用户手中,让用户能够轻松下载并使用,才是决定APP成功与否的关键。 一、应用商店分发…

当然不是草台班子-冲刺计划

作业所属课程 软件工程2024作业要求 2024秋软工实践团队作业-第三次( Alpha冲刺)作业目标 做出alpha冲刺的计划团队名称 当然不是草台班子团队成员学号 姓名102201427 侯丽珂102201426 郑嘉祺102201241 戴康怡102201218 肖晗涵112200328 谢李东292300304 陈鹭102201242 魏儀阳…

设备管理系统功能拆解——设备档案管理

设备档案管理是设备管理系统中的一个核心组成部分,简单来说,它就是对设备的所有信息进行系统化的记录与管理,包括设备的基本数据、使用情况以及维护历史等。 如果一个工厂里数十台设备同时运转,没有准确的设备档案—— 设备出现故障时,管理者如何能迅速找到相关信息? 当需…

jenkins环境搭建

linux安装maven及环境配置 一、maven下载地址,安装binaries版本 https://dlcdn.apache.org/maven/maven-3/3.8.8/ 或者使用wget命令命令:wget https://https://dlcdn.apache.org/maven/maven-3/3.8.8/binaries/apache-maven-3.8.8-src.tar.gz二、解压命令:tar -zxvf apache-…