@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 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
  }
@@ -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
- traverse(ast, {
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) lines.push(...leadingComments);
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: false,
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.7",
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 --config prettier.config.mjs --write .",
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
  }