@1adybug/prettier-plugin-sort-imports 0.0.7 → 0.0.9
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 +4 -0
- package/README.zh-CN.md +3 -0
- package/dist/analyzer.d.ts +2 -1
- package/dist/index.js +27 -7
- package/dist/types.d.ts +2 -0
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -65,6 +65,7 @@ export default {
|
|
|
65
65
|
// Specify group order
|
|
66
66
|
sortGroup: (a, b) => {
|
|
67
67
|
const order = ["react", "external", "local"]
|
|
68
|
+
|
|
68
69
|
return order.indexOf(a.name) - order.indexOf(b.name)
|
|
69
70
|
},
|
|
70
71
|
// Add blank lines between groups
|
|
@@ -187,6 +188,7 @@ export default {
|
|
|
187
188
|
},
|
|
188
189
|
sortGroup: (a, b) => {
|
|
189
190
|
const order = ["react", "external", "local"]
|
|
191
|
+
|
|
190
192
|
return order.indexOf(a.name) - order.indexOf(b.name)
|
|
191
193
|
},
|
|
192
194
|
sortImportStatement: (a, b) => {
|
|
@@ -252,6 +254,7 @@ export default createPlugin({
|
|
|
252
254
|
// Define group order
|
|
253
255
|
sortGroup: (a, b) => {
|
|
254
256
|
const order = ["react", "external", "ui", "utils", "internal", "relative"]
|
|
257
|
+
|
|
255
258
|
return order.indexOf(a.name) - order.indexOf(b.name)
|
|
256
259
|
},
|
|
257
260
|
|
|
@@ -418,6 +421,7 @@ separator: ""
|
|
|
418
421
|
separator: (group, index) => {
|
|
419
422
|
// No separator for the first group
|
|
420
423
|
if (index === 0) return undefined
|
|
424
|
+
|
|
421
425
|
// Add blank lines for other groups
|
|
422
426
|
return ""
|
|
423
427
|
}
|
package/README.zh-CN.md
CHANGED
|
@@ -64,6 +64,7 @@ export default {
|
|
|
64
64
|
// 指定分组顺序
|
|
65
65
|
sortGroup: (a, b) => {
|
|
66
66
|
const order = ["react", "external", "local"]
|
|
67
|
+
|
|
67
68
|
return order.indexOf(a.name) - order.indexOf(b.name)
|
|
68
69
|
},
|
|
69
70
|
// 在分组之间添加空行
|
|
@@ -245,6 +246,7 @@ export default createPlugin({
|
|
|
245
246
|
// 定义分组顺序
|
|
246
247
|
sortGroup: (a, b) => {
|
|
247
248
|
const order = ["react", "external", "ui", "utils", "internal", "relative"]
|
|
249
|
+
|
|
248
250
|
return order.indexOf(a.name) - order.indexOf(b.name)
|
|
249
251
|
},
|
|
250
252
|
|
|
@@ -411,6 +413,7 @@ separator: ""
|
|
|
411
413
|
separator: (group, index) => {
|
|
412
414
|
// 第一个分组不添加分隔符
|
|
413
415
|
if (index === 0) return undefined
|
|
416
|
+
|
|
414
417
|
// 其他分组添加空行
|
|
415
418
|
return ""
|
|
416
419
|
}
|
package/dist/analyzer.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ImportStatement } from "./types";
|
|
1
|
+
import { ImportStatement } from "./types";
|
|
2
|
+
/** 分析代码中使用的标识符 */
|
|
2
3
|
export declare function analyzeUsedIdentifiers(code: string): Set<string>;
|
|
3
4
|
/** 过滤未使用的导入内容 */
|
|
4
5
|
export declare function filterUnusedImports(importStatement: ImportStatement, usedIdentifiers: Set<string>): ImportStatement;
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createRequire } from "module";
|
|
2
2
|
import { parse } from "@babel/parser";
|
|
3
3
|
import traverse from "@babel/traverse";
|
|
4
|
+
const analyzer_traverse = "function" == typeof traverse ? traverse : traverse["default"];
|
|
4
5
|
function analyzeUsedIdentifiers(code) {
|
|
5
6
|
const usedIdentifiers = new Set();
|
|
6
7
|
try {
|
|
@@ -12,7 +13,7 @@ function analyzeUsedIdentifiers(code) {
|
|
|
12
13
|
],
|
|
13
14
|
errorRecovery: true
|
|
14
15
|
});
|
|
15
|
-
|
|
16
|
+
analyzer_traverse(ast, {
|
|
16
17
|
Identifier (path) {
|
|
17
18
|
const node = path.node;
|
|
18
19
|
const parent = path.parent;
|
|
@@ -72,9 +73,13 @@ function removeUnusedImportsFromStatements(importStatements, code) {
|
|
|
72
73
|
return filteredStatements;
|
|
73
74
|
}
|
|
74
75
|
function formatImportStatement(statement) {
|
|
75
|
-
const { path, isExport, isSideEffect, importContents, leadingComments, trailingComments, removedTrailingComments } = statement;
|
|
76
|
+
const { path, isExport, isSideEffect, importContents, leadingComments, trailingComments, removedTrailingComments, emptyLinesAfterComments } = statement;
|
|
76
77
|
const lines = [];
|
|
77
|
-
if (leadingComments && leadingComments.length > 0)
|
|
78
|
+
if (leadingComments && leadingComments.length > 0) {
|
|
79
|
+
lines.push(...leadingComments);
|
|
80
|
+
const emptyLines = emptyLinesAfterComments ?? 0;
|
|
81
|
+
for(let i = 0; i < emptyLines; i++)lines.push("");
|
|
82
|
+
}
|
|
78
83
|
if (isSideEffect) {
|
|
79
84
|
let importLine = "";
|
|
80
85
|
importLine = isExport ? `export * from "${path}"` : `import "${path}"`;
|
|
@@ -170,30 +175,42 @@ function parseImports(code) {
|
|
|
170
175
|
const importStatements = [];
|
|
171
176
|
const { body } = ast.program;
|
|
172
177
|
const usedComments = new Set();
|
|
178
|
+
let isFirstImport = true;
|
|
173
179
|
for (const node of body)if ("ImportDeclaration" === node.type || "ExportNamedDeclaration" === node.type && node.source || "ExportAllDeclaration" === node.type) {
|
|
174
|
-
const statement = parseImportNode(node, ast.comments ?? [], usedComments);
|
|
180
|
+
const statement = parseImportNode(node, ast.comments ?? [], usedComments, code, isFirstImport);
|
|
175
181
|
importStatements.push(statement);
|
|
182
|
+
isFirstImport = false;
|
|
176
183
|
} else break;
|
|
177
184
|
return importStatements;
|
|
178
185
|
}
|
|
179
|
-
function parseImportNode(node, comments, usedComments) {
|
|
186
|
+
function parseImportNode(node, comments, usedComments, code, isFirstImport) {
|
|
180
187
|
node.type;
|
|
181
188
|
const source = node.source?.value ?? "";
|
|
182
|
-
node.loc?.start.line;
|
|
189
|
+
const nodeStartLine = node.loc?.start.line ?? 0;
|
|
183
190
|
node.loc?.end.line;
|
|
184
191
|
const nodeStart = node.start ?? 0;
|
|
185
192
|
let nodeEnd = node.end ?? 0;
|
|
186
193
|
const leadingComments = [];
|
|
187
194
|
const trailingComments = [];
|
|
188
195
|
let start = nodeStart;
|
|
196
|
+
let emptyLinesAfterComments = 0;
|
|
189
197
|
if (node.leadingComments) {
|
|
198
|
+
let lastCommentEndLine = 0;
|
|
190
199
|
for (const comment of node.leadingComments)if (!usedComments.has(comment)) {
|
|
200
|
+
const commentEndLine = comment.loc?.end.line ?? 0;
|
|
201
|
+
const emptyLinesBetween = nodeStartLine - commentEndLine - 1;
|
|
202
|
+
if (isFirstImport && emptyLinesBetween >= 1) {
|
|
203
|
+
usedComments.add(comment);
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
191
206
|
if ("CommentLine" === comment.type) leadingComments.push(`//${comment.value}`);
|
|
192
207
|
else if ("CommentBlock" === comment.type) leadingComments.push(`/*${comment.value}*/`);
|
|
193
208
|
const commentStart = comment.start ?? 0;
|
|
194
209
|
if (commentStart < start) start = commentStart;
|
|
210
|
+
lastCommentEndLine = commentEndLine;
|
|
195
211
|
usedComments.add(comment);
|
|
196
212
|
}
|
|
213
|
+
if (leadingComments.length > 0 && lastCommentEndLine > 0) emptyLinesAfterComments = nodeStartLine - lastCommentEndLine - 1;
|
|
197
214
|
}
|
|
198
215
|
if (node.trailingComments) {
|
|
199
216
|
for (const comment of node.trailingComments)if (!usedComments.has(comment)) {
|
|
@@ -221,6 +238,7 @@ function parseImportNode(node, comments, usedComments) {
|
|
|
221
238
|
importContents,
|
|
222
239
|
leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
|
|
223
240
|
trailingComments: trailingComments.length > 0 ? trailingComments : void 0,
|
|
241
|
+
emptyLinesAfterComments: emptyLinesAfterComments > 0 ? emptyLinesAfterComments : void 0,
|
|
224
242
|
start,
|
|
225
243
|
end
|
|
226
244
|
};
|
|
@@ -228,10 +246,11 @@ function parseImportNode(node, comments, usedComments) {
|
|
|
228
246
|
if ("ExportAllDeclaration" === node.type) return {
|
|
229
247
|
path: source,
|
|
230
248
|
isExport: true,
|
|
231
|
-
isSideEffect:
|
|
249
|
+
isSideEffect: true,
|
|
232
250
|
importContents: [],
|
|
233
251
|
leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
|
|
234
252
|
trailingComments: trailingComments.length > 0 ? trailingComments : void 0,
|
|
253
|
+
emptyLinesAfterComments: emptyLinesAfterComments > 0 ? emptyLinesAfterComments : void 0,
|
|
235
254
|
start,
|
|
236
255
|
end
|
|
237
256
|
};
|
|
@@ -244,6 +263,7 @@ function parseImportNode(node, comments, usedComments) {
|
|
|
244
263
|
importContents,
|
|
245
264
|
leadingComments: leadingComments.length > 0 ? leadingComments : void 0,
|
|
246
265
|
trailingComments: trailingComments.length > 0 ? trailingComments : void 0,
|
|
266
|
+
emptyLinesAfterComments: emptyLinesAfterComments > 0 ? emptyLinesAfterComments : void 0,
|
|
247
267
|
start,
|
|
248
268
|
end
|
|
249
269
|
};
|
package/dist/types.d.ts
CHANGED
|
@@ -28,6 +28,8 @@ export interface ImportStatement {
|
|
|
28
28
|
trailingComments?: string[];
|
|
29
29
|
/** 被移除的导入语句的行尾注释(合并时使用) */
|
|
30
30
|
removedTrailingComments?: string[];
|
|
31
|
+
/** 前导注释后的空行数(用于保留注释和 import 之间的空行) */
|
|
32
|
+
emptyLinesAfterComments?: number;
|
|
31
33
|
/** 在源代码中的起始位置(包括注释) */
|
|
32
34
|
start?: number;
|
|
33
35
|
/** 在源代码中的结束位置 */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@1adybug/prettier-plugin-sort-imports",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.9",
|
|
5
5
|
"description": "一个 Prettier 插件,用于对 JavaScript/TypeScript 文件的导入语句进行分组和排序",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"prettier",
|
|
@@ -44,16 +44,19 @@
|
|
|
44
44
|
"build": "rslib build",
|
|
45
45
|
"dev": "rslib build --watch",
|
|
46
46
|
"prepublishOnly": "npm run build",
|
|
47
|
-
"format": "prettier --
|
|
47
|
+
"format": "prettier --write .",
|
|
48
48
|
"test": "bun test",
|
|
49
|
-
"test:watch": "bun test --watch"
|
|
49
|
+
"test:watch": "bun test --watch",
|
|
50
|
+
"fg": "npm run format && git add . && git commit -m \"✨feature: format\""
|
|
50
51
|
},
|
|
51
52
|
"devDependencies": {
|
|
52
53
|
"@rslib/core": "^0.15.0",
|
|
53
54
|
"@types/babel__core": "^7.20.5",
|
|
54
55
|
"@types/bun": "latest",
|
|
55
56
|
"@types/node": "^22.18.6",
|
|
57
|
+
"json5": "^2.2.3",
|
|
56
58
|
"prettier": "^3.6.2",
|
|
59
|
+
"prettier-plugin-block-padding": "^0.0.6",
|
|
57
60
|
"prettier-plugin-tailwindcss": "^0.7.0",
|
|
58
61
|
"supports-color": "^10.2.2",
|
|
59
62
|
"typescript": "^5.9.2"
|
|
@@ -64,6 +67,7 @@
|
|
|
64
67
|
"dependencies": {
|
|
65
68
|
"@babel/core": "^7.28.4",
|
|
66
69
|
"@babel/parser": "^7.28.4",
|
|
70
|
+
"@babel/traverse": "^7.28.4",
|
|
67
71
|
"@babel/types": "^7.28.4"
|
|
68
72
|
}
|
|
69
73
|
}
|