Browse Source

更新 package.json、pnpm-lock.yaml 和 pnpm-workspace.yaml,添加 ESLint 相关依赖和脚本,扩展工作区配置以包含 internal 目录,新增多个依赖项以支持项目开发。

xbx 2 days ago
parent
commit
279ca7aa8a

+ 22 - 0
.eslintrc.js

@@ -0,0 +1,22 @@
+module.exports = {
+  root: true,
+  extends: [
+    './internal/eslint/base.js',
+  ],
+  ignorePatterns: [
+    'node_modules',
+    'dist',
+    'build',
+    '.turbo',
+    'coverage',
+  ],
+  overrides: [
+    {
+      // 为 React 应用配置特定规则
+      files: ['apps/**/*.{js,jsx,ts,tsx}', 'packages/**/*.{js,jsx,ts,tsx}'],
+      extends: [
+        './internal/eslint/react.js',
+      ],
+    },
+  ],
+}; 

+ 12 - 0
apps/purchase-admin/package.json

@@ -0,0 +1,12 @@
+{
+  "name": "purchase-admin",
+  "version": "1.0.0",
+  "main": "index.js",
+  "scripts": {
+    "test": "echo \"Error: no test specified\" && exit 1"
+  },
+  "keywords": [],
+  "author": "",
+  "license": "ISC",
+  "description": ""
+}

+ 5 - 0
apps/purchase-admin/rsbuild.config.js

@@ -0,0 +1,5 @@
+// rsbuild.config.js
+const rsbuildConfig = require('../../internal/rsbuild');
+
+// 使用共享的 React 配置
+module.exports = rsbuildConfig.react; 

+ 9 - 0
apps/purchase-admin/src/index.js

@@ -0,0 +1,9 @@
+// 示例 JavaScript 文件
+console.log('Hello, Rsbuild!');
+
+// 一些可能会被 ESLint 检查出问题的代码
+const unused = 'This variable is never used';
+if (true) console.log('Single line if statement');
+
+// 不推荐的写法
+var oldVar = 'Using var instead of const or let'; 

+ 48 - 0
internal/eslint/base.js

@@ -0,0 +1,48 @@
+module.exports = {
+  extends: ['eslint:recommended'],
+  env: {
+    browser: true,
+    node: true,
+    es6: true,
+  },
+  parserOptions: {
+    ecmaVersion: 2022,
+    sourceType: 'module',
+  },
+  rules: {
+    // 错误级别规则
+    'no-console': ['warn', { allow: ['warn', 'error', 'info'] }],
+    'no-debugger': 'warn',
+    'no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
+    
+    // 代码风格规则
+    'arrow-body-style': ['error', 'as-needed'],
+    'prefer-const': 'error',
+    'no-var': 'error',
+    'eqeqeq': ['error', 'always', { null: 'ignore' }],
+    'no-multiple-empty-lines': ['error', { max: 1, maxEOF: 1 }],
+    'no-trailing-spaces': 'error',
+    
+    // 其他规则
+    'no-restricted-syntax': [
+      'error',
+      {
+        selector: 'ForInStatement',
+        message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.',
+      },
+    ],
+  },
+  overrides: [
+    {
+      files: ['*.ts', '*.tsx'],
+      parser: '@typescript-eslint/parser',
+      extends: [
+        'plugin:@typescript-eslint/recommended',
+      ],
+      rules: {
+        '@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
+        'no-unused-vars': 'off',
+      },
+    },
+  ],
+}; 

+ 4 - 0
internal/eslint/index.js

@@ -0,0 +1,4 @@
+module.exports = {
+  base: require('./base'),
+  react: require('./react'),
+}; 

+ 33 - 0
internal/eslint/package.json

@@ -0,0 +1,33 @@
+{
+  "name": "@internal/eslint-config",
+  "version": "1.0.0",
+  "private": true,
+  "main": "index.js",
+  "exports": {
+    ".": "./index.js",
+    "./base": "./base.js",
+    "./react": "./react.js"
+  },
+  "typesVersions": {
+    "*": {
+      "*": ["./*"]
+    }
+  },
+  "files": [
+    "index.js",
+    "base.js",
+    "react.js"
+  ],
+  "dependencies": {
+    "@typescript-eslint/eslint-plugin": "catalog:",
+    "@typescript-eslint/parser": "catalog:",
+    "eslint-config-prettier": "catalog:",
+    "eslint-plugin-import": "catalog:",
+    "eslint-plugin-jsx-a11y": "catalog:",
+    "eslint-plugin-react": "catalog:",
+    "eslint-plugin-react-hooks": "catalog:"
+  },
+  "peerDependencies": {
+    "eslint": "catalog:"
+  }
+} 

+ 32 - 0
internal/eslint/react.js

@@ -0,0 +1,32 @@
+module.exports = {
+  extends: [
+    './base.js',
+    'plugin:react/recommended',
+    'plugin:react-hooks/recommended',
+    'plugin:jsx-a11y/recommended',
+  ],
+  settings: {
+    react: {
+      version: 'detect',
+    },
+  },
+  rules: {
+    // React 相关规则
+    'react/prop-types': 'off',
+    'react/react-in-jsx-scope': 'off',
+    'react/display-name': 'off',
+    'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }],
+    'react/jsx-boolean-value': ['error', 'never'],
+    'react/self-closing-comp': 'error',
+    'react/jsx-no-useless-fragment': 'warn',
+    
+    // React Hooks 规则
+    'react-hooks/rules-of-hooks': 'error',
+    'react-hooks/exhaustive-deps': 'warn',
+    
+    // JSX 无障碍规则
+    'jsx-a11y/anchor-is-valid': 'warn',
+    'jsx-a11y/click-events-have-key-events': 'warn',
+    'jsx-a11y/no-static-element-interactions': 'warn',
+  },
+}; 

+ 23 - 0
internal/rsbuild/base.js

@@ -0,0 +1,23 @@
+/**
+ * 基础 Rsbuild 配置
+ */
+module.exports = {
+  output: {
+    polyfill: 'usage',
+    minify: process.env.NODE_ENV === 'production',
+    sourceMap: {
+      js: process.env.NODE_ENV === 'development' ? 'cheap-module-source-map' : false,
+      css: process.env.NODE_ENV === 'development',
+    },
+  },
+  performance: {
+    chunkSplit: {
+      strategy: 'split-by-experience',
+    },
+  },
+  tools: {
+    bundlerChain: (chain, { CHAIN_ID }) => {
+      // 自定义 webpack 配置
+    },
+  },
+}; 

+ 10 - 0
internal/rsbuild/index.js

@@ -0,0 +1,10 @@
+/**
+ * Rsbuild 配置入口文件
+ */
+module.exports = {
+  base: require('./base'),
+  react: require('./react'),
+  plugins: {
+    eslint: require('./plugins/eslint'),
+  },
+}; 

+ 29 - 0
internal/rsbuild/package.json

@@ -0,0 +1,29 @@
+{
+  "name": "@internal/rsbuild-config",
+  "version": "1.0.0",
+  "private": true,
+  "main": "index.js",
+  "exports": {
+    ".": "./index.js",
+    "./base": "./base.js",
+    "./react": "./react.js",
+    "./plugins/eslint": "./plugins/eslint.js"
+  },
+  "typesVersions": {
+    "*": {
+      "*": ["./*"]
+    }
+  },
+  "files": [
+    "index.js",
+    "base.js",
+    "react.js",
+    "plugins"
+  ],
+  "dependencies": {
+    "@rsbuild/core": "catalog:",
+    "@rsbuild/plugin-eslint": "catalog:",
+    "@rsbuild/plugin-react": "catalog:",
+    "eslint": "catalog:"
+  }
+} 

+ 19 - 0
internal/rsbuild/plugins/eslint.js

@@ -0,0 +1,19 @@
+const { pluginEslint } = require('@rsbuild/plugin-eslint');
+
+/**
+ * 创建 ESLint 插件配置
+ * @param {Object} options - ESLint 插件选项
+ * @returns {Object} - Rsbuild 插件
+ */
+function createEslintPlugin(options = {}) {
+  return pluginEslint({
+    // 默认只在开发环境启用
+    lintDirtyModulesOnly: process.env.NODE_ENV === 'development',
+    // 默认不会因为 ESLint 错误而中断构建
+    failOnError: process.env.CI === 'true',
+    // 合并自定义选项
+    ...options,
+  });
+}
+
+module.exports = createEslintPlugin; 

+ 33 - 0
internal/rsbuild/react.js

@@ -0,0 +1,33 @@
+const { pluginReact } = require('@rsbuild/plugin-react');
+const createEslintPlugin = require('./plugins/eslint');
+const baseConfig = require('./base');
+const { mergeRsbuildConfig } = require('@rsbuild/core');
+
+/**
+ * React 应用的 Rsbuild 配置
+ */
+const reactConfig = {
+  plugins: [
+    pluginReact({
+      // React 插件配置
+      fastRefresh: true,
+    }),
+    createEslintPlugin(),
+  ],
+  source: {
+    // 默认入口配置
+    entry: {
+      index: './src/index',
+    },
+    // 默认支持的文件扩展名
+    extensions: ['.js', '.jsx', '.ts', '.tsx', '.json'],
+  },
+  dev: {
+    // 开发服务器配置
+    port: 3000,
+    open: true,
+  },
+};
+
+// 合并基础配置和 React 配置
+module.exports = mergeRsbuildConfig(baseConfig, reactConfig); 

+ 35 - 6
package.json

@@ -9,12 +9,15 @@
     "postinstall": "pnpm run build",
     "build": "echo \"Building packages...\" && pnpm -r build",
     "clean": "rimraf node_modules **/node_modules",
-    "init": "pnpm clean && pnpm install"
+    "init": "pnpm clean && pnpm install",
+    "lint": "eslint .",
+    "lint:fix": "eslint . --fix"
   },
   "keywords": [],
   "private": true,
   "workspaces": [
-    "packages/*"
+    "packages/*",
+    "internal/*"
   ],
   "author": "",
   "license": "ISC",
@@ -23,17 +26,43 @@
     "node": ">=20.0.0",
     "pnpm": ">=9.0.0"
   },
-  "dependencies": {},
+  "dependencies": {
+    "@ant-design/v5-patch-for-react-19": "catalog:",
+    "@iconify/json": "catalog:",
+    "@iconify/types": "catalog:",
+    "@rsbuild/plugin-sass": "catalog:",
+    "@rsbuild/plugin-svgr": "catalog:",
+    "@types/react": "catalog:",
+    "@types/react-dom": "catalog:",
+    "@types/react-transition-group": "catalog:",
+    "ahooks": "catalog:",
+    "echarts": "catalog:",
+    "keepalive-for-react": "catalog:",
+    "nprogress": "catalog:",
+    "typescript": "catalog:",
+    "zod": "catalog:"
+  },
   "devDependencies": {
+    "@rsbuild/core": "catalog:",
+    "@rsbuild/plugin-react": "catalog:",
+    "@rsbuild/plugin-eslint": "catalog:",
+    "@typescript-eslint/eslint-plugin": "catalog:",
+    "@typescript-eslint/parser": "catalog:",
+    "eslint-config-prettier": "catalog:",
+    "eslint-plugin-import": "catalog:",
+    "eslint-plugin-jsx-a11y": "catalog:",
+    "eslint-plugin-react": "catalog:",
+    "eslint-plugin-react-hooks": "catalog:",
     "antd": "catalog:",
     "axios": "catalog:",
     "dayjs": "catalog:",
+    "eslint": "catalog:",
     "react": "catalog:",
     "react-dom": "catalog:",
-    "rimraf": "catalog:",
-    "turbo": "catalog:",
     "react-router": "catalog:",
-    "react-router-dom": "catalog:"
+    "react-router-dom": "catalog:",
+    "rimraf": "catalog:",
+    "turbo": "catalog:"
   },
   "pnpm": {
     "peerDependencyRules": {

File diff suppressed because it is too large
+ 4716 - 2
pnpm-lock.yaml


+ 26 - 0
pnpm-workspace.yaml

@@ -2,6 +2,7 @@ packages:
   - packages/*
   - app/*
   - .
+  - internal/*
 
 catalog:
   react: ^19.1.0
@@ -13,5 +14,30 @@ catalog:
   antd: ^5.26.3
   turbo: ^2.5.4
   rimraf: ^5.0.5
+  '@rsbuild/core': ^1.4.3
+  '@rsbuild/plugin-react': ^1.3.3
+  '@rsbuild/plugin-eslint': ^0.4.2
+  '@typescript-eslint/eslint-plugin': ^7.0.0
+  '@typescript-eslint/parser': ^7.0.0
+  'eslint': ^8.56.0
+  'eslint-config-prettier': ^9.1.0
+  'eslint-plugin-import': ^2.29.1
+  'eslint-plugin-jsx-a11y': ^6.8.0
+  'eslint-plugin-react': ^7.33.2
+  'eslint-plugin-react-hooks': ^4.6.0
+  '@ant-design/v5-patch-for-react-19': ^1.0.3
+  '@iconify/json': ^2.2.354
+  '@iconify/types': ^2.0.0
+  '@rsbuild/plugin-sass': ^1.3.2
+  '@rsbuild/plugin-svgr': ^1.2.0
+  '@types/react': ^19.1.8
+  '@types/react-dom': ^19.1.6
+  '@types/react-transition-group': ^4.4.12
+  'ahooks': ^3.9.0
+  'echarts': ^5.6.0
+  'keepalive-for-react': ^4.0.2
+  'nprogress': ^0.2.0
+  'typescript': ^5.8.3
+  'zod': ^3.25.71
 
 shared-workspace-lockfile: true