|  | ||
|---|---|---|
| .. | ||
| config | ||
| src | ||
| README.md | ||
| eslint.config.js | ||
| package.json | ||
| tsconfig.build.json | ||
| tsconfig.json | ||
| tsconfig.misc.json | ||
| vitest.config.mts | ||
		
			
				
				README.md
			
		
		
			
			
		
	
	@coze-arch/eslint-plugin
A comprehensive ESLint plugin designed for Flow applications, providing essential linting rules for code quality, import management, and Zustand state management best practices.
Features
Core Rules
- Import Management: Prevent deep relative imports and batch import/export issues
- Code Quality: Enforce function length limits, proper error handling, and catch block usage
- Package Management: Validate package.json structure and dependencies
- React/TSX: Prevent leaked renders and other React-specific issues
Zustand Rules
- State Management: Enforce proper state mutation patterns and store conventions
- Performance: Optimize selector usage and prevent unnecessary re-renders
- Best Practices: Enforce naming conventions and proper store typing
Processors
- JSON Processor: Custom processor for linting package.json files
Get Started
Installation
# Install the package
rush update
# Or using pnpm in workspace
pnpm add @coze-arch/eslint-plugin@workspace:*
Basic Usage
Add the plugin to your ESLint configuration:
// eslint.config.js
import flowPlugin from '@coze-arch/eslint-plugin';
export default [
  {
    plugins: {
      '@coze-arch': flowPlugin,
    },
    rules: {
      '@coze-arch/no-deep-relative-import': ['error', { max: 4 }],
      '@coze-arch/max-line-per-function': ['error', { max: 150 }],
      '@coze-arch/tsx-no-leaked-render': 'warn',
    },
  },
];
Using Recommended Configuration
// eslint.config.js
import flowPlugin from '@coze-arch/eslint-plugin';
export default [
  ...flowPlugin.configs.recommended,
];
Zustand Rules
// eslint.config.js
import zustandPlugin from '@coze-arch/eslint-plugin/zustand';
export default [
  {
    plugins: {
      '@coze-arch/zustand': zustandPlugin,
    },
    ...zustandPlugin.configs.recommended,
  },
];
API Reference
Core Rules
no-deep-relative-import
Prevents excessive relative import nesting.
// ❌ Bad (default max: 3)
import something from '../../../deep/path';
// ✅ Good
import something from '../../shallow/path';
Options:
- max(number): Maximum allowed relative path depth (default: 3)
max-line-per-function
Enforces maximum lines per function.
// ❌ Bad (exceeds limit)
function longFunction() {
  // ... 200 lines of code
}
// ✅ Good
function shortFunction() {
  // ... less than 150 lines
}
Options:
- max(number): Maximum lines per function (default: 150)
tsx-no-leaked-render
Prevents leaked renders in TSX components.
// ❌ Bad
{count && <Component />} // count could be 0
// ✅ Good
{count > 0 && <Component />}
{Boolean(count) && <Component />}
no-pkg-dir-import
Prevents importing from package directories.
// ❌ Bad
import something from 'package/src/internal';
// ✅ Good
import something from 'package';
use-error-in-catch
Enforces proper error handling in catch blocks.
// ❌ Bad
try {
  doSomething();
} catch (e) {
  console.log('error occurred');
}
// ✅ Good
try {
  doSomething();
} catch (error) {
  console.error('error occurred:', error);
}
no-empty-catch
Prevents empty catch blocks.
// ❌ Bad
try {
  doSomething();
} catch (error) {
  // empty
}
// ✅ Good
try {
  doSomething();
} catch (error) {
  console.error(error);
}
no-new-error
Discourages creating new Error instances.
// ❌ Bad
throw new Error('Something went wrong');
// ✅ Good (when configured)
throw createError('Something went wrong');
Zustand Rules
no-state-mutation
Prevents direct state mutation in Zustand stores.
// ❌ Bad
const state = useStore.getState();
state.count = 5;
// ✅ Good
useStore.setState({ count: 5 });
prefer-selector
Encourages using selectors for state access.
// ❌ Bad
const { count, name } = useStore();
// ✅ Good
const count = useStore(state => state.count);
const name = useStore(state => state.name);
store-name-convention
Enforces naming conventions for stores.
// ❌ Bad
const myStore = create(() => ({}));
// ✅ Good
const useMyStore = create(() => ({}));
prefer-shallow
Encourages using shallow equality for object selections.
// ❌ Bad
const { user, settings } = useStore(state => ({
  user: state.user,
  settings: state.settings
}));
// ✅ Good
const { user, settings } = useStore(
  state => ({ user: state.user, settings: state.settings }),
  shallow
);
Package.json Rules
package-require-author
Ensures package.json has an author field.
{
  "name": "my-package",
  "author": "developer@example.com"
}
package-disallow-deps
Prevents usage of disallowed dependencies (configurable).
Development
Setup
# Install dependencies
rush update
# Run tests
rushx test
# Run with coverage
rushx test:cov
# Lint code
rushx lint
# Build (no-op for this package)
rushx build
Project Structure
src/
├── index.ts              # Main plugin entry
├── processors/
│   └── json.ts          # JSON processor for package.json
├── rules/               # Core ESLint rules
│   ├── no-deep-relative-import/
│   ├── max-lines-per-function/
│   ├── tsx-no-leaked-render/
│   └── ...
└── zustand/             # Zustand-specific rules
    ├── index.ts         # Zustand plugin entry
    └── rules/
        ├── no-state-mutation/
        ├── prefer-selector/
        └── ...
Adding New Rules
- Create a new directory under src/rules/orsrc/zustand/rules/
- Implement the rule in index.ts
- Add comprehensive tests in index.test.ts
- Export the rule in the main plugin file
- Add the rule to recommended configuration if appropriate
Testing
Tests are written using ESLint's RuleTester:
import { RuleTester } from 'eslint';
import { myRule } from './index';
const ruleTester = new RuleTester();
ruleTester.run('my-rule', myRule, {
  valid: [
    // Valid code examples
  ],
  invalid: [
    // Invalid code examples with expected errors
  ],
});
Dependencies
Runtime Dependencies
- @typescript-eslint/utils- TypeScript ESLint utilities
- eslint-module-utils- ESLint module resolution utilities
- eslint-rule-composer- Rule composition utilities
- eslint-traverse- AST traversal utilities
- eslint-utils- General ESLint utilities
- semver- Semantic versioning utilities
Development Dependencies
- @typescript-eslint/rule-tester- Rule testing utilities
- vitest- Test runner
- eslint- ESLint core
- TypeScript and various ESLint plugins for development
License
Apache-2.0 License
Author
For more information about ESLint plugin development, see the ESLint Plugin Developer Guide.