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

feat(organize_imports): support bun:, #, absolute imports #503

Merged
merged 1 commit into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom

- Import sorting is safe to apply now, and it will be applied when running `check --apply` instead of `check --apply-unsafe`.

- Import sorting now handles Bun imports `bun:<name>`, absolute path imports `/<path>`, and [Node's subpath imports `#<name>`](https://nodejs.org/api/packages.html#subpath-imports). See [our documentation](https://biomejs.dev/analyzer/) for more details. Contributed by @Conaclos

### CLI

#### Bug fixes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ impl PartialEq for ImportKey {
/// are listed before imports closer to the source file.
#[derive(Eq, Ord, PartialEq, PartialOrd)]
enum ImportCategory {
/// Anything with an explicit `bun:` prefix.
Bun,
/// Anything with an explicit `node:` prefix, or one of the recognized
/// Node built-ins, such `"fs"`, `"child_process"`, etc..
NodeBuiltin,
Expand All @@ -601,6 +603,12 @@ enum ImportCategory {
/// may (incorrectly) include source imports through custom import mappings
/// as well.
Library,
/// Absolute file imports `/<path>`.
Absolute,
/// Node allows specifying an import map with name prefixed with `#`.
/// See https://nodejs.org/api/packages.html#subpath-imports
SharpImport,
/// Relative file imports `./<path>`.
Relative,
/// Any unrecognized protocols are grouped here. These may include custom
/// protocols such as supported by bundlers.
Expand All @@ -613,11 +621,16 @@ impl From<&str> for ImportCategory {
Self::Relative
} else if let Some((protocol, _)) = value.split_once(':') {
match protocol {
"bun" => Self::Bun,
"http" | "https" => Self::Url,
"node" => Self::NodeBuiltin,
"npm" => Self::Npm,
_ => Self::Other,
}
} else if value.starts_with('#') {
Self::SharpImport
} else if value.starts_with('/') {
Self::Absolute
} else if NODE_BUILTINS.binary_search(&value).is_ok() {
Self::NodeBuiltin
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ import assert from "node:assert";
import aunt from "../aunt";
import { VERSION } from "https://deno.land/std/version.ts";
import { mock, test } from "node:test";
import { expect } from "bun:test";
import { internal } from "#internal";
import { secret } from "/absolute/path";
Original file line number Diff line number Diff line change
Expand Up @@ -12,25 +12,35 @@ import assert from "node:assert";
import aunt from "../aunt";
import { VERSION } from "https://deno.land/std/version.ts";
import { mock, test } from "node:test";

import { expect } from "bun:test";
import { internal } from "#internal";
import { secret } from "/absolute/path";
```

# Actions
```diff
@@ -1,8 +1,8 @@
@@ -1,11 +1,11 @@
-import uncle from "../uncle";
-import sibling from "./sibling";
+import { expect } from "bun:test";
+import assert from "node:assert";
+import { mock, test } from "node:test";
+import express from "npm:express";
+import { VERSION } from "https://deno.land/std/version.ts";
+import aunt from "../aunt";
import uncle from "../uncle";
import sibling from "./sibling";
-import express from "npm:express";
import imageUrl from "url:./image.png";
import express from "npm:express";
-import imageUrl from "url:./image.png";
-import assert from "node:assert";
-import aunt from "../aunt";
-import { VERSION } from "https://deno.land/std/version.ts";
import { VERSION } from "https://deno.land/std/version.ts";
-import { mock, test } from "node:test";
-import { expect } from "bun:test";
+import { secret } from "/absolute/path";
import { internal } from "#internal";
-import { secret } from "/absolute/path";
\ No newline at end of file
+import aunt from "../aunt";
+import uncle from "../uncle";
+import sibling from "./sibling";
+import imageUrl from "url:./image.png";
\ No newline at end of file

```

Expand Down
23 changes: 17 additions & 6 deletions website/src/content/docs/analyzer/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ This feature is enabled by default but can be opted-in/out via configuration:

Import statements are sorted by "distance". Modules that are "farther" from the user are put on the top, modules "closer" to the user are put on the bottom:

1. built-in Node.js modules that are explicitly imported using the `node:` protocol;
2. modules imported via `npm:` protocol. This is a valid syntax when writing code run by Deno, for example;
3. modules imported via URL;
4. modules imported from libraries;
5. modules imported via relative imports;
6. modules that couldn't be identified by the previous criteria;
1. modules imported via `bun:` protocol. This is applicable when writing code run by Bun;
2. built-in Node.js modules that are explicitly imported using the `node:` protocol and common Node built-ins such as `assert`;
3. modules imported via `npm:` protocol. This is applicable when writing code run by Deno;
4. modules imported via URL;
5. modules imported from libraries;
6. modules imported via absolute imports;
7. modules imported from a name prefixed by `#`. This is applicable when using [Node's subpath imports](https://nodejs.org/api/packages.html#subpath-imports);
8. modules imported via relative imports;
9. modules that couldn't be identified by the previous criteria;

For example, given the following code:

Expand All @@ -41,15 +44,23 @@ import assert from "node:assert";
import aunt from "../aunt";
import { VERSION } from "https://deno.land/std/version.ts";
import { mock, test } from "node:test";
import { expect } from "bun:test";
import { internal } from "#internal";
import { secret } from "/absolute/path";
import React from "react";
```

They will be sorted like this:

```ts
import { expect } from "bun:test";
import assert from "node:assert";
import { mock, test } from "node:test";
import express from "npm:express";
import { VERSION } from "https://deno.land/std/version.ts";
import React from "react";
import { secret } from "/absolute/path";
import { internal } from "#internal";
import aunt from "../aunt";
import uncle from "../uncle";
import sibling from "./sibling";
Expand Down
2 changes: 2 additions & 0 deletions website/src/content/docs/internals/changelog.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Read our [guidelines for writing a good changelog entry](https://github.com/biom

- Import sorting is safe to apply now, and it will be applied when running `check --apply` instead of `check --apply-unsafe`.

- Import sorting now handles Bun imports `bun:<name>`, absolute path imports `/<path>`, and [Node's subpath imports `#<name>`](https://nodejs.org/api/packages.html#subpath-imports). See [our documentation](https://biomejs.dev/analyzer/) for more details. Contributed by @Conaclos

### CLI

#### Bug fixes
Expand Down
Loading