项目搭建
为什么使用craco
使用create-react-app 创建的项目默认是无法修改其内部的webpack 配置的,不像vue-cli 那样可以通过一个配置文件修改。 虽然有一个eject 命令可以是将配置完全暴露出来,但这是一个不可逆的操作,同时也会失去CRA 带来的便利和后续升级。 如果想要无 eject 重写 CRA 配置,目前成熟的是下面这几种方式
- 通过 CRA 官方支持的
--scripts-version 参数,创建项目时使用自己重写过的 react-scripts 包 - 使用
react-app-rewired + customize-cra 组合覆盖配置 - 使用
craco 覆盖配置
这里我们选择的是使用craco 覆盖配置
搭建步骤
- 使用
create-react-app 创建一个项目,这里我们命名为 react-app
npx create-react-app react-app --template typescript
npm install --save @craco/craco
- 在项目根目录下创建配置文件
craco.config.js ,并根据实际情况完善配置
const path = require('path');
const { name } = require('./package.json');
const pathResolve = pathUrl => path.join(__dirname, pathUrl);
module.exports = {
reactScriptsVersion: 'react-scripts' ,
webpack: {
alias: {
'@': pathResolve('src'),
'@assets': pathResolve('src/assets'),
'@components': pathResolve('src/components'),
'@constants': pathResolve('src/constants'),
'@containers': pathResolve('src/containers'),
'@hooks': pathResolve('src/hooks'),
'@mocks': pathResolve('src/mocks'),
'@routes': pathResolve('src/routes'),
'@services': pathResolve('src/services'),
'@styles': pathResolve('src/styles'),
'@types': pathResolve('src/types'),
'@utils': pathResolve('src/utils'),
'@contexts': pathResolve('src/contexts'),
},
configure(webpackConfig) {
webpackConfig.resolve.extensions = [...webpackConfig.resolve.extensions, ...['.scss', '.css']];
webpackConfig.output.library = `${name}-[name]`;
webpackConfig.output.libraryTarget = 'umd';
webpackConfig.output.globalObject = 'window';
return webpackConfig;
},
},
devServer: {
port: 3001,
headers: {
'Access-Control-Allow-Origin': '*',
},
},
};
详细配置请参考官网文档
- 修改
package.json 中的 scripts
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
},
集成Eslint
什么是Eslint
ESLint 是一个在 JavaScript 代码中通过规则模式匹配作代码识别和报告的插件化的检测工具,它的目的是保证代码规范的一致性和及时发现代码问题、提前避免错误发生。 ESLint 的关注点是代码质量,检查代码风格并且会提示不符合风格规范的代码。除此之外 ESLint 也具有一部分代码格式化的功能。
Eslint的作用及优势
比如:api语法错误、使用了未定义的变量、修改const变量
比如:使用tab还是空格,使用单引号还是双引号等
比如:可以借助eslint-config-standard配置包扩展社区中流行的最佳实践的风格指南。
这样就能极大提高项目中多人协作开发时的效率、代码的可读性以及可维护性。
支持的配置文件格式
ESLint 支持几种格式的配置文件:
- JavaScript – 使用
.eslintrc.js 然后输出一个配置对象。 - YAML – 使用
.eslintrc.yaml 或 .eslintrc.yml 去定义配置的结构。 - JSON – 使用
.eslintrc.json 去定义配置的结构,ESLint 的 JSON 文件允许 JavaScript 风格的注释。 - (弃用) – 使用
.eslintrc ,可以使 JSON 也可以是 YAML。 - package.json – 在 package.json 里创建一个
eslintConfig 属性,在那里定义你的配置。
如果同一个目录下有多个配置文件,ESLint 只会使用一个。优先级顺序如下: .eslintrc.js > .eslintrc.yaml > .eslintrc.yml > .eslintrc.json > .eslintrc > package.json
遇到项目内有多个层叠配置时,依然采用就近原则作为高优先级;
配置文件说明
Rules-启用的规则及其各自的错误级别
ESLint 附带有大量的规则。你可以使用注释或配置文件修改你项目中要使用的规则。要改变一个规则设置,你必须将规则 ID 设置为下列值之一:
"off" 或 0 - 关闭规则"warn" 或 1 - 开启规则,使用警告级别的错误:warn (不会导致程序退出)"error" 或 2 - 开启规则,使用错误级别的错误:error (当被触发的时候,程序会退出)
例如:
rules: {
'eqeqeq': 2,
'no-alert': 2,
'no-undef': 2,
'no-use-before-define': 2,
'react-hooks/exhaustive-deps': 2,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-var-requires': 0,
},
Globals-配置额外的全局变量
启用ESLint 规则后,当访问当前源文件内未定义的变量时,no-undef 规则将发出警告。 而有时候,我们是需要在其他文件访问一些全局变量的,且保证能正常取到值。这时可以在 ESLint 中定义这些全局变量,这样 ESLint 就不会发出警告了。
这定义了两个全局变量,var1 和 var2 。如果你想选择性地指定这些全局变量可以被写入(而不是只被读取),那么你可以用一个 "writable" 的标志来设置它们:
- 配置文件中通过
globals 配置属性设置,对于每个全局变量键,将对应的值设置为 "writable" 以允许重写变量,或 "readonly" 不允许重写变量。例如:
"globals": {
"var1": "writable",
"var2": "readonly"
}
Environments - 指定脚本的运行环境
每种环境都有一组特定的预定义全局变量。如brower、node环境变量、es2021环境变量等。
env: {
browser: true,
es2021: true,
node: true,
},
Plugins - 第三方插件
ESLint 支持使用第三方插件,先在项目中下载安装要引入的插件,配置文件中使用 plugins 关键字来存放插件名字的列表。插件名称可以省略 eslint-plugin- 前缀。
plugins: ['react', 'babel'],
Extends - 继承
一个配置文件可以被基础配置中的已启用的规则继承。
extends: ["eslint:recommended","plugin:prettier/recommended"],
使用Eslint
安装Eslint
ESLint 可以安装在当前项目中或全局环境下,但因项目间存在的差异性,我们一般会将它安装在当前项目中。
npm install eslint --save-dev
安装插件和解析器
假如项目中使用了TypeScript和React,则安装
npm install --save-dev eslint-plugin-react @typescript-eslint/parser @typescript-eslint/eslint-plugin
其他的插件和解析器请根据实际项目需要安装。
创建配置文件
创建配置文件有以下两种方式
- 在根目录新建
.eslintrc.js 文件,并自己完善该配置文件 - 在终端中输入如下命令
npx eslint--init 并根据提示自动创建配置文件
文件配置大致如下:
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
root: true,
extends: ['eslint:recommended', 'react-app', 'plugin:prettier/recommended', 'plugin:@typescript-eslint/recommended'],
overrides: [],
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
ecmaFeatures: {
jsx: true,
},
},
plugins: ['react', '@typescript-eslint'],
rules: {
eqeqeq: 2,
'no-alert': 2,
'no-undef': 2,
'no-use-before-define': 2,
'react-hooks/exhaustive-deps': 2,
'@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-non-null-assertion': 0,
'@typescript-eslint/no-var-requires': 0,
},
};
具体配置可根据项目实际需要进行配置
添加命令进行eslint检测
在package.json 中添加如下命令:
"scripts": {
"start": "craco start",
"build": "craco build",
"test": "craco test",
"lint": "eslint -c .eslintrc.js src --ext .ts,.tsx,.js,.jsx --fix"
},
之后就可以运行npm run lint 这个命令进行eslint校验;
比如,我们在项目内任意一个ts文件内输入如下代码:
console.log('jump', age);
然后运行npm run lint 就会发现终端报如下错误: 这就说明,我们的Eslint 配置成功了
集成Prettier
什么是Prettier
Prettier是一个诞生于2016年就迅速流行起来的专注于代码格式化的工具。出道即巅峰啊-.- Prettier只关注格式化,并不具有lint检查语法等能力。它通过解析代码并匹配自己的一套规则,来强制执行一致的代码展示格式。 它在美化代码方面有很大的优势,配合ESLint可以对ESLint格式化基础上做一个很好的补充。
使用Prettier
安装Prettier
npm install prettier --save-dev
配置Prettier规则
在项目根目录新建.prettierrc.js ,并完善配置 大致配置如下:
module.exports = {
printWidth: 120,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
quoteProps: 'as-needed',
jsxSingleQuote: false,
trailingComma: 'es5',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'avoid',
rangeStart: 0,
rangeEnd: Infinity,
vueIndentScriptAndStyle: false,
endOfLine: 'auto',
embeddedLanguageFormatting: 'off',
};
如何解决Prettier与ESLint的配置冲突问题?
在代码格式化时采用Perttier规则,而我们代码校验使用的是ESLint,如果同一个规则配置不一致,往往就会出现冲突问题;
比如:字符串单、双引号的配置,eslint fix后把字符串变成单引号,再次编辑文件后,保存(Prettier)自动格式化后却又变成双引号,导致代码校验异常。
通常有以下两种解决方法:
- 要么修改 eslintrc,要么修改 prettierrc 配置,让它们配置保持一致
- 禁用 ESLint中和Prettier配置有冲突的规则;再使用 Prettier 来替代 ESLint 的格式化功能
安装eslint-config-prettier 插件配置集,把其配置到eslintrc 规则的尾部。执行eslint 命令,会禁用那些和Prettier 配置有冲突的规则。 安装eslint-plugin-prettier 插件,先使用Prettier 对代码进行格式化,再并对不一致的地方进行标记;
这两个包配合使用,可以达到运行 eslint --fix 时,采用Prettier 的配置规则 来格式化文件。
集成husky
什么是husky
husky 是一个为 git 客户端增加 hook 的工具。安装后,它会自动在仓库中的 .git/ 目录下增加相应的钩子;比如 pre-commit 钩子就会在你执行 git commit 的触发。
husky的作用
我们可以在 pre-commit 中实现一些比如 lint 检查、单元测试、代码美化等操作。当然,pre-commit 阶段执行的命令当然要保证其速度不要太慢,每次 commit 都等很久也不是什么好的体验。
也可以在commit-msg 钩子中结合commitlint 实现提交信息的检查
了解githooks
Git Hooks 就是在 Git 执行特定事件(如commit 、push 、receive 等)时触发运行的脚本,类似于“钩子函数”,没有设置可执行的钩子将被忽略。 git hook 的作用是在 git 动作发生前后触发自定义脚本。这些动作包括提交,合并,推送等,我们可以利用这些钩子在 git 流程的各个环节实现自己的业务逻辑。
git hook 分为客户端 hook 和服务端 hook。
客户端 hook 主要有四个:
pre-commit :提交信息前运行,可检查暂存区的代码prepare-commit-msg :不常用commit-msg :非常重要,检查提交信息就用这个钩子post-commit :提交完成后运行
服务端 hook 包括:
pre-receive :非常重要,推送前的各种检查都在这post-receive :不常用update :不常用
自动配置husky
初始化husky
npx husky-init install
yarn dlx husky-init
pnpm dlx husky-init
husky-init 命令主要做了以下的事情
- 在项目目录下创建.husky文件夹,并且默认创建了一个
pre-commit 的钩子,钩子中内容为
. "$(dirname -- "$0")/_/husky.sh"
npm run test
- 在package.json中添加脚本:
"prepare":"husky install" 。npm install 时默认会执行这个脚本
配置pre-commit 钩子
修改pre-commit 钩子内容为:
. "$(dirname -- "$0")/_/husky.sh"
echo "pre-commit";
npm run lint;
这样我们每次执行git commit 命令的时候都会触发pre-commit 钩子,从而在控制台先打印pre-commit ,然后在执行一遍eslint 校验,如果eslint 校验失败就会中止git commit ;
集成lint-staged
什么是lint-staged
之前我们的配置是每次git commit 的时候都执行一次npm run lint ,这个命令会把src 文件夹下的所有符合文件格式的文件都走一遍eslint 校验,这显然是不太合理的;尤其是项目越来越大的时候这更是一个很耗时的操作。所以,我们需要过滤出git暂存区 里的文件,仅对暂存区的文件做eslint 校验即可。 lint-staged 就是这样一个工具,它可以帮我们过滤出 Git 代码暂存区文件(被 git add 的文件)。这个很实用,因为我们如果对整个项目的代码做一个检查,可能耗时很长,如果是老项目,要对之前的代码做一个代码规范检查并修改的话,这可能就麻烦了呀,可能导致项目改动很大。 lint-staged 总是将所有暂存文件的列表传递给任务。
使用lint-staged
npm install lint-staged --save-dev
- 配置
lint-staged 在package.json 中新增如下命令:
"lint-staged": {
"src/**/*.{ts,tsx,js,jsx}": [
"eslint -c .eslintrc.js --fix"
]
}
这条命令的意思是,对于暂存区中src 文件夹下后缀名为ts,tsx,js,jsx 的文件执行eslint 校验并自动修复可修复的eslint 报错。当然,也可以根据项目需要加入其他任务,比如:
"lint-staged": {
"src/**/*.{js,vue}": [
"prettier --write",
"eslint --cache --fix",
"git add"
]
}
这里 lint-staged 的配置是:在 git 的待提交的文件中,在 src 目录下的所有 .js .vue 都要执行三条命令。使用prettier 格式化文件样式;校验eslint 并自动修复;将处理过的代码重新 add 到 暂存区 中。
- 修改
pre-commit 钩子 将pre-commit 钩子的内容修改为如下:
. "$(dirname -- "$0")/_/husky.sh"
echo "pre-commit";
npx lint-staged;
这样每次提交的时候就只会对暂存区中的文件进行eslint 校验了。
以上就是react 项目使用craco 进行配置并集成Prettier 、Eslint 、husky 、lint-staged 的详细内容,详细代码可查看我的代码仓库。
|