@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 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 { parse } from "@babel/parser";
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 = parse(code, {
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 = parse(code, {
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 separatorIndex = key.lastIndexOf("|||");
474
- const name = key.slice(0, separatorIndex);
475
- const isSideEffect = "true" === key.slice(separatorIndex + 3);
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
- return function(text, options) {
623
- const otherPlugins = config.otherPlugins || [];
624
- if (0 === otherPlugins.length) return preprocessImports(text, options, config);
625
- const prettierOptions = config.prettierOptions || {};
626
- const mergedOptions = {
627
- ...options,
628
- ...prettierOptions
629
- };
630
- const preprocessFunctions = [];
631
- preprocessFunctions.push((text, options)=>preprocessImports(text, options, config));
632
- for (const plugin of otherPlugins){
633
- const parser = plugin?.parsers?.[parserName];
634
- if (parser?.preprocess && "function" == typeof parser.preprocess) preprocessFunctions.push(parser.preprocess);
635
- }
636
- let processedText = text;
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("Plugin preprocess failed:", error instanceof Error ? error.message : String(error));
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
- const { preprocess, ...otherAttrs } = otherParser;
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 和 isSideEffect 区分 */
9
+ /** 对导入语句进行分组,同时根据 name、isSideEffectisExport 区分 */
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
@@ -45,6 +45,8 @@ export interface Group {
45
45
  name: string;
46
46
  /** 是否是副作用分组,默认为 false */
47
47
  isSideEffect: boolean;
48
+ /** 是否是导出分组,默认为 false */
49
+ isExport: boolean;
48
50
  /** 分组对应的导入语句列表 */
49
51
  importStatements: ImportStatement[];
50
52
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1adybug/prettier-plugin-sort-imports",
3
- "version": "0.0.19",
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.0.0"
59
+ "prettier": "^3.7.3"
60
60
  },
61
61
  "scripts": {
62
62
  "build": "rslib build",