Skip to content

docs(linter): Improve the documentation for the import/extensions rule.#17162

Merged
graphite-app[bot] merged 1 commit intomainfrom
improve-ext-docs
Dec 20, 2025
Merged

docs(linter): Improve the documentation for the import/extensions rule.#17162
graphite-app[bot] merged 1 commit intomainfrom
improve-ext-docs

Conversation

@connorshea
Copy link
Member

@connorshea connorshea commented Dec 20, 2025

Include configuration examples for clarity, and ensure the severity level is included in the examples to make it easier to understand for the end-user.

I also used Claude Opus to fix a bug in the sanitize method, where it crashed when you had a json code block on a non-indented doc comment, which was hilarious.

Generated docs:

## Configuration

This rule accepts three types of configuration:

1. **Global rule** (string): `"always"`, `"never"`, or `"ignorePackages"`

\```json
{
  "rules": {
    // this would require extensions for all imports
    "import/extensions": ["error", "always"]
  }
}
\```

2. **Per-extension rules** (object): `{ "js": "always", "jsx": "never", ... }`

\```json
{
  "rules": {
    "import/extensions": [
      "error",
      // per-extension rules:
      // require extensions for .js imports and disallow them for .ts imports
      { "js": "always", "ts": "never" }
    ]
  }
}
\```

3. **Combined** (array): `["error", "always", { "js": "never" }]` or `["error", { "js": "always" }]`

\```json
{
  "rules": {
    "import/extensions": [
      "error",
      "always", // by default, require extensions for all imports
      { "ts": "never" } // override the global value and disallow extensions on imports for specific file types
    ]
  }
}
\```

**Default behavior (no configuration)**: All imports pass.
Unconfigured file extensions are ignored, to avoid false positives.

This rule accepts a configuration object with the following properties:

### checkTypeImports

type: `boolean`

default: `false`

Whether to check type imports when enforcing extension rules.

### extensions

type: `Record<string, string>`

default: `{}`

Map from file extension (without dot) to its configured rule.

### ignorePackages

type: `boolean`

default: `false`

Whether to ignore package imports when enforcing extension rules.

A boolean option (not per-extension) that exempts package imports from the "always" rule.
Can be set in the config object: `["error", "always", { "ignorePackages": true }]`
Legacy shorthand: `["error", "ignorePackages"]` is equivalent to `["error", "always", { "ignorePackages": true }]`

- **With "always"**: When `true`, package imports (e.g., `lodash`, `@babel/core`) don't require extensions
- **With "never"**: This option has no effect; extensions are still forbidden on package imports

Example: `["error", "always", { "ignorePackages": true }]` allows `import foo from "lodash"` but requires `import bar from "./bar.js"`

### pathGroupOverrides

type: `array`

default: `[]`

Path group overrides for bespoke import specifiers.

Array of pattern-action pairs for custom import protocols (monorepo tools, custom resolvers).
Each override has: `{ "pattern": "<glob-pattern>", "action": "enforce" | "ignore" }`

**Pattern matching**: Uses glob patterns (`*`, `**`, `{a,b}`) to match import specifiers.

**Actions**:

- `"enforce"`: Apply normal extension validation (respect global/per-extension rules)
- `"ignore"`: Skip all extension validation for matching imports

**Precedence**: First matching pattern wins.

Example: `["error", "always", { "pathGroupOverrides": [{ "pattern": "rootverse{*,*/**}", "action": "ignore" }] }]`

- Allows `import { x } from 'rootverse+debug:src'` without extension
- Still requires extensions for standard imports

#### pathGroupOverrides[n]

type: `object`

Path group override configuration for bespoke import specifiers.

Allows fine-grained control over extension validation for custom import protocols
(e.g., monorepo tools, custom resolvers, framework-specific imports).

**Pattern matching:**

Uses fast-glob patterns to match import specifiers:

- `*`: Match any characters except `/`
- `**`: Match any characters including `/` (recursive)
- `{a,b}`: Match alternatives

**Examples:**

\```json
{
  "pattern": "rootverse{*,*/**}",
  "action": "enforce"
}
\```

Matches: `rootverse+debug:src`, `rootverse+bfe:src/symbols`

##### pathGroupOverrides[n].action

type: `"enforce" | "ignore"`

Action to take for path group overrides.

Determines how import extensions are validated for matching bespoke import specifiers.

###### `"enforce"`

Enforce extension validation for matching imports (require extensions based on config)

###### `"ignore"`

Ignore matching imports entirely (skip all extension validation)

##### pathGroupOverrides[n].pattern

type: `string`

Glob pattern to match import specifiers

Copilot AI review requested due to automatic review settings December 20, 2025 05:41
@connorshea connorshea requested a review from camc314 as a code owner December 20, 2025 05:41
@github-actions github-actions bot added A-linter Area - Linter C-docs Category - Documentation. Related to user-facing or internal documentation labels Dec 20, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the documentation for the import/extensions linter rule by adding comprehensive configuration examples with proper severity levels and reorganizing the documentation structure.

Key Changes:

  • Added a dedicated "Configuration" section with three detailed JSON examples showing different configuration approaches
  • Updated all configuration examples throughout the documentation to include the severity level (e.g., "error")
  • Moved high-level configuration documentation from the ExtensionsConfig struct to the main rule documentation

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 20, 2025

CodSpeed Performance Report

Merging #17162 will not alter performance

Comparing improve-ext-docs (4e74583) with main (cee4a6c)

Summary

✅ 4 untouched
⏩ 41 skipped1

Footnotes

  1. 41 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@camc314 camc314 self-assigned this Dec 20, 2025
@camc314 camc314 added the 0-merge Merge with Graphite Merge Queue label Dec 20, 2025
Copy link
Contributor

camc314 commented Dec 20, 2025

Merge activity

…e. (#17162)

Include configuration examples for clarity, and ensure the severity level is included in the examples to make it easier to understand for the end-user.

I also used Claude Opus to fix a bug in the `sanitize` method, where it crashed when you had a json code block on a non-indented doc comment, which was hilarious.

Generated docs:

```md
## Configuration

This rule accepts three types of configuration:

1. **Global rule** (string): `"always"`, `"never"`, or `"ignorePackages"`

\```json
{
  "rules": {
    // this would require extensions for all imports
    "import/extensions": ["error", "always"]
  }
}
\```

2. **Per-extension rules** (object): `{ "js": "always", "jsx": "never", ... }`

\```json
{
  "rules": {
    "import/extensions": [
      "error",
      // per-extension rules:
      // require extensions for .js imports and disallow them for .ts imports
      { "js": "always", "ts": "never" }
    ]
  }
}
\```

3. **Combined** (array): `["error", "always", { "js": "never" }]` or `["error", { "js": "always" }]`

\```json
{
  "rules": {
    "import/extensions": [
      "error",
      "always", // by default, require extensions for all imports
      { "ts": "never" } // override the global value and disallow extensions on imports for specific file types
    ]
  }
}
\```

**Default behavior (no configuration)**: All imports pass.
Unconfigured file extensions are ignored, to avoid false positives.

This rule accepts a configuration object with the following properties:

### checkTypeImports

type: `boolean`

default: `false`

Whether to check type imports when enforcing extension rules.

### extensions

type: `Record<string, string>`

default: `{}`

Map from file extension (without dot) to its configured rule.

### ignorePackages

type: `boolean`

default: `false`

Whether to ignore package imports when enforcing extension rules.

A boolean option (not per-extension) that exempts package imports from the "always" rule.
Can be set in the config object: `["error", "always", { "ignorePackages": true }]`
Legacy shorthand: `["error", "ignorePackages"]` is equivalent to `["error", "always", { "ignorePackages": true }]`

- **With "always"**: When `true`, package imports (e.g., `lodash`, `@babel/core`) don't require extensions
- **With "never"**: This option has no effect; extensions are still forbidden on package imports

Example: `["error", "always", { "ignorePackages": true }]` allows `import foo from "lodash"` but requires `import bar from "./bar.js"`

### pathGroupOverrides

type: `array`

default: `[]`

Path group overrides for bespoke import specifiers.

Array of pattern-action pairs for custom import protocols (monorepo tools, custom resolvers).
Each override has: `{ "pattern": "<glob-pattern>", "action": "enforce" | "ignore" }`

**Pattern matching**: Uses glob patterns (`*`, `**`, `{a,b}`) to match import specifiers.

**Actions**:

- `"enforce"`: Apply normal extension validation (respect global/per-extension rules)
- `"ignore"`: Skip all extension validation for matching imports

**Precedence**: First matching pattern wins.

Example: `["error", "always", { "pathGroupOverrides": [{ "pattern": "rootverse{*,*/**}", "action": "ignore" }] }]`

- Allows `import { x } from 'rootverse+debug:src'` without extension
- Still requires extensions for standard imports

#### pathGroupOverrides[n]

type: `object`

Path group override configuration for bespoke import specifiers.

Allows fine-grained control over extension validation for custom import protocols
(e.g., monorepo tools, custom resolvers, framework-specific imports).

**Pattern matching:**

Uses fast-glob patterns to match import specifiers:

- `*`: Match any characters except `/`
- `**`: Match any characters including `/` (recursive)
- `{a,b}`: Match alternatives

**Examples:**

\```json
{
  "pattern": "rootverse{*,*/**}",
  "action": "enforce"
}
\```

Matches: `rootverse+debug:src`, `rootverse+bfe:src/symbols`

##### pathGroupOverrides[n].action

type: `"enforce" | "ignore"`

Action to take for path group overrides.

Determines how import extensions are validated for matching bespoke import specifiers.

###### `"enforce"`

Enforce extension validation for matching imports (require extensions based on config)

###### `"ignore"`

Ignore matching imports entirely (skip all extension validation)

##### pathGroupOverrides[n].pattern

type: `string`

Glob pattern to match import specifiers
```
@graphite-app graphite-app bot merged commit c7cbe69 into main Dec 20, 2025
20 checks passed
@graphite-app graphite-app bot deleted the improve-ext-docs branch December 20, 2025 12:00
@graphite-app graphite-app bot removed the 0-merge Merge with Graphite Merge Queue label Dec 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-linter Area - Linter C-docs Category - Documentation. Related to user-facing or internal documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants