feat: import grouping (#493)#784
Open
todor-a wants to merge 33 commits into
Open
Conversation
…headers to file start
… redundant state)
…sit when actually implemented)
b231628 to
a8c550e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #493.
Transparency note: This PR was prepared with AI assistance (Claude).
Adds ESLint-
import/order-style import grouping to dprint-plugin-typescript: classify import declarations, reorder across the import block to match a user-declared group order, and insert exactly one blank line between groups.Configuration
Four new keys under
module.*:{ "module.importGroups": [ { "match": "builtin" }, { "match": "external" }, { "match": "parent" }, { "match": ["sibling", "index"] } ], "module.typeImports": "separate", // or "interleave" "module.builtinsRuntime": "node" // or "deno" | "bun" | "none" }Empty
module.importGroups(default) disables the feature; output is byte-identical to the previous release.matchformsbuiltin | external | parent | sibling | index | type | unknown{ "pattern": "<glob>" }matched against the literal import sourceFirst-match-wins across the list.
Built-in categories per runtime
builtinmatchnode(default)node:*prefix or hardcoded Node 22 LTS core listdenonode:*prefix onlybunnode:*,bun:*, or Node core listnoneWhat works
@app/**, etc.)unknowncatch-all (implicit at end, or explicit anywhere)"separate"(default, own category) or"interleave"import "./polyfill") act as barriers — preserve position; imports either side grouped independently// @ts-check, etc.) pinned to file startmodule.sortImportDeclarationsfor within-group orderimportDeclaration.sortNamedImportsfor specifier sortformat_twice: truein the existing spec harness)Tests
16 new spec files under
tests/specs/declarations/import/ImportGroups_*.txtcovering: basic reorder, sort variants, type-imports both modes, all four runtimes, pattern matchers + first-match-wins, side-effect barriers, header comments, multi-chunk barriers, import attributes (with { type: "json" }),.d.tsfiles + nesteddeclare module, knob interactions, implicit/explicitunknown.Plus unit tests covering classifier, partition, resolved-config compile, and diagnostics.
Full suite: 666 specs pass (660 pre-existing untouched + 16 new files / 14 sub-tests), 61 lib tests pass. Feature-off output byte-identical to baseline.
Known limitations (documented in README)
// dprint-ignoreon an import currently reorders like any other; barrier handling is a follow-up.require(...), dynamicimport(), TSimport = require()not reordered.declare module "..."bodies not classified.ESLint
import/ordermigrationgroupsmodule.importGroups(strings; nested arrays merge)pathGroups{ "pattern": "..." }entries placed positionallynewlines-between: "always"newlines-between: "never"/"ignore"module.importGroupsalphabetize.order: "asc"module.sortImportDeclarationsalphabetize.order: "desc"