You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:50:25