diff --git a/.eslintrc.js b/.eslintrc.js index c961715..b3a07da 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -13,7 +13,8 @@ module.exports = { extends: [ 'eslint:recommended', // 使用eslint中recommened的规则 'plugin:react/recommended', // 推荐的react lint配置 - 'plugin:@typescript-eslint/recommended' // 需额外手动安装 @typescript-eslint/eslint-plugin + 'plugin:@typescript-eslint/recommended', // 可开启针对 ts 语法推荐的规则定义, 需额外手动安装 @typescript-eslint/eslint-plugin + 'plugin:react-hooks/recommended' // react hook当依赖项指定不正确时,会发出警告并建议修复。 ], overrides: [], // ESLint 默认使用Espree作为其解析器,你可以在配置文件中指定一个不同的解析器 @@ -33,17 +34,20 @@ module.exports = { }, // ESLint 支持使用第三方插件。在使用插件之前,你必须使用 npm 安装它。 // 在配置文件里配置插件时,可以使用 plugins 关键字来存放插件名字的列表。插件名称可以省略 eslint-plugin- 前缀。 - plugins: ['react', '@typescript-eslint'], + plugins: ['react', '@typescript-eslint', 'react-hooks'], // ESLint 附带有大量的规则。你可以使用注释或配置文件修改你项目中要使用的规则。要改变一个规则设置,你必须将规则 ID 设置为下列值之一: rules: { 'import/extensions': [ - ERROR, + OFF, 'ignorePackages', { ts: 'never', tsx: 'never', js: 'never' } - ] + ], + '@typescript-eslint/no-var-requires': OFF, // 忽略没有导入声明模块 + 'react-hooks/rules-of-hooks': ERROR, // 检查 Hook 的规则 + 'react-hooks/exhaustive-deps': WARN // 检查 Effect 的依赖 } }; diff --git a/.stylelintrc.js b/.stylelintrc.js index 06c989a..54b0055 100644 --- a/.stylelintrc.js +++ b/.stylelintrc.js @@ -1,10 +1,14 @@ module.exports = { - // stylelint-config-standard: stylelint配置标准, 如需修改请在rules添加配置 - // stylelint-config-rational-order: 将相关属性声明进行排序, 按照(1.Positioning 2.Box Model 3.Typography 4.Visual 5.Animation 6.Misc) - // stylelint-config-prettier: 关闭所有不必要的或者可能与prettier相冲突的规则。(放到后面) - extends: ['stylelint-config-standard', 'stylelint-config-rational-order', 'stylelint-config-prettier'], - // stylelint-declaration-block-no-ignored-properties: 提示样式矛盾情况, 禁止由于同一规则中的另一个属性值而忽略的属性值。 - plugins: ['stylelint-order', 'stylelint-declaration-block-no-ignored-properties', 'stylelint-scss'], + extends: [ + 'stylelint-config-standard', // stylelint配置标准, 如需修改请在rules添加配置 + 'stylelint-config-rational-order', // 将相关属性声明进行排序, 按照(1.Positioning 2.Box Model 3.Typography 4.Visual 5.Animation 6.Misc) + 'stylelint-config-prettier' // 关闭所有不必要的或者可能与prettier相冲突的规则。(放到后面) + ], + + plugins: [ + 'stylelint-order', // 提示样式矛盾情况, 禁止由于同一规则中的另一个属性值而忽略的属性值。 + 'stylelint-declaration-block-no-ignored-properties' // 提示样式矛盾情况, 禁止由于同一规则中的另一个属性值而忽略的属性值。 + ], // rules: 其中添加重写和添加内容。可以通过将规则的值设置为 null 来关闭规则 rules: { 'plugin/declaration-block-no-ignored-properties': true, @@ -16,8 +20,7 @@ module.exports = { 'block-no-empty': null, 'value-keyword-case': null, 'rule-empty-line-before': ['always', {except: ['after-single-line-comment', 'first-nested']}], - 'at-rule-no-unknown': null, - 'scss/at-rule-no-unknown': true + 'at-rule-no-unknown': null }, // 忽略检测文件 ignoreFiles: ['node_modules/**/*', 'build/**/*', 'dist/**/*', 'src/assets/font/*'] diff --git a/README.md b/README.md index ab9b8ce..f907fbe 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,10 @@
- - +
+

+ 简体中文 | English +

## 👨🏻‍💻 项目说明 @@ -18,8 +20,7 @@ - 📦 开箱即用,无需配置 - 📝 全面注释说明,学习低成本 - 🚀 启动编译迅速 -- ⭐️ 1.0 版本(2023/2/21 日)已经全部完成 -- 📬 有问题直接 issues 或者留言 +- 🌱 极易定制, 拓展容易 ## 🚀 技术栈 @@ -46,20 +47,20 @@ ## ⌛️ 安装项目依赖 ``` -if you prefer npm +npm $ npm install -if you prefer yarn +yarn $ yarn ``` ## 🚀 运行项目 ``` -if you prefer npm +npm $ npm run start -if you prefer yarn +yarn $ yarn dev ``` @@ -149,3 +150,12 @@ merge 🔀 合并分支 └── yarn.lock # yarn安装包锁定管理 ``` + +## 🤝 如何贡献 + +- 📬 有问题直接 issues 或者留言 +- 欢迎所有的贡献者,在成为贡献者之前,请先阅读贡献指南。如果您已经了解,快来 Issus 或 Pull requests 成为贡献者吧,让我们和小蝴蝶一起成长,一起变得更好、更棒! + +## 开源协议 + +该项目的代码和文档基于  MIT License  开源协议。 diff --git a/docs/README.en.md b/docs/README.en.md new file mode 100644 index 0000000..3699045 --- /dev/null +++ b/docs/README.en.md @@ -0,0 +1,161 @@ +

react 模板

+
+ +
+ +
+
+

+ 简体中文 | English +

+ +## 👨🏻‍💻 项目说明 + +- react 模板, 一个比 CRA 更丰富的模板 + +- 开发配置文档说明 [React18 + webpack5 + TypeScript4 + react-router-dom](https://juejin.cn/post/7197790401495121977) + +## 📱 特点 + +- 📦 开箱即用,无需配置 +- 📝 全面注释说明,学习低成本 +- 🚀 启动编译迅速 +- 🌱 极易定制, 拓展容易 + +## 🚀 技术栈 + +[![react](https://img.shields.io/badge/react-18.2.0-brightgreen.svg)](https://github.com/facebook/react/) [![TypeScript](https://img.shields.io/badge/TypeScript-4.9.4-brightgreen.svg)](https://github.com/microsoft/TypeScript)[![webpack](https://img.shields.io/badge/webpack-5.75.0-brightgreen.svg)](https://github.com/facebook/react/) [![axios](https://img.shields.io/badge/axios-0.18.0-brightgreen.svg)](https://github.com/axios/axios) [![mobx](https://img.shields.io/badge/mobx-6.8.0-brightgreen.svg)](https://github.com/mobx) [![react-router-dom](https://img.shields.io/badge/react--router--dom-6.8.1-brightgreen.svg)](https://github.com/remix-run/react-router) [![MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)]() + +- React v18 +- react-dom v18 +- React Hook +- TypeScript v4 +- webpack v5 +- axios v1 +- mobx v6 +- mobx-react-lite v3 +- react-router-dom v6 + +## 🎄 陆续新增内容: + +- ① 样式 ✅ 2023/2/6 日提交 [config: 🔧  新增样式文件(css/less/sass/postCss)处理](https://github.com/guokaigdg/react-enterprise-template/commit/11fb415bac609dfa7474a1ee2db93ccb4a350a51) +- ② 代码规范 ✅ 2023/2/7 日提交 [config: 🔧  新增 Prettier/ESlint/StyleLint/EditorConfig 代码规范](https://github.com/guokaigdg/react-enterprise-template/commit/87dd1ca333f81203dd245a6eb40479a0745f096f) +- ③ 路由 ✅ 2023/2/8 日提交 [config: 🔧 新增路由管理 react-router-dom v6](https://github.com/guokaigdg/react-enterprise-template/commit/239446d0709eb52bad2b48af4983eef91c49f60d) +- ④ 网络请求 ✅ 2023/2/21 日提交 [feat: ✨  新增网络请求 Axios v1](https://github.com/guokaigdg/react-enterprise-template/commit/27cd67f641d5ecf53b89770195f75bd32bccce46) +- ⑤ 数据共享 ✅ 2023/2/13 日提交 [feature: ✨  新增状态管理 Mobx v6](https://github.com/guokaigdg/react-enterprise-template/commit/992e1884943d4f8bda836f48c60df473418397d7) + +## ⌛️ 安装项目依赖 + +``` +npm +$ npm install + +yarn +$ yarn +``` + +## 🚀 运行项目 + +``` +npm +$ npm run start + +yarn +$ yarn dev +``` + +## 📦 打包编译 + +``` +npm run build:qa // 测试环境 +npm run build:prod // 线上环境 +``` + +## 💡 分支说明 + +| 分支 | 说明 | +| ---- | -------- | +| main | 主分支 | +| dev | 开发分支 | + +## 代码提交规范 + +``` +git : +git commit -m “feat: 项目初始化” +``` + +### type 参考: + +``` +fix 🐛 Bug修复 +feature ✨ 引入新特性 +docs 📝 文档书写改动 +prune 🔥 移除代码或文件 +ui 💄 更新UI和样式文件 +perf ⚡ 性能相关优化 +rocket 🚀 部署功能 +style 🎨 style修改 +init 🎉 初始化提交 +release 🔖 发布版本 +wip 🚧 正在进行中, 且有可能出现不稳定运行的提交 +config 🔧 修改配置文件 +refactot 🔨 重构(既不增加新功能, 也不修改bug的代码改动) +merge 🔀 合并分支 +``` + +## 📂 目录结构 + +``` + ├── .vscode + │ └──setting.json # 先于vscode全局的settings.json配置 + ├── doc # 开发文档记录 + ├── webpack # 打包编译 + │ └──config # webpack配置 + │ ├── webpack.common.js # 基础配置 + │ ├── webpack.dev.js # 开发环境配置 + │ └──webpack.prod.js # 生产环境配置 + ├── pubilc + │ ├──favicon.ico # HTML图标 + │ └──index.html # HTML入口模板 + ├── src + | ├── api # 接口配置 + | ├── assets # 静态资源 + │ ├── components # 项目通用通用组件 + │ ├── http # 请求统一封装 + │ ├── httpinterface # ts类型定义 + │ ├── constData # 系统内的常量列表 + │ ├── router # 统一路由入口 + │ ├── store # 数据共享 + │ ├── styles # 全局样式 + │ ├── utils # 工具库 + │ ├── view # 页面 + │ ├── App.tsx # 主界面 + │ └──index.tsx # 入口文件 + ├── .babelrc.js # babel配置 + ├── .editorconfig # 跨编辑器维护一致编码风格 + ├── .env.json # 环境变量配置 + ├── .eslintignore # ESLint忽略检测文件 + ├── .eslintrc.js # ESLint配置 + ├── .gitignore # git提交忽略文件 + ├── .npmrc + ├── .prettierignore # prettierc忽略文件 + ├── .prettierrc # prettierc配置 + ├── .stylelintrc.js # 代码风格配置 + ├── LICENSE # 开源协议 + ├── package-lock.json # npm安装包锁定管理 + ├── package.json # 依赖包管理 + ├── README.md # 项目说明 + ├── tsconfig.json # ts配置文件 + └── yarn.lock # yarn安装包锁定管理 + +``` + +## 🤝 如何贡献 + +- 📬 有问题直接 issues 或者留言 +- 欢迎所有的贡献者,在成为贡献者之前,请先阅读贡献指南。如果您已经了解,快来 Issus 或 Pull requests 成为贡献者吧,让我们和小蝴蝶一起成长,一起变得更好、更棒! + +## 开源协议 + +该项目的代码和文档基于  MIT License  开源协议。 diff --git a/package-lock.json b/package-lock.json index 0a5e928..2bdffbe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1529,9 +1529,9 @@ "dev": true }, "@eslint/eslintrc": { - "version": "1.4.1", - "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-1.4.1.tgz", - "integrity": "sha512-XXrH9Uarn0stsyldqDYq8r++mROmWRI1xKMXa640Bb//SY1+ECYX6VzT6Lcx5frD0V30XieqJ0oX9I2Xj5aoMA==", + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-2.0.0.tgz", + "integrity": "sha512-fluIaaV+GyV24CCu/ggiHdV+j4RNh85yQnAYS/G2mZODZgGmmlrgCydjUcV3YvxCm9x8nMAfThsqTni4KiXT4A==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -1556,6 +1556,12 @@ } } }, + "@eslint/js": { + "version": "8.35.0", + "resolved": "https://registry.npmmirror.com/@eslint/js/-/js-8.35.0.tgz", + "integrity": "sha512-JXdzbRiWclLVoD8sNUjR443VVlYqiYmDVT6rGUEIEHU5YJW0gaVZwV2xgM7D4arkvASqD0IlLUVjHiFuxaftRw==", + "dev": true + }, "@gar/promisify": { "version": "1.1.3", "resolved": "https://registry.npmmirror.com/@gar/promisify/-/promisify-1.1.3.tgz", @@ -4806,12 +4812,13 @@ "dev": true }, "eslint": { - "version": "8.33.0", - "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.33.0.tgz", - "integrity": "sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA==", + "version": "8.35.0", + "resolved": "https://registry.npmmirror.com/eslint/-/eslint-8.35.0.tgz", + "integrity": "sha512-BxAf1fVL7w+JLRQhWl2pzGeSiGqbWumV4WNvc9Rhp6tiCtm4oHnyPBSEtMGZwrQgudFQ+otqzWoPB7x+hxoWsw==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.4.1", + "@eslint/eslintrc": "^2.0.0", + "@eslint/js": "8.35.0", "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -4825,7 +4832,7 @@ "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", "espree": "^9.4.0", - "esquery": "^1.4.0", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", @@ -4994,6 +5001,12 @@ } } }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmmirror.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true + }, "eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -5045,9 +5058,9 @@ "dev": true }, "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "version": "1.5.0", + "resolved": "https://registry.npmmirror.com/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", "dev": true, "requires": { "estraverse": "^5.1.0" @@ -12778,19 +12791,6 @@ } } }, - "stylelint-scss": { - "version": "4.3.0", - "resolved": "https://registry.npmmirror.com/stylelint-scss/-/stylelint-scss-4.3.0.tgz", - "integrity": "sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==", - "dev": true, - "requires": { - "lodash": "^4.17.21", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.6", - "postcss-value-parser": "^4.1.0" - } - }, "sugarss": { "version": "2.0.0", "resolved": "https://registry.npmmirror.com/sugarss/-/sugarss-2.0.0.tgz", diff --git a/package.json b/package.json index c486ef3..61e4442 100644 --- a/package.json +++ b/package.json @@ -70,8 +70,9 @@ "detect-port-alt": "^1.1.6", "env-cmd": "^10.1.0", "error-overlay-webpack-plugin": "^1.1.1", - "eslint": "^8.33.0", + "eslint": "^8.35.0", "eslint-plugin-react": "^7.32.2", + "eslint-plugin-react-hooks": "^4.6.0", "fork-ts-checker-webpack-plugin": "^7.3.0", "html-webpack-plugin": "^5.5.0", "husky": "^8.0.3", @@ -94,7 +95,6 @@ "stylelint-config-standard": "^29.0.0", "stylelint-declaration-block-no-ignored-properties": "^2.6.0", "stylelint-order": "^6.0.1", - "stylelint-scss": "^4.3.0", "terser-webpack-plugin": "^5.3.6", "typescript": "^4.9.4", "webpack": "^5.75.0", diff --git a/src/view/Home/HomeTwo/index.tsx b/src/view/Home/HomeTwo/index.tsx index 1e88965..d032862 100644 --- a/src/view/Home/HomeTwo/index.tsx +++ b/src/view/Home/HomeTwo/index.tsx @@ -17,6 +17,7 @@ const HomeTwo = () => { getFetchGetTest({ limit: 500 }); + // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return ( diff --git a/tsconfig.json b/tsconfig.json index b356ac4..4699a2e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -32,7 +32,7 @@ "noUnusedLocals": true, // 有未使用的变量时,抛出错误 "noUnusedParameters": true, // 有未使用的参数时,抛出错误 "noFallthroughCasesInSwitch": true, // 报告 switch 语句的 fallthrough 错误。(即,不允许 switch 的 case 语句贯穿) - + /* 其他选项 */ "experimentalDecorators": true, // 是否启用实验性的ES装饰器 }, diff --git a/webpack/config/webpack.common.js b/webpack/config/webpack.common.js index 143d5ab..62693c1 100644 --- a/webpack/config/webpack.common.js +++ b/webpack/config/webpack.common.js @@ -10,13 +10,14 @@ const {isDevelopment, isProduction} = require('../env'); const {imageInlineSizeLimit, imageBase64Path, shouldBase64FromFileEnd} = require('../conf'); const cssLoaders = (importLoaders) => [ - isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, // style-loader的作用就是将结果以style标签的方式插入DOM树中。 + // 执行顺序从后到前 less-loader -> postcss-loader -> css-loader -> style-loader/MiniCssExtractPlugin.loader + isDevelopment ? 'style-loader' : MiniCssExtractPlugin.loader, // style-loader的作用就是将结果以style标签的方式插入DOM树中。style-loader将css-loader打包好的 CSS 代码以