如何通过ESLint限制组件必须从index.ts导入?
如何通过ESLint限制组件必须从子目录index.ts导入?
需求说明
导入src/components目录下的组件时,必须从对应子目录的index.ts导入,直接从组件文件(如src/components/Forms/Button)导入需触发ESLint错误。
示例代码
组件目录的导出文件(src/components/Forms/index.ts)
export { Input } from './Input'; export { CheckBox } from './CheckBox'; export { Button } from './Button';
页面导入示例(pages/home.tsx)
import { Input,CheckBox,Button } from "src/components/Forms" // 合法:从子目录index.ts导入 import { Button } from "src/components/Forms/Button" // 需报错:直接导入组件文件 import { Input } from "src/components/Forms/Input" // 需报错:直接导入组件文件
当前已配置的ESLint内容
module.exports = { parser: '@typescript-eslint/parser', parserOptions: { ecmaVersion: 2020, sourceType: 'module', }, extends: [ 'plugin:@typescript-eslint/recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended', 'plugin:jsx-a11y/recommended', 'prettier', 'plugin:prettier/recommended', ], settings: { react: { version: 'detect', }, }, plugins: ['import', 'no-relative-import-paths'], rules: { 'react/prop-types': 'off', 'react/react-in-jsx-scope': 'off', 'jsx-a11y/anchor-is-valid': 'off', 'jsx-a11y/no-onchange': 'off', 'jsx-a11y/no-static-element-interactions': 'off', 'jsx-a11y/click-events-have-key-events': 'off', '@typescript-eslint/ban-ts-comment': 'warn', '@typescript-eslint/no-unused-vars': 'error', 'no-unused-vars': 'off', 'no-relative-import-paths/no-relative-import-paths': [ 'error', { allowSameFolder: false, rootDir: './src' }, ], 'prettier/prettier': 'warn', '@typescript-eslint/explicit-module-boundary-types': 'off', '@typescript-eslint/explicit-function-return-type': 'off', 'react/display-name': 'off', '@typescript-eslint/no-restricted-imports': [ 'error', { patterns: [ { group: [ 'src/components/common/*/*', '!src/components/common/*/index', ], message: 'import from .../index.js instead', }, ], }, ], }, };
可行的ESLint规则方案
方案1:优化现有@typescript-eslint/no-restricted-imports规则
你已经在使用这个规则,只需调整匹配模式,覆盖所有src/components下的子目录:
修改@typescript-eslint/no-restricted-imports的配置:
'@typescript-eslint/no-restricted-imports': [ 'error', { patterns: [ { group: [ 'src/components/*/*', '!src/components/*/index', ], message: '请从对应子目录的index.ts导入组件', }, ], }, ],
- 规则逻辑:
src/components/*/*匹配所有组件子目录下的二级文件(如Forms/Button),!src/components/*/index排除对index.ts的限制,允许从该文件导入。 - 优势:无需新增插件,基于现有配置修改即可,模式匹配灵活。
方案2:使用eslint-plugin-import的import/no-internal-modules规则
利用eslint-plugin-import插件提供的规则,禁止导入模块的内部文件,仅允许从index.ts导入:
在ESLint规则中添加:
'import/no-internal-modules': [ 'error', { allow: ['src/components/*/index'], message: '请从对应子目录的index.ts导入组件' } ]
- 规则逻辑:限制仅能导入
allow数组中指定的路径,其他src/components下的内部文件均被禁止导入。 - 优势:规则语义更明确,专门针对“禁止内部模块导入”场景。
内容的提问来源于stack exchange,提问作者aahhuhuhu
相关产品推荐
相关产品推荐

