From 0e3719edbe52f11afe1859bde721e37ffe82dd79 Mon Sep 17 00:00:00 2001 From: Simon Lydell Date: Sat, 3 Sep 2022 11:21:38 +0200 Subject: [PATCH] Put `node:*` modules in a separate group by default (#111) --- LICENSE | 2 +- README.md | 15 ++++--- examples/.eslintrc.js | 18 ++++++--- examples/groups.default-reverse.js | 3 ++ examples/groups.none.js | 1 + ...groups.type-imports-first-in-each-group.ts | 4 ++ examples/groups.type-imports-first-sorted.ts | 4 ++ examples/groups.type-imports-first.ts | 4 ++ .../groups.type-imports-last-in-each-group.ts | 4 ++ examples/groups.type-imports-last-sorted.ts | 4 ++ examples/groups.type-imports-last.ts | 4 ++ examples/readme-order.prettier.js | 5 ++- src/imports.js | 2 + test/__snapshots__/examples.test.js.snap | 40 ++++++++++++++++++- test/imports.test.js | 5 +++ 15 files changed, 101 insertions(+), 14 deletions(-) diff --git a/LICENSE b/LICENSE index 78e288a..51fdd02 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2018, 2019, 2020 Simon Lydell +Copyright (c) 2018, 2019, 2020, 2022 Simon Lydell Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 3391f02..06ec13b 100644 --- a/README.md +++ b/README.md @@ -158,9 +158,10 @@ First, the plugin finds all _chunks_ of imports. A “chunk” is a sequence of Then, each chunk is _grouped_ into sections with a blank line between each. 1. `import "./setup"`: Side effect imports. (These are not sorted internally.) -2. `import react from "react"`: Packages (npm packages and Node.js builtins). -3. `import a from "/a"`: Absolute imports and other imports such as Vue-style `@/foo`. -4. `import a from "./a"`: Relative imports. +2. `import * as fs from "node:fs"`: Node.js builtin modules prefixed with `node:`. +3. `import react from "react"`: Packages (npm packages and Node.js builtins _without_ `node:`). +4. `import a from "/a"`: Absolute imports and other imports such as Vue-style `@/foo`. +5. `import a from "./a"`: Relative imports. Note: The above groups are very loosely defined. See [Custom grouping] for more information. @@ -227,10 +228,13 @@ import "./setup"; import "some-polyfill"; import "./global.css"; +// Node.js builtins prefixed with `node:`. +import * as fs from "node:fs"; + // Packages. import type A from "an-npm-package"; import a from "an-npm-package"; -import fs from "fs"; +import fs2 from "fs"; import b from "https://example.com/script.js"; // Absolute imports and other imports. @@ -323,7 +327,6 @@ There is **one** option (see [Not for everyone]) called `groups` that allows you - Move `src/Button`, `@company/Button` and similar out of the (third party) “packages” group, into their own group. - Move `react` first. - Remove blank lines between groups. -- Make a separate group for Node.js builtins. - Make a separate group for style imports. - Separate `./` and `../` imports. - Not use groups at all and only sort alphabetically. @@ -364,6 +367,8 @@ These are the default groups: [ // Side effect imports. ["^\\u0000"], + // Node.js builtins prefixed with `node:`. + ["^node:"], // Packages. // Things that start with a letter (or digit or underscore), or `@` followed by a letter. ["^@?\\w"], diff --git a/examples/.eslintrc.js b/examples/.eslintrc.js index b14d695..44df29b 100644 --- a/examples/.eslintrc.js +++ b/examples/.eslintrc.js @@ -74,6 +74,8 @@ module.exports = { groups: [ // Node.js builtins. You could also generate this regex if you use a `.js` config. // For example: `^(${require("module").builtinModules.join("|")})(/|$)` + // Note that if you use the `node:` prefix for Node.js builtins, + // you can avoid this complexity: You can simply use "^node:". [ "^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)", ], @@ -101,7 +103,7 @@ module.exports = { "error", { // The default grouping, but with no blank lines. - groups: [["^\\u0000", "^@?\\w", "^", "^\\."]], + groups: [["^\\u0000", "^node:", "^@?\\w", "^", "^\\."]], }, ], }, @@ -113,7 +115,7 @@ module.exports = { "error", { // The default grouping, but in reverse. - groups: [["^\\."], ["^"], ["^@?\\w"], ["^\\u0000"]], + groups: [["^\\."], ["^"], ["^@?\\w"], ["^node:"], ["^\\u0000"]], }, ], }, @@ -126,7 +128,7 @@ module.exports = { "error", { // The default grouping, but with type imports first as a separate group. - groups: [["^.*\\u0000$"], ["^\\u0000"], ["^@?\\w"], ["^"], ["^\\."]], + groups: [["^.*\\u0000$"], ["^\\u0000"], ["^node:"], ["^@?\\w"], ["^"], ["^\\."]], }, ], }, @@ -139,7 +141,7 @@ module.exports = { "error", { // The default grouping, but with type imports last as a separate group. - groups: [["^\\u0000"], ["^@?\\w"], ["^"], ["^\\."], ["^.+\\u0000$"]], + groups: [["^\\u0000"], ["^node:"], ["^@?\\w"], ["^"], ["^\\."], ["^.+\\u0000$"]], }, ], }, @@ -154,8 +156,9 @@ module.exports = { // The default grouping, but with type imports first as a separate // group, sorting that group like non-type imports are grouped. groups: [ - ["^@?\\w.*\\u0000$", "^[^.].*\\u0000$", "^\\..*\\u0000$"], + ["^node:.*\\u0000$", "^@?\\w.*\\u0000$", "^[^.].*\\u0000$", "^\\..*\\u0000$"], ["^\\u0000"], + ["^node:"], ["^@?\\w"], ["^"], ["^\\."], @@ -175,10 +178,11 @@ module.exports = { // group, sorting that group like non-type imports are grouped. groups: [ ["^\\u0000"], + ["^node:"], ["^@?\\w"], ["^"], ["^\\."], - ["^@?\\w.*\\u0000$", "^[^.].*\\u0000$", "^\\..*\\u0000$"], + ["^node:.*\\u0000$", "^@?\\w.*\\u0000$", "^[^.].*\\u0000$", "^\\..*\\u0000$"], ], }, ], @@ -194,6 +198,7 @@ module.exports = { // The default grouping, but with type imports first in each group. groups: [ ["^\\u0000"], + ["^node:.*\\u0000$", "^node:"], ["^@?\\w.*\\u0000$", "^@?\\w"], ["(?<=\\u0000)$", "^"], ["^\\..*\\u0000$", "^\\."], @@ -212,6 +217,7 @@ module.exports = { // The default grouping, but with type imports last in each group. groups: [ ["^\\u0000"], + ["^node:", "^node:.*\\u0000$"], ["^@?\\w", "^@?\\w.*\\u0000$"], ["(? ({ |import {} from "#/test" |import {} from "fs"; |import {} from "fs/something"; + |import {} from "node:fs/something"; + |import {} from "node:fs"; |import {} from "Fs"; |import {} from "lodash/fp"; |import {} from "@storybook/react"; @@ -854,6 +856,9 @@ const baseTests = (expect) => ({ `, output: (actual) => { expect(actual).toMatchInlineSnapshot(` + |import {} from "node:fs"; + |import {} from "node:fs/something"; + | |import {} from "@storybook/react"; |import {} from "@storybook/react/something"; |import {} from "1";