Comments (5)
React 项目代码格式化示例
install
yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-config-airbnb eslint-config-prettier eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks husky lint-staged prettier stylelint stylelint-config-prettier stylelint-config-rational-order stylelint-config-standard stylelint-prettier -D
更新配置文件后需重启编辑器并等待载入配置
package.json
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.10.0",
"@typescript-eslint/parser": "^5.10.0",
"eslint": "^8.7.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.28.0",
"eslint-plugin-react-hooks": "^4.3.0",
"husky": "^7.0.4",
"lint-staged": "^12.2.1",
"prettier": "^2.5.1",
"stylelint": "^14.2.0",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-standard": "^24.0.0",
"stylelint-prettier": "^2.0.0"
}
生成 husky pre-commit hook
npx husky add .husky/pre-commit "npm run lint"
执行该命令后,会看到
.husky/
目录下新增了一个名为pre-commit
的shell脚本。
这样,在之后执行git commit
命令时会先触发pre-commit
这个脚本。
pre-commit
脚本内容如下:
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npm run lint
在 package 根结点添加脚本字段
"scripts": {
"lint": "lint-staged"
},
"lint-staged": {
"src/**/*.{html,css,scss,less}": [
"stylelint 'src/**/*.{html,css,scss,less}' --fix",
"prettier --write"
],
"src/**/*.{ts,tsx}": [
"eslint 'src/**/*.{ts,tsx}' --fix",
"prettier --parser=typescript --write"
],
"src/**/*.{js,jsx}": [
"eslint 'src/**/*.{js,jsx}' --fix",
"prettier --write"
]
},
.editorconfig
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
.eslintignore
node_modules
src/lib/*
typings
.vscode
config
dist
doc
environments
mock
projects/*
test
.less
.css
.md
.ico
.svg
.png
.jpg
.jpeg
.eslintrc.json
{
"env": {
"browser": true,
"es2021": true,
"node": true,
"commonjs": true
},
//"extends": ["plugin:react/recommended", "airbnb"],
"extends": [
"plugin:@typescript-eslint/recommended", //让 ESLint 兼容 TypeScript
"plugin:prettier/recommended", //箭头主体样式和首选箭头回调
"plugin:react/jsx-runtime", //禁用 React 17的新 JSX 转换相关规则
"eslint:recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended", //强制执行Hooks 规则。
//扩展"prettier"关闭了一堆核心 ESLint 规则,以及来自这些插件的一些规则
"prettier" // Prettier 的配置将覆盖 extends 数组中先前任何 代码格式化 相关的 ESLint 配置,二者就能并行不悖地工作了
//"prettier/@typescript-eslint" //禁用相关插件中所有关乎 代码格式化 的规则 "prettier/@typescript-eslint" has been merged into "prettier"
], // 排后的规则会覆盖前面
"parser": "@typescript-eslint/parser", //让 ESLint 兼容 TypeScript
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 13,
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "prettier"],
"rules": {
// "no-use-before-define": "off",
// "@typescript-eslint/no-use-before-define": ["error"],
// "no-param-reassign": "off",
// "react/jsx-filename-extension": [2, { "extensions": [".js", ".jsx", ".ts", ".tsx", ".svg"] }],
"no-unused-vars": "off",
"@typescript-eslint/no-unused-vars": "off",
"prettier/prettier": "error", //任何格式化错误就也被认为是 ESLint 错误了
"no-useless-escape": "off", //禁用不必要的转义
"@typescript-eslint/no-explicit-any": "off", // any 类型
"@typescript-eslint/ban-ts-comment": "off", // "@ts-ignore"
"react/react-in-jsx-scope": "off", // 'React' must be in scope when using JSX
"react-hooks/exhaustive-deps": "off"
},
//rules 数组中自定义的规则会覆盖 prettier/@typescript-eslint 配置
//代码格式化 规则应该在 .prettierrc 中配置
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
},
"react": {
//"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
//"pragma": "React", // Pragma to use, default to "React"
//"fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
"version": "detect" // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
//"flowVersion": "0.53" // Flow version
}
}
}
.gitignore
# dependencies
node_modules/
examples/*/node_modules/
packages/*/node_modules/
packages/*/package-lock.json
package-lock.json
# build and test
build/
packages/*/dist/
packages/*/esm/
coverage/
scratch/
*.pyc
*.tsbuildinfo
scenarios/*/dist/
# logs
yarn-error.log
npm-debug.log
lerna-debug.log
local.log
# ide
.idea
*.sublime-*
# misc
.DS_Store
._*
.Spotlight-V100
.Trashes
.rpt2_cache
docs
lint-results.json
# legacy
tmp.js
# eslint
.eslintcache
eslintcache/*
# Parcel
.cache
# dist
dist/**/*
app/**/*/dist
backend/**/*/dist
doc/**/*/dist
examples/**/*/dist
packages/**/*/dist
# yarn
yarn.lock
.prettierignore
**/*.md
**/*.svg
**/*.ejs
**/*.html
src/lib/*
node_modules
.prettierrc
{
"singleQuote": true,
"tabWidth": 2,
"bracketSpacing": true,
"trailingComma": "none",
"printWidth": 100,
"semi": false,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "typescript" }
}
]
}
.stylelintignore
*.min.css
# 其他类型文件
*.js
*.jpg
*.woff
# 测试和打包目录
/test/
/dist/
.md
.ico
.svg
.png
.jpg
.jpeg
.stylelintrc.json
{
"extends": [
"stylelint-config-standard",
"stylelint-config-rational-order",
"stylelint-prettier/recommended"
],
"rules": {
"at-rule-no-unknown": null,
"rule-empty-line-before": [
"always-multi-line",
{
"except": ["first-nested"],
"ignore": ["after-comment"]
}
],
"at-rule-empty-line-before": [
"always",
{
"except": ["blockless-after-same-name-blockless", "first-nested"],
"ignore": ["after-comment"]
}
],
"comment-empty-line-before": [
"always",
{
"except": ["first-nested"],
"ignore": ["stylelint-commands"]
}
],
"block-no-empty": true,
"declaration-empty-line-before": "never",
"declaration-block-no-duplicate-properties": true,
"declaration-block-no-redundant-longhand-properties": true,
"shorthand-property-no-redundant-values": true,
"function-url-quotes": "always",
"color-hex-length": "short",
"color-named": "never",
"comment-no-empty": true,
"font-family-name-quotes": null,
"font-weight-notation": "numeric",
"property-no-vendor-prefix": true,
"value-no-vendor-prefix": true,
"selector-no-vendor-prefix": true,
"no-descending-specificity": null,
"no-invalid-double-slash-comments": null,
"no-empty-source": null,
"selector-class-pattern": null,
"font-family-no-missing-generic-family-keyword": null
}
}
tsconfig.json
{
"compilerOptions": {
"alwaysStrict": false,
"declaration": true,
"declarationMap": true,
"downlevelIteration": true,
"importHelpers": true,
"inlineSources": true,
"lib": ["es6", "dom"],
// "module": "commonjs", // implied by "target" : "es5"
"moduleResolution": "node",
"noEmitHelpers": true,
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitUseStrict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"plugins": [
{
"name": "typescript-tslint-plugin",
"configFile": "./tslint.json",
"alwaysShowRuleFailuresAsWarnings": false,
"ignoreDefinitionFiles": true,
"mockTypeScriptVersion": false,
"suppressWhileTypeErrorsPresent": false
}
],
"pretty": true,
"sourceMap": true,
"strict": true,
"strictBindCallApply": false,
"target": "es5",
"allowSyntheticDefaultImports": true,
"types": ["node"],
"noErrorTruncation": true, // move me up to @sentry/typescript
}
}
from blog.
Stylelint
Stylelint 支持 scss
安装
postcss-scss
yarn add postcss-scss -D
更新 配置文件 追加
"customSyntax" : "postcss-scss"
.stylelintrc.json
"rules":{}
"customSyntax" : "postcss-scss"
from blog.
monorepo 项目中子包package.json
必须有 lint-staged
配置
"lint-staged": {
"src/**/*.{html,css,scss,less}": [
"stylelint 'src/**/*.{html,css,scss,less}' --fix",
"prettier --write"
],
"src/**/*.{ts,tsx}": [
"eslint 'src/**/*.{ts,tsx}' --fix",
"prettier --parser=typescript --write"
],
"src/**/*.{js,jsx}": [
"eslint 'src/**/*.{js,jsx}' --fix",
"prettier --write"
]
}
from blog.
Vue3 项目代码格式化示例
依赖
pnpm install -D @types/node @typescript-eslint/eslint-plugin @typescript-eslint/parser @vitejs/plugin-vue eslint eslint-config-prettier eslint-plugin-vue husky lint-staged postcss-html prettier stylelint stylelint-config-prettier stylelint-config-rational-order stylelint-config-recommended-vue stylelint-config-standard stylelint-prettier postcss-less
package.json
{
"name": "vue3-vite-lint",
"private": true,
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview",
"lint":"lint-staged",
"-prepare": "husky install"
},
"dependencies": {
"vue": "^3.2.25",
"vue-router": "4"
},
"devDependencies": {
"@types/node": "^18.0.0",
"@typescript-eslint/eslint-plugin": "^5.30.0",
"@typescript-eslint/parser": "^5.30.0",
"@vitejs/plugin-vue": "^2.3.3",
"eslint": "^8.18.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-vue": "^9.1.1",
"husky": "^8.0.1",
"lint-staged": "^13.0.3",
"postcss-html": "^1.4.1",
"postcss-less": "^6.0.0",
"prettier": "2.7.1",
"stylelint": "^14.9.1",
"stylelint-config-prettier": "^9.0.3",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-recommended-vue": "^1.4.0",
"stylelint-config-standard": "^26.0.0",
"stylelint-prettier": "^2.0.0",
"typescript": "^4.5.4",
"vite": "^2.9.9",
"vue-tsc": "^0.34.7"
},
"lint-staged": {
"src/**/*.{html,css,scss,less,vue}": [
"stylelint 'src/**/*.{html,css,scss,less,vue}' --fix",
"prettier --write"
],
"src/**/*.{ts,tsx,vue}": [
"eslint 'src/**/*.{ts,tsx,vue}' --fix",
"prettier --write"
],
"src/**/*.{js,jsx,vue}": [
"eslint 'src/**/*.{js,jsx,vue}' --fix",
"prettier --write"
]
}
}
.stylelintrc.json
{
"extends": [
"stylelint-config-standard",
"stylelint-config-rational-order",
"stylelint-prettier/recommended",
"stylelint-config-recommended-vue"
],
"rules": {
"at-rule-no-unknown": null,
"rule-empty-line-before": [
"always-multi-line",
{
"except": ["first-nested"],
"ignore": ["after-comment"]
}
],
"at-rule-empty-line-before": [
"always",
{
"except": ["blockless-after-same-name-blockless", "first-nested"],
"ignore": ["after-comment"]
}
],
"comment-empty-line-before": [
"always",
{
"except": ["first-nested"],
"ignore": ["stylelint-commands"]
}
],
"block-no-empty": true,
"declaration-empty-line-before": "never",
"declaration-block-no-duplicate-properties": true,
"declaration-block-no-redundant-longhand-properties": true,
"shorthand-property-no-redundant-values": true,
"function-url-quotes": "always",
"color-hex-length": "short",
"color-named": "never",
"comment-no-empty": true,
"font-family-name-quotes": null,
"font-weight-notation": "numeric",
"property-no-vendor-prefix": true,
"value-no-vendor-prefix": true,
"selector-no-vendor-prefix": true,
"no-descending-specificity": null,
"no-invalid-double-slash-comments": null,
"no-empty-source": null,
"selector-class-pattern": null,
"font-family-no-missing-generic-family-keyword": null
}
}
.stylelintignore
*.min.css
# 其他类型文件
*.js
*.jpg
*.woff
# 测试和打包目录
/test/
/dist/
.md
.ico
.svg
.png
.jpg
.jpeg
.prettierrc.json
{
"singleQuote": true,
"tabWidth": 2,
"bracketSpacing": true,
"trailingComma": "none",
"printWidth": 100,
"semi": false,
"overrides": [
{
"files": ".prettierrc",
"options": { "parser": "typescript" }
}
]
}
.prettierignore
**/*.md
**/*.svg
**/*.ejs
**/*.html
src/lib/*
node_modules
.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
// prettier 必须在最后以解决格式化冲突
extends: ['eslint:recommended', 'plugin:vue/vue3-recommended', 'prettier'],
parserOptions: {
ecmaVersion: 13,
parser: '@typescript-eslint/parser',
sourceType: 'module'
},
plugins: ['vue', '@typescript-eslint'],
rules: {
// override/add rules settings here, such as:
// 'vue/no-unused-vars': 'error'
'vue/multi-word-component-names': 'off', //建议开启 App用户组件名称应始终为多字,根组件除外。这可以防止与现有和未来的 HTML 元素发生冲突,因为所有 HTML 元素都是一个单词。
}
}
.eslintignore
node_modules
src/lib/*
typings
.vscode
config
dist
doc
environments
mock
projects/*
test
.less
.css
.md
.ico
.svg
.png
.jpg
.jpeg
src/env.d.ts
**/*.d.ts
.editorconfig
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
.husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install lint-staged
from blog.
error
base.less: When linting something other than CSS, you should install an appropriate syntax, e.g. "postcss-less", and use the "customSyntax" option
安装 postcss-less
from blog.
Related Issues (20)
- React Hooks HOT 4
- Visual Studio Code [VSCode] HOT 1
- React Router v6 HOT 1
- Vite HOT 2
- front business logic 前端业务逻辑 HOT 2
- preconstruct HOT 5
- 运维Ops HOT 2
- Turborepo
- Storybook HOT 3
- esbuild HOT 5
- Commissioning 调试 HOT 1
- express-gateway HOT 1
- Nestjs HOT 1
- 领域驱动设计 Domain-Driven Design DDD HOT 8
- Vue 3 HOT 1
- yarn
- Arduino HOT 17
- C 语言 HOT 3
- IoT 物联网 HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from blog.