Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[New] order: collapse excess spacing for aesthetically pleasing imports via consolidateIslands #3129

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

Xunnamius
Copy link
Contributor

Depends on #3128

This PR implements in import/order: a new option enabling the manipulation/consolidation of newlines around imports.

A demo package containing this feature is temporarily available for easy testing:

npm install --save-dev eslint-plugin-import@npm:@-xun/eslint-plugin-import-experimental

Collapse excess spacing for aesthetically pleasing imports

This is implemented via consolidateIslands. The proposed documentation corresponding to this new feature can be previewed here.

Example

Given this code (which could be the output of a previous --fix pass):

var fs = require('fs');
var path = require('path');
var { util1, util2, util3 } = require('util');

var async = require('async');

// Ugly but technically valid

var relParent1 = require('../foo');
var {
  relParent21,
  relParent22,
  relParent23,
  relParent24,
} = require('../');
var relParent3 = require('../bar');

var { sibling1,
  sibling2, sibling3 } = require('./foo');
var sibling2 = require('./bar');
var sibling3 = require('./foobar');

And the following settings, the rule check will pass:

{
  "newlines-between": "always-and-inside-groups"
}

However, when given the following instead, the rule check will fail:

{
  "newlines-between": "always-and-inside-groups",
+ "consolidateIslands": "inside-groups"
}

With --fix yielding:

var fs = require('fs');
var path = require('path');
var { util1, util2, util3 } = require('util');

var async = require('async');

// Pretty

var relParent1 = require('../foo');

var {
  relParent21,
  relParent22,
  relParent23,
  relParent24,
} = require('../');

var relParent3 = require('../bar');

var { sibling1,
  sibling2, sibling3 } = require('./foo');

var sibling2 = require('./bar');
var sibling3 = require('./foobar');

Note how the intragroup "islands" of grouped single-line imports, as well as multi-line imports, are surrounded by new lines.

Essentially, I was looking for a newlines-between-like setting somewhere between "never" and "always-and-inside-groups". I want newlines separating groups/pathGroups imports from one another (like "always-and-inside-groups"), newlines separating imports that span multiple lines from other imports (this is the new thing), and any remaining newlines deleted or "consolidated" (like "never"). The example above demonstrates this use case.

Right now, this is achievable with newlines-between set to "always-and-inside-groups" if you add additional newlines around multi-line imports to every file by hand. The goal of consolidateIslands is to allow eslint --fix to take care of the tedium in a backward-compatible way.

There was a slight complication with consolidateIslands though: while testing across a few mid-sized repos, I discovered my naive implementation caused a conflict when enabled alongside sortTypesAmongThemselves: true, newlines-between: "always-and-inside-groups", and newlines-between-types: "never"... and then only when a normal import was followed by a multi-line type-only import. This conflict makes sense, since newlines-between-types: "never" wants no newlines ever and demands no newline separate type-only imports from normal imports (since, currently, newlines-between-types governs that space), yet consolidateIslands demands a newline separate all multi-line imports from other imports.

To solve this, the current implementation has newlines-between-types yield to consolidateIslands whenever they conflict. I've also added a test to catch any regressions around this edge case.

Copy link

codecov bot commented Dec 23, 2024

Codecov Report

Attention: Patch coverage is 0% with 83 lines in your changes missing coverage. Please review.

Project coverage is 0.00%. Comparing base (8b2d570) to head (02507ca).

Files with missing lines Patch % Lines
src/rules/order.js 0.00% 83 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (8b2d570) and HEAD (02507ca). Click for more details.

HEAD has 3 uploads less than BASE
Flag BASE (8b2d570) HEAD (02507ca)
6 3
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #3129       +/-   ##
==========================================
- Coverage   95.04%   0.00%   -95.05%     
==========================================
  Files          84      95       +11     
  Lines        3634    4265      +631     
  Branches     1279    1420      +141     
==========================================
- Hits         3454       0     -3454     
- Misses        180    4265     +4085     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@ljharb ljharb marked this pull request as draft December 23, 2024 04:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

1 participant