Skip to content

bug: Import ordering configuration doesn't follow outermost-inward pattern #403

@georgewrmarshall

Description

@georgewrmarshall

Description

The current base import-x/order configuration in @metamask/eslint-config isn't correctly implementing the intended "outermost inward" pattern for imports. Instead, it's grouping 'parent', 'sibling', and 'index' imports together and sorting them alphabetically, which results in unexpected ordering where local imports can appear before parent/sibling imports.

Screencast shows the current order using yarn lint:fix vs the proposed ordering

eslint.bug720.mov

Current Behavior

With the current configuration from @metamask/eslint-config:

'import-x/order': [
  'error',
  {
    'newlines-between': 'always',
    groups: [
      ['builtin', 'external'],
      ['internal', 'parent', 'sibling', 'index'],
    ],
    alphabetize: {
      order: 'asc',
      caseInsensitive: true,
    },
  },
],

This produces imports like:

import type { Meta, StoryObj } from '@storybook/react';
import React from 'react';

import { AvatarBase } from './AvatarBase';  // Local import appears first
import { SAMPLE_AVATARBASE_URIS } from './AvatarBase.dev';
import README from './README.mdx';
import { AvatarBaseSize, AvatarBaseShape } from '../../types';  // Parent import appears later
import { Icon, IconName, IconSize } from '../Icon';  // Sibling import appears later
import { TextColor } from '../Text';

Expected Behavior

Imports should follow an "outermost inward" pattern (from most distant to closest paths):

import type { Meta, StoryObj } from '@storybook/react';
import React from 'react';

import { AvatarBaseSize, AvatarBaseShape } from '../../types';  // Parent imports first
import { Icon, IconName, IconSize } from '../Icon';  // Then sibling imports
import { TextColor } from '../Text';

import { AvatarBase } from './AvatarBase';  // Then local imports
import { SAMPLE_AVATARBASE_URIS } from './AvatarBase.dev';
import README from './README.mdx';

Proposed Solution

Update the import-x/order configuration to explicitly separate parent, sibling, and local imports into distinct groups:

'import-x/order': [
  'error',
  {
    'newlines-between': 'always',
    groups: [
      // External libraries first
      ['builtin', 'external'],
      // Then parent imports (../../)
      ['parent'],
      // Then sibling imports (../)
      ['sibling'],
      // Then local imports (./) including index
      ['index', 'internal'],
    ],
    alphabetize: {
      order: 'asc',
      caseInsensitive: true,
    },
  },
],

Impact

This change would improve code readability by organizing imports in a more logical hierarchical structure, creating a consistent pattern that better reflects the code's dependency structure from external to internal. The current configuration can lead to confusing import ordering where local imports appear before parent imports, which doesn't match the expected mental model of dependency organization.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions