Repository: prettier/prettier (JavaScript)

Issue:
Blank line between export specifiers not preserved
**Prettier 2.6.2**
[Playground link](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEcAeAHCAnGACYAHSjzwHoy8BDY0gMwggBpa9WK8AjVzq7FklyoAvAQF8A3CCYgIGGAEtoAZ2Sg+2CAHcACnwSqUVADZaqAT1UzO2KmADWcGAGUqAWzgAZBVDjI6Jspw1rYOTs4Ydj4A5sgw2ACuwahunHAAJukZnlRQ0QlU0XAAYjhuVDCKecggVAkwENIgABYwbsYA6s0K8MqRYHDOBj0KAG495jVgylYgPkG4OrbR5f6ByQBWymjOMcZwAIoJEPBrxkEykdgLNbxpxk0Y2D4wHQrpMM3IABwADJeaIIdWwYGpPOALUZ+GQAR2O8CWckMtWUAFpfBkMk1sHA4QocUtCqskAFzskgm4FHFEuS9od4X4SesZDAqJw3h8vkgAEws2wKYwxADCEDcxNQygArE0EkEACpswyki4gUZJACSUCysGcYGe8gAglrnDBzPszkExGIgA)
<!-- prettier-ignore -->
```sh
--parser babel
```

**Input:**
<!-- prettier-ignore -->
```jsx
export {
  // a
  foo,
  
  // b
  bar,
  baz,
};
```

**Output:**
<!-- prettier-ignore -->
```jsx
export {
  // a
  foo,
  // b
  bar,
  baz,
};

```

**Expected behavior:**

Keep blank line.

Should work as [import and other similar cases](https://prettier.io/playground/#N4Igxg9gdgLgprEAuEcAeAHCAnGACYAHSjzwHoy8BDY0gMwggBpa9WK8AjVzq7FklyoAvAQF88dbBAC2eAOQMI84sXRZcBdpRqClA0tq48+BoaOISpshUpVRiASxkb8RQR131GZo90G8-CYWUFbScoqM9sSQUADObkZekj6sfiZBASLieAC8KRAgTCAQGDCO0HHIoHzSAO4ACnwIVShUADZ1VACeVcWc2FRgANZwMADKVDJwADKOUHDIdB1xcP2DI2PjGEPzAObIMNgArmuoMpxwACZX1zNUUHvHVHtwAGI4MlQw5Y-IIFRjjBCsUABYwGTtADqoMc8DiOzAcHGLThjgAbnDuv8wHE+iB5qtcA1BnsvksVmcAFZxNDjfbtOAARWOEHgFPaq2KO2wRP+vEu7SKIAw2HmMChjiuMFByAAHAAGbnSVZQwYYf6iuBE9GLYoAR1Z8BJpVaALiAFoFtdrsLsHBDY57SSXuSkMtOWdVjJHIcTl6GcyjYt3ZTijAqJxJdLZUgAEzhwaOdr7ADCsjdqDiAFZhcdVgAVSOtD1ckDo04ASSgt1g4zAYrKAEEa+MYN1GRzVmIxEA)



Hints:

Patch:
diff --git a/src/language-js/comments.js b/src/language-js/comments.js
--- a/src/language-js/comments.js
+++ b/src/language-js/comments.js
@@ -65,7 +65,7 @@ function handleOwnLineComment(context) {
     handleForComments,
     handleUnionTypeComments,
     handleOnlyComments,
-    handleImportDeclarationComments,
+    handleModuleSpecifiersComments,
     handleAssignmentPatternComments,
     handleMethodNameComments,
     handleLabeledStatementComments,
@@ -787,17 +787,20 @@ function handleForComments({ comment, enclosingNode }) {
   return false;
 }
 
-function handleImportDeclarationComments({
+function handleModuleSpecifiersComments({
   comment,
   precedingNode,
   enclosingNode,
   text,
 }) {
+  const isImportDeclaration =
+    precedingNode?.type === "ImportSpecifier" &&
+    enclosingNode?.type === "ImportDeclaration";
+  const isExportDeclaration =
+    precedingNode?.type === "ExportSpecifier" &&
+    enclosingNode?.type === "ExportNamedDeclaration";
   if (
-    precedingNode &&
-    precedingNode.type === "ImportSpecifier" &&
-    enclosingNode &&
-    enclosingNode.type === "ImportDeclaration" &&
+    (isImportDeclaration || isExportDeclaration) &&
     hasNewline(text, locEnd(comment))
   ) {
     addTrailingComment(precedingNode, comment);


Test patch:
diff --git a/tests/format/js/export/__snapshots__/jsfmt.spec.js.snap b/tests/format/js/export/__snapshots__/jsfmt.spec.js.snap
--- a/tests/format/js/export/__snapshots__/jsfmt.spec.js.snap
+++ b/tests/format/js/export/__snapshots__/jsfmt.spec.js.snap
@@ -1,5 +1,114 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
+exports[`blank-line-between-specifiers.js - {"bracketSpacing":false} format 1`] = `
+====================================options=====================================
+bracketSpacing: false
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+export {
+  // a
+  foo1,
+
+  // b
+  bar1,
+  baz1,
+} from "mod";
+
+const foo2 = 1;
+const bar2 = 1;
+const baz2 = 1;
+
+export {
+  // a
+  foo2,
+
+  // b
+  bar2,
+  baz2,
+};
+
+=====================================output=====================================
+export {
+  // a
+  foo1,
+
+  // b
+  bar1,
+  baz1,
+} from "mod";
+
+const foo2 = 1;
+const bar2 = 1;
+const baz2 = 1;
+
+export {
+  // a
+  foo2,
+
+  // b
+  bar2,
+  baz2,
+};
+
+================================================================================
+`;
+
+exports[`blank-line-between-specifiers.js format 1`] = `
+====================================options=====================================
+parsers: ["babel", "flow", "typescript"]
+printWidth: 80
+                                                                                | printWidth
+=====================================input======================================
+export {
+  // a
+  foo1,
+
+  // b
+  bar1,
+  baz1,
+} from "mod";
+
+const foo2 = 1;
+const bar2 = 1;
+const baz2 = 1;
+
+export {
+  // a
+  foo2,
+
+  // b
+  bar2,
+  baz2,
+};
+
+=====================================output=====================================
+export {
+  // a
+  foo1,
+
+  // b
+  bar1,
+  baz1,
+} from "mod";
+
+const foo2 = 1;
+const bar2 = 1;
+const baz2 = 1;
+
+export {
+  // a
+  foo2,
+
+  // b
+  bar2,
+  baz2,
+};
+
+================================================================================
+`;
+
 exports[`bracket.js - {"bracketSpacing":false} format 1`] = `
 ====================================options=====================================
 bracketSpacing: false
diff --git a/tests/format/js/export/blank-line-between-specifiers.js b/tests/format/js/export/blank-line-between-specifiers.js
new file mode 100644
--- /dev/null
+++ b/tests/format/js/export/blank-line-between-specifiers.js
@@ -0,0 +1,21 @@
+export {
+  // a
+  foo1,
+
+  // b
+  bar1,
+  baz1,
+} from "mod";
+
+const foo2 = 1;
+const bar2 = 1;
+const baz2 = 1;
+
+export {
+  // a
+  foo2,
+
+  // b
+  bar2,
+  baz2,
+};