@1adybug/prettier-plugin-sort-imports 0.0.19 → 0.0.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -18
- package/README.zh-CN.md +6 -18
- package/dist/index.js +42 -28
- package/dist/sorter.d.ts +1 -1
- package/dist/types.d.ts +2 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -234,29 +234,19 @@ export default createPlugin({
|
|
|
234
234
|
const path = statement.path
|
|
235
235
|
|
|
236
236
|
// React and related libraries
|
|
237
|
-
if (path.startsWith("react") || path.startsWith("@react"))
|
|
238
|
-
return "react"
|
|
239
|
-
}
|
|
237
|
+
if (path.startsWith("react") || path.startsWith("@react")) return "react"
|
|
240
238
|
|
|
241
239
|
// UI libraries
|
|
242
|
-
if (path.includes("antd") || path.includes("@mui") || path.includes("chakra"))
|
|
243
|
-
return "ui"
|
|
244
|
-
}
|
|
240
|
+
if (path.includes("antd") || path.includes("@mui") || path.includes("chakra")) return "ui"
|
|
245
241
|
|
|
246
242
|
// Utility libraries
|
|
247
|
-
if (path.includes("lodash") || path.includes("ramda") || path.includes("date-fns"))
|
|
248
|
-
return "utils"
|
|
249
|
-
}
|
|
243
|
+
if (path.includes("lodash") || path.includes("ramda") || path.includes("date-fns")) return "utils"
|
|
250
244
|
|
|
251
245
|
// External packages (node_modules)
|
|
252
|
-
if (!path.startsWith(".") && !path.startsWith("@/"))
|
|
253
|
-
return "external"
|
|
254
|
-
}
|
|
246
|
+
if (!path.startsWith(".") && !path.startsWith("@/")) return "external"
|
|
255
247
|
|
|
256
248
|
// Internal aliases (@/)
|
|
257
|
-
if (path.startsWith("@/"))
|
|
258
|
-
return "internal"
|
|
259
|
-
}
|
|
249
|
+
if (path.startsWith("@/")) return "internal"
|
|
260
250
|
|
|
261
251
|
// Relative imports
|
|
262
252
|
return "relative"
|
|
@@ -272,9 +262,7 @@ export default createPlugin({
|
|
|
272
262
|
// Custom import content sorting
|
|
273
263
|
sortImportContent: (a, b) => {
|
|
274
264
|
// Types first, then variables
|
|
275
|
-
if (a.type !== b.type)
|
|
276
|
-
return a.type === "type" ? -1 : 1
|
|
277
|
-
}
|
|
265
|
+
if (a.type !== b.type) return a.type === "type" ? -1 : 1
|
|
278
266
|
|
|
279
267
|
// Alphabetical order within same type
|
|
280
268
|
const aName = a.alias ?? a.name
|
package/README.zh-CN.md
CHANGED
|
@@ -230,29 +230,19 @@ export default createPlugin({
|
|
|
230
230
|
const path = statement.path
|
|
231
231
|
|
|
232
232
|
// React 及相关库
|
|
233
|
-
if (path.startsWith("react") || path.startsWith("@react"))
|
|
234
|
-
return "react"
|
|
235
|
-
}
|
|
233
|
+
if (path.startsWith("react") || path.startsWith("@react")) return "react"
|
|
236
234
|
|
|
237
235
|
// UI 库
|
|
238
|
-
if (path.includes("antd") || path.includes("@mui") || path.includes("chakra"))
|
|
239
|
-
return "ui"
|
|
240
|
-
}
|
|
236
|
+
if (path.includes("antd") || path.includes("@mui") || path.includes("chakra")) return "ui"
|
|
241
237
|
|
|
242
238
|
// 工具库
|
|
243
|
-
if (path.includes("lodash") || path.includes("ramda") || path.includes("date-fns"))
|
|
244
|
-
return "utils"
|
|
245
|
-
}
|
|
239
|
+
if (path.includes("lodash") || path.includes("ramda") || path.includes("date-fns")) return "utils"
|
|
246
240
|
|
|
247
241
|
// 外部包 (node_modules)
|
|
248
|
-
if (!path.startsWith(".") && !path.startsWith("@/"))
|
|
249
|
-
return "external"
|
|
250
|
-
}
|
|
242
|
+
if (!path.startsWith(".") && !path.startsWith("@/")) return "external"
|
|
251
243
|
|
|
252
244
|
// 内部别名 (@/)
|
|
253
|
-
if (path.startsWith("@/"))
|
|
254
|
-
return "internal"
|
|
255
|
-
}
|
|
245
|
+
if (path.startsWith("@/")) return "internal"
|
|
256
246
|
|
|
257
247
|
// 相对导入
|
|
258
248
|
return "relative"
|
|
@@ -268,9 +258,7 @@ export default createPlugin({
|
|
|
268
258
|
// 自定义导入内容排序
|
|
269
259
|
sortImportContent: (a, b) => {
|
|
270
260
|
// 类型在前,变量在后
|
|
271
|
-
if (a.type !== b.type)
|
|
272
|
-
return a.type === "type" ? -1 : 1
|
|
273
|
-
}
|
|
261
|
+
if (a.type !== b.type) return a.type === "type" ? -1 : 1
|
|
274
262
|
|
|
275
263
|
// 同类型内按字母顺序
|
|
276
264
|
const aName = a.alias ?? a.name
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createRequire } from "module";
|
|
2
2
|
import { relative } from "path";
|
|
3
|
-
import {
|
|
3
|
+
import { format } from "prettier";
|
|
4
|
+
import { parse as parser_parse } from "@babel/parser";
|
|
4
5
|
import traverse from "@babel/traverse";
|
|
5
6
|
const analyzer_traverse = "function" == typeof traverse ? traverse : traverse["default"];
|
|
6
7
|
function analyzeUsedIdentifiers(code) {
|
|
7
8
|
const usedIdentifiers = new Set();
|
|
8
9
|
try {
|
|
9
|
-
const ast =
|
|
10
|
+
const ast = parser_parse(code, {
|
|
10
11
|
sourceType: "module",
|
|
11
12
|
plugins: [
|
|
12
13
|
"typescript",
|
|
@@ -174,7 +175,7 @@ function formatImportStatements(statements) {
|
|
|
174
175
|
function parseImports(code, filepath) {
|
|
175
176
|
const hasImportOrExport = /^\s*(import|export)\s/m.test(code);
|
|
176
177
|
if (!hasImportOrExport) return [];
|
|
177
|
-
const ast =
|
|
178
|
+
const ast = parser_parse(code, {
|
|
178
179
|
sourceType: "module",
|
|
179
180
|
plugins: [
|
|
180
181
|
"typescript",
|
|
@@ -195,10 +196,8 @@ function parseImports(code, filepath) {
|
|
|
195
196
|
return importStatements;
|
|
196
197
|
}
|
|
197
198
|
function parseImportNode(node, comments, usedComments, code, isFirstImport, filepath) {
|
|
198
|
-
node.type;
|
|
199
199
|
const source = node.source?.value ?? "";
|
|
200
200
|
const nodeStartLine = node.loc?.start.line ?? 0;
|
|
201
|
-
node.loc?.end.line;
|
|
202
201
|
const nodeStart = node.start ?? 0;
|
|
203
202
|
let nodeEnd = node.end ?? 0;
|
|
204
203
|
const leadingComments = [];
|
|
@@ -463,21 +462,23 @@ function groupImports(imports, userConfig) {
|
|
|
463
462
|
const groupMap = new Map();
|
|
464
463
|
for (const statement of imports){
|
|
465
464
|
const groupName = config.getGroup(statement);
|
|
466
|
-
const key = `${groupName}|||${statement.isSideEffect}`;
|
|
465
|
+
const key = `${groupName}|||${statement.isSideEffect}|||${statement.isExport}`;
|
|
467
466
|
const statements = groupMap.get(key) ?? [];
|
|
468
467
|
statements.push(statement);
|
|
469
468
|
groupMap.set(key, statements);
|
|
470
469
|
}
|
|
471
470
|
const groups = [];
|
|
472
471
|
for (const [key, statements] of Array.from(groupMap.entries())){
|
|
473
|
-
const
|
|
474
|
-
const
|
|
475
|
-
const isSideEffect = "true" ===
|
|
472
|
+
const parts = key.split("|||");
|
|
473
|
+
const isExport = "true" === parts.pop();
|
|
474
|
+
const isSideEffect = "true" === parts.pop();
|
|
475
|
+
const name = parts.join("|||");
|
|
476
476
|
const filepath = statements[0].filepath;
|
|
477
477
|
groups.push({
|
|
478
478
|
filepath,
|
|
479
479
|
name,
|
|
480
480
|
isSideEffect,
|
|
481
|
+
isExport,
|
|
481
482
|
importStatements: statements
|
|
482
483
|
});
|
|
483
484
|
}
|
|
@@ -618,26 +619,25 @@ function preprocessImports(text, options, config = {}) {
|
|
|
618
619
|
const { parsers: { babel } } = src_require("prettier/parser-babel");
|
|
619
620
|
const { parsers: { typescript } } = src_require("prettier/parser-typescript");
|
|
620
621
|
const { parsers: { "babel-ts": babelTs } } = src_require("prettier/parser-babel");
|
|
622
|
+
const PROCESSING_MARKER = Symbol("prettier-plugin-sort-imports-processing");
|
|
621
623
|
function createCombinedPreprocess(parserName, config) {
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
for (const preprocess of preprocessFunctions)try {
|
|
638
|
-
processedText = preprocess(processedText, mergedOptions);
|
|
624
|
+
const otherPlugins = config.otherPlugins || [];
|
|
625
|
+
const pluginsWithPreprocess = otherPlugins.filter((plugin)=>{
|
|
626
|
+
const parser = plugin?.parsers?.[parserName];
|
|
627
|
+
return parser?.preprocess && "function" == typeof parser.preprocess;
|
|
628
|
+
});
|
|
629
|
+
return async function(text, options) {
|
|
630
|
+
if (options[PROCESSING_MARKER]) return text;
|
|
631
|
+
let processedText = preprocessImports(text, options, config);
|
|
632
|
+
if (0 === pluginsWithPreprocess.length) return processedText;
|
|
633
|
+
try {
|
|
634
|
+
processedText = await format(processedText, {
|
|
635
|
+
...options,
|
|
636
|
+
plugins: pluginsWithPreprocess,
|
|
637
|
+
[PROCESSING_MARKER]: true
|
|
638
|
+
});
|
|
639
639
|
} catch (error) {
|
|
640
|
-
console.warn("
|
|
640
|
+
console.warn("Failed to apply other plugins preprocess:", error instanceof Error ? error.message : String(error));
|
|
641
641
|
}
|
|
642
642
|
return processedText;
|
|
643
643
|
};
|
|
@@ -685,16 +685,30 @@ function createPluginInstance(config = {}) {
|
|
|
685
685
|
let merged = {
|
|
686
686
|
...baseParser
|
|
687
687
|
};
|
|
688
|
+
const transformASTFunctions = [];
|
|
688
689
|
for (const plugin of otherPlugins){
|
|
689
690
|
const otherParser = plugin?.parsers?.[parserName];
|
|
690
691
|
if (otherParser) {
|
|
691
|
-
|
|
692
|
+
if ("function" == typeof otherParser.__transformAST) transformASTFunctions.push(otherParser.__transformAST);
|
|
693
|
+
const { preprocess, parse, __transformAST, ...otherAttrs } = otherParser;
|
|
692
694
|
merged = {
|
|
693
695
|
...merged,
|
|
694
696
|
...otherAttrs
|
|
695
697
|
};
|
|
696
698
|
}
|
|
697
699
|
}
|
|
700
|
+
if (transformASTFunctions.length > 0) {
|
|
701
|
+
const originalParse = baseParser.parse;
|
|
702
|
+
merged.parse = function(text, options) {
|
|
703
|
+
let ast = originalParse(text, options);
|
|
704
|
+
for (const transformAST of transformASTFunctions)try {
|
|
705
|
+
ast = transformAST(ast, options);
|
|
706
|
+
} catch (error) {
|
|
707
|
+
console.warn("Plugin transformAST failed:", error instanceof Error ? error.message : String(error));
|
|
708
|
+
}
|
|
709
|
+
return ast;
|
|
710
|
+
};
|
|
711
|
+
}
|
|
698
712
|
merged.preprocess = createCombinedPreprocess(parserName, config);
|
|
699
713
|
mergedParsers[parserName] = merged;
|
|
700
714
|
}
|
package/dist/sorter.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface MergedConfig extends Omit<Required<PluginConfig>, "separator" |
|
|
|
6
6
|
}
|
|
7
7
|
/** 对导入语句进行排序 */
|
|
8
8
|
export declare function sortImports(imports: ImportStatement[], userConfig: PluginConfig): ImportStatement[];
|
|
9
|
-
/** 对导入语句进行分组,同时根据 name 和
|
|
9
|
+
/** 对导入语句进行分组,同时根据 name、isSideEffect 和 isExport 区分 */
|
|
10
10
|
export declare function groupImports(imports: ImportStatement[], userConfig: PluginConfig): Group[];
|
|
11
11
|
/** 对分组进行排序 */
|
|
12
12
|
export declare function sortGroups(groups: Group[], userConfig: PluginConfig): Group[];
|
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1adybug/prettier-plugin-sort-imports",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.21",
|
|
4
4
|
"description": "一个 Prettier 插件,用于对 JavaScript/TypeScript 文件的导入语句进行分组和排序",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"prettier",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"typescript": "^5.9.2"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
|
-
"prettier": "^3.
|
|
59
|
+
"prettier": "^3.7.3"
|
|
60
60
|
},
|
|
61
61
|
"scripts": {
|
|
62
62
|
"build": "rslib build",
|