Repository: prettier/plugin-php
Pull request #2212 (2023-08-16 09:53:49)

Simplify `print()`
Since we are going to drop support for Prettier<3, we can use [simplified `print()` introduced in Prettier v2.3.0](https://prettier.io/blog/2021/05/09/2.3.0#simplified-print-callback-10557httpsgithubcomprettierprettierpull10557-by-fiskerhttpsgithubcomfisker).


Patch:
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 57a6e77..f62d294 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -39,9 +39,13 @@ rules:
     - never
     - exceptRange: true
 overrides:
-  - files: "tests/**/*.js"
+  - files: "{tests,tests_config}/**/*.js"
+    parserOptions:
+      sourceType: "module"
     rules:
-      strict: off
+      # Turned off temporarily since we add a package.json without dependencies in these dirs
+      import/no-extraneous-dependencies: off
+  - files: "tests/**/*.js"
     globals:
       run_spec: true
   - files: "build/*.js"
diff --git a/.gitattributes b/.gitattributes
index 2d640ef..ced0335 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,3 +1,4 @@
+* text=auto eol=lf
 tests/newline/CRLF.php text eol=crlf
 tests/newline/html-CRLF.php text eol=crlf
 tests/newline/mixed-CRLF.php text eol=crlf
diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml
index 2cc92d9..1fa6773 100644
--- a/.github/workflows/nodejs.yml
+++ b/.github/workflows/nodejs.yml
@@ -12,9 +12,9 @@ jobs:
         node-version: [14.x, 16.x, 18.x, 20.x]
 
     steps:
-      - uses: actions/checkout@v1
+      - uses: actions/checkout@v3
       - name: Use Node.js ${{ matrix.node-version }}
-        uses: actions/setup-node@v1
+        uses: actions/setup-node@v3
         with:
           node-version: ${{ matrix.node-version }}
       - name: yarn install, build, and test
diff --git a/jest.config.js b/jest.config.js
index 3248cc7..4c65d2f 100644
--- a/jest.config.js
+++ b/jest.config.js
@@ -1,6 +1,7 @@
 "use strict";
 
 const ENABLE_COVERAGE = !!process.env.CI;
+const RUN_STANDALONE_TESTS = Boolean(process.env.RUN_STANDALONE_TESTS);
 
 module.exports = {
   collectCoverage: ENABLE_COVERAGE,
@@ -10,34 +11,31 @@ module.exports = {
     "!<rootDir>/tests_config/",
   ],
   projects: [
-    {
-      displayName: "test-node",
-      setupFiles: ["<rootDir>/tests_config/run_spec.js"],
-      testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
-      snapshotSerializers: ["jest-snapshot-serializer-raw"],
-      testEnvironment: "node",
-      globals: {
-        STANDALONE: false,
-      },
-      runner: "jest-light-runner",
-      transform: {},
-    },
-    ...(/^true$/i.test(process.env.RUN_STANDALONE_TESTS)
-      ? [
-          {
-            displayName: "test-standalone",
-            setupFiles: ["<rootDir>/tests_config/run_spec.js"],
-            testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
-            snapshotSerializers: ["jest-snapshot-serializer-raw"],
-            testEnvironment: "jsdom",
-            globals: {
-              STANDALONE: true,
-            },
-            runner: "jest-light-runner",
-            transform: {},
+    RUN_STANDALONE_TESTS
+      ? {
+          displayName: "test-standalone",
+          setupFiles: ["<rootDir>/tests_config/run_spec.js"],
+          testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
+          snapshotSerializers: ["jest-snapshot-serializer-raw"],
+          testEnvironment: "jsdom",
+          globals: {
+            STANDALONE: true,
+          },
+          runner: "jest-light-runner",
+          transform: {},
+        }
+      : {
+          displayName: "test-node",
+          setupFiles: ["<rootDir>/tests_config/run_spec.js"],
+          testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
+          snapshotSerializers: ["jest-snapshot-serializer-raw"],
+          testEnvironment: "node",
+          globals: {
+            STANDALONE: false,
           },
-        ]
-      : []),
+          runner: "jest-light-runner",
+          transform: {},
+        },
     {
       runner: "jest-runner-eslint",
       displayName: "lint",
diff --git a/package.json b/package.json
index 97dd246..1aaab2d 100644
--- a/package.json
+++ b/package.json
@@ -40,15 +40,16 @@
     "rollup-plugin-node-resolve": "^5.2.0",
     "rollup-plugin-replace": "^2.1.0",
     "rollup-plugin-terser": "^7.0.2",
-    "strip-ansi": "^6.0.0",
-    "yarpm": "^1.1.1"
+    "strip-ansi": "^6.0.0"
   },
   "peerDependencies": {
     "prettier": "^3.0.0"
   },
   "scripts": {
-    "test": "jest",
-    "prepublishOnly": "yarpm run build-standalone && cross-env RUN_STANDALONE_TESTS=true yarpm test",
+    "test": "yarn test:node && yarn test:standalone",
+    "test:node": "jest",
+    "test:standalone": "yarn run build-standalone && cross-env RUN_STANDALONE_TESTS=true yarn jest",
+    "prepublishOnly": "yarn test",
     "prettier": "prettier --plugin=src/index.js --parser=php",
     "build-standalone": "rollup -c build/rollup.config.js",
     "debug": "node --inspect-brk node_modules/.bin/jest --runInBand"
diff --git a/src/printer.js b/src/printer.js
index 43079e3..53b27a8 100644
--- a/src/printer.js
+++ b/src/printer.js
@@ -115,7 +115,7 @@ function genericPrint(path, options, print) {
 }
 
 function printPropertyLookup(path, options, print, nullsafe = false) {
-  return [nullsafe ? "?" : "", "->", path.call(print, "offset")];
+  return [nullsafe ? "?" : "", "->", print("offset")];
 }
 
 function printNullsafePropertyLookup(path, options, print) {
@@ -126,12 +126,7 @@ function printStaticLookup(path, options, print) {
   const node = path.getValue();
   const needCurly = !["variable", "identifier"].includes(node.offset.kind);
 
-  return [
-    "::",
-    needCurly ? "{" : "",
-    path.call(print, "offset"),
-    needCurly ? "}" : "",
-  ];
+  return ["::", needCurly ? "{" : "", print("offset"), needCurly ? "}" : ""];
 }
 
 function printOffsetLookup(path, options, print) {
@@ -144,7 +139,7 @@ function printOffsetLookup(path, options, print) {
     "[",
     node.offset
       ? group([
-          indent([shouldInline ? "" : softline, path.call(print, "offset")]),
+          indent([shouldInline ? "" : softline, print("offset")]),
           shouldInline ? "" : softline,
         ])
       : "",
@@ -262,7 +257,7 @@ function printMemberChain(path, options, print) {
     } else {
       printedNodes.unshift({
         node,
-        printed: path.call(print),
+        printed: print(),
       });
     }
   }
@@ -659,7 +654,7 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
     path.each((argPath) => {
       if (shouldGroupFirst && i === 0) {
         printedExpanded = [
-          argPath.call((p) => print(p, { expandFirstArg: true })),
+          argPath.call(() => print([], { expandFirstArg: true })),
           printedArguments.length > 1 ? "," : "",
           hasEmptyLineFollowingFirstArg ? hardline : line,
           hasEmptyLineFollowingFirstArg ? hardline : "",
@@ -670,7 +665,7 @@ function printArgumentsList(path, options, print, argumentsKey = "arguments") {
       if (shouldGroupLast && i === args.length - 1) {
         printedExpanded = [
           ...printedArguments.slice(0, -1),
-          argPath.call((p) => print(p, { expandLastArg: true })),
+          argPath.call(() => print([], { expandLastArg: true })),
         ];
       }
 
@@ -772,9 +767,9 @@ function printBinaryExpression(
       // Flatten them out by recursively calling this function.
       parts = parts.concat(
         path.call(
-          (left) =>
+          () =>
             printBinaryExpression(
-              left,
+              path,
               print,
               options,
               /* isNested */ true,
@@ -784,14 +779,14 @@ function printBinaryExpression(
         )
       );
     } else {
-      parts.push(path.call(print, "left"));
+      parts.push(print("left"));
     }
 
     const shouldInline = shouldInlineLogicalExpression(node);
 
     const right = shouldInline
-      ? [node.type, " ", path.call(print, "right")]
-      : [node.type, line, path.call(print, "right")];
+      ? [node.type, " ", print("right")]
+      : [node.type, line, print("right")];
 
     // If there's only a single binary expression, we want to create a group
     // in order to avoid having a small right part like -1 be on its own line.
@@ -822,7 +817,7 @@ function printBinaryExpression(
     }
   } else {
     // Our stopping case. Simply print the node normally.
-    parts.push(path.call(print));
+    parts.push(print());
   }
 
   return parts;
@@ -1148,7 +1143,7 @@ function printClassPart(
     ? [
         hardline,
         path.call(
-          (partPath) => comments.printDanglingComments(partPath, options, true),
+          () => comments.printDanglingComments(path, options, true),
           part
         ),
         hardline,
@@ -1172,7 +1167,7 @@ function printClassPart(
           }, part)
         )
       )
-    : [afterPart, path.call(print, part)];
+    : [afterPart, print(part)];
 
   return indent([
     printedBeforePart,
@@ -1241,11 +1236,11 @@ function printClass(path, options, print) {
   declaration.push(isAnonymousClass ? "" : node.kind);
 
   if (node.name) {
-    declaration.push(" ", path.call(print, "name"));
+    declaration.push(" ", print("name"));
   }
 
   if (node.kind === "enum" && node.valueType) {
-    declaration.push(": ", path.call(print, "valueType"));
+    declaration.push(": ", print("valueType"));
   }
 
   // Only `class` can have `extends` and `implements`
@@ -1369,7 +1364,7 @@ function printFunction(path, options, print) {
   }
 
   if (node.name) {
-    declaration.push(path.call(print, "name"));
+    declaration.push(print("name"));
   }
 
   declaration.push(printArgumentsList(path, options, print));
@@ -1386,15 +1381,14 @@ function printFunction(path, options, print) {
       hasDanglingComments(node.type)
         ? [
             path.call(
-              (typePath) =>
-                comments.printDanglingComments(typePath, options, true),
+              () => comments.printDanglingComments(path, options, true),
               "type"
             ),
             " ",
           ]
         : "",
       node.nullable ? "?" : "",
-      path.call(print, "type"),
+      print("type"),
     ]);
   }
 
@@ -1407,7 +1401,7 @@ function printFunction(path, options, print) {
   const isClosure = node.kind === "closure";
   const printedBody = [
     "{",
-    indent([hasEmptyBody(path) ? "" : hardline, path.call(print, "body")]),
+    indent([hasEmptyBody(path) ? "" : hardline, print("body")]),
     isClosure && hasEmptyBody(path) ? "" : hardline,
     "}",
   ];
@@ -1456,7 +1450,7 @@ function printBodyControlStructure(
     return ";";
   }
 
-  const printedBody = path.call(print, bodyProperty);
+  const printedBody = print(bodyProperty);
 
   return [
     node.shortForm ? ":" : " {",
@@ -1586,10 +1580,7 @@ function isStringOnItsOwnLine(node, text, options) {
 
 function printComposedTypes(path, print, glue) {
   return group(
-    path.map(
-      (uPath, i) => (i === 0 ? [path.call(print)] : [glue, path.call(print)]),
-      "types"
-    )
+    path.map((uPath, i) => (i === 0 ? [print()] : [glue, print()]), "types")
   );
 }
 
@@ -1609,7 +1600,7 @@ function printNode(path, options, print) {
       ]);
     }
     case "expressionstatement":
-      return path.call(print, "expression");
+      return print("expression");
     case "block":
       return [
         printLines(path, options, print),
@@ -1648,7 +1639,7 @@ function printNode(path, options, print) {
       ];
     }
     case "declaredirective":
-      return [path.call(print, "key"), "=", path.call(print, "value")];
+      return [print("key"), "=", print("value")];
     case "namespace":
       return [
         "namespace ",
@@ -1708,7 +1699,7 @@ function printNode(path, options, print) {
         hasDanglingComments(node)
           ? [" ", comments.printDanglingComments(path, options, true)]
           : "",
-        node.alias ? [" as ", path.call(print, "alias")] : "",
+        node.alias ? [" as ", print("alias")] : "",
       ];
     case "class":
     case "enum":
@@ -1717,20 +1708,20 @@ function printNode(path, options, print) {
       return printClass(path, options, print);
     case "traitprecedence":
       return [
-        path.call(print, "trait"),
+        print("trait"),
         "::",
-        path.call(print, "method"),
+        print("method"),
         " insteadof ",
         join(", ", path.map(print, "instead")),
       ];
     case "traitalias":
       return [
-        node.trait ? [path.call(print, "trait"), "::"] : "",
-        node.method ? path.call(print, "method") : "",
+        node.trait ? [print("trait"), "::"] : "",
+        node.method ? print("method") : "",
         " as ",
         join(" ", [
           ...(node.visibility ? [node.visibility] : []),
-          ...(node.as ? [path.call(print, "as")] : []),
+          ...(node.as ? [print("as")] : []),
         ]),
       ];
     case "traituse":
@@ -1770,11 +1761,9 @@ function printNode(path, options, print) {
         node.isStatic ? "static " : "",
         "fn",
         printArgumentsList(path, options, print),
-        node.type
-          ? [": ", node.nullable ? "?" : "", path.call(print, "type")]
-          : "",
+        node.type ? [": ", node.nullable ? "?" : "", print("type")] : "",
         " => ",
-        path.call(print, "body"),
+        print("body"),
         node.parenthesizedExpression ? ")" : "",
       ];
     case "parameter": {
@@ -1791,11 +1780,11 @@ function printNode(path, options, print) {
         promoted,
         node.readonly ? "readonly " : "",
         node.nullable ? "?" : "",
-        node.type ? [path.call(print, "type"), " "] : "",
+        node.type ? [print("type"), " "] : "",
         node.byref ? "&" : "",
         node.variadic ? "..." : "",
         "$",
-        path.call(print, "name"),
+        print("name"),
       ];
 
       if (node.value) {
@@ -1810,7 +1799,7 @@ function printNode(path, options, print) {
           printAssignmentRight(
             node.name,
             node.value,
-            path.call(print, "value"),
+            print("value"),
             false,
             options
           ),
@@ -1820,22 +1809,20 @@ function printNode(path, options, print) {
       return name;
     }
     case "variadic":
-      return ["...", path.call(print, "what")];
+      return ["...", print("what")];
     case "property":
       return group([
         node.readonly ? "readonly " : "",
-        node.type
-          ? [node.nullable ? "?" : "", path.call(print, "type"), " "]
-          : "",
+        node.type ? [node.nullable ? "?" : "", print("type"), " "] : "",
         "$",
-        path.call(print, "name"),
+        print("name"),
         node.value
           ? [
               " =",
               printAssignmentRight(
                 node.name,
                 node.value,
-                path.call(print, "value"),
+                print("value"),
                 false,
                 options
               ),
@@ -1882,7 +1869,7 @@ function printNode(path, options, print) {
       const body = printBodyControlStructure(path, options, print, "body");
       const opening = group([
         "if (",
-        group([indent([softline, path.call(print, "test")]), softline]),
+        group([indent([softline, print("test")]), softline]),
         ")",
         body,
       ]);
@@ -1918,7 +1905,7 @@ function printNode(path, options, print) {
           "else",
           group(
             node.alternate.kind === "if"
-              ? path.call(print, "alternate")
+              ? print("alternate")
               : printBodyControlStructure(path, options, print, "alternate")
           )
         );
@@ -1933,7 +1920,7 @@ function printNode(path, options, print) {
         "do",
         printBodyControlStructure(path, options, print, "body"),
         " while (",
-        group([indent([softline, path.call(print, "test")]), softline]),
+        group([indent([softline, print("test")]), softline]),
         ")",
       ];
     case "while":
@@ -1941,7 +1928,7 @@ function printNode(path, options, print) {
       return group([
         node.kind,
         " (",
-        group([indent([softline, path.call(print, "test")]), softline]),
+        group([indent([softline, print("test")]), softline]),
         ")",
         printBodyControlStructure(path, options, print, "body"),
       ]);
@@ -2004,18 +1991,13 @@ function printNode(path, options, print) {
           group([
             indent([
               softline,
-              path.call(print, "source"),
+              print("source"),
               line,
               "as ",
               group(
                 node.key
-                  ? indent(
-                      join(
-                        [" =>", line],
-                        [path.call(print, "key"), path.call(print, "value")]
-                      )
-                    )
-                  : path.call(print, "value")
+                  ? indent(join([" =>", line], [print("key"), print("value")]))
+                  : print("value")
               ),
             ]),
             softline,
@@ -2053,7 +2035,7 @@ function printNode(path, options, print) {
           ? [
               " (",
               join(" | ", path.map(print, "what")),
-              node.variable ? [" ", path.call(print, "variable")] : "",
+              node.variable ? [" ", print("variable")] : "",
               ")",
             ]
           : "",
@@ -2065,9 +2047,7 @@ function printNode(path, options, print) {
         node.test
           ? [
               "case ",
-              node.test.comments
-                ? indent(path.call(print, "test"))
-                : path.call(print, "test"),
+              node.test.comments ? indent(print("test")) : print("test"),
               ":",
             ]
           : "default:",
@@ -2075,7 +2055,7 @@ function printNode(path, options, print) {
           ? node.body.children && node.body.children.length
             ? indent([
                 isFirstChildrenInlineNode(path) ? "" : hardline,
-                path.call(print, "body"),
+                print("body"),
               ])
             : ""
           : "",
@@ -2084,7 +2064,7 @@ function printNode(path, options, print) {
     case "continue":
       if (node.level) {
         if (node.level.kind === "number" && node.level.value !== "1") {
-          return [`${node.kind} `, path.call(print, "level")];
+          return [`${node.kind} `, print("level")];
         }
 
         return node.kind;
@@ -2098,7 +2078,7 @@ function printNode(path, options, print) {
         isStringOnItsOwnLine(node.arguments[0], options.originalText, options)
       ) {
         return [
-          path.call(print, "what"),
+          print("what"),
           "(",
           join(", ", path.map(print, "arguments")),
           ")",
@@ -2110,10 +2090,7 @@ function printNode(path, options, print) {
         return printMemberChain(path, options, print);
       }
 
-      return [
-        path.call(print, "what"),
-        printArgumentsList(path, options, print),
-      ];
+      return [print("what"), printArgumentsList(path, options, print)];
     }
     case "new": {
       const isAnonymousClassNode =
@@ -2128,7 +2105,7 @@ function printNode(path, options, print) {
         return [
           "new ",
           ...path.call(printAttrs, "what"),
-          path.call(print, "what"),
+          print("what"),
           "(",
           join(", ", path.map(print, "arguments")),
           ")",
@@ -2146,20 +2123,20 @@ function printNode(path, options, print) {
             ? [comments.printComments(node.what.leadingComments, options), " "]
             : "",
           ...path.call(
-            (pa) => printAttrs(pa, options, print, { inline: true }),
+            () => printAttrs(path, options, print, { inline: true }),
             "what"
           ),
           "class",
           node.arguments.length > 0
             ? [" ", printArgumentsList(path, options, print)]
             : "",
-          group(path.call(print, "what"))
+          group(print("what"))
         );
       } else {
         const isExpression = ["call", "offsetlookup"].includes(node.what.kind);
         const printed = [
           isExpression ? "(" : "",
-          path.call(print, "what"),
+          print("what"),
           isExpression ? ")" : "",
           printArgumentsList(path, options, print),
         ];
@@ -2172,9 +2149,7 @@ function printNode(path, options, print) {
     case "clone":
       return [
         "clone ",
-        node.what.comments
-          ? indent(path.call(print, "what"))
-          : path.call(print, "what"),
+        node.what.comments ? indent(print("what")) : print("what"),
       ];
     case "propertylookup":
     case "nullsafepropertylookup":
@@ -2206,7 +2181,7 @@ function printNode(path, options, print) {
           !isLookupNode(parent));
 
       return [
-        path.call(print, "what"),
+        print("what"),
         shouldInline
           ? printLookupNodes(path, options, print)
           : group(indent([softline, printLookupNodes(path, options, print)])),
@@ -2218,8 +2193,8 @@ function printNode(path, options, print) {
         "(",
         node.expression
           ? isStringOnItsOwnLine(node.expression, options.originalText, options)
-            ? path.call(print, "expression")
-            : [indent([softline, path.call(print, "expression")]), softline]
+            ? print("expression")
+            : [indent([softline, print("expression")]), softline]
           : comments.printDanglingComments(path, options),
         ")",
       ]);
@@ -2233,23 +2208,19 @@ function printNode(path, options, print) {
         node.require ? "require" : "include",
         node.once ? "_once" : "",
         " ",
-        node.target.comments
-          ? indent(path.call(print, "target"))
-          : path.call(print, "target"),
+        node.target.comments ? indent(print("target")) : print("target"),
       ];
     case "label":
-      return [path.call(print, "name"), ":"];
+      return [print("name"), ":"];
     case "goto":
-      return ["goto ", path.call(print, "label")];
+      return ["goto ", print("label")];
     case "throw":
       return [
         "throw ",
-        node.what.comments
-          ? indent(path.call(print, "what"))
-          : path.call(print, "what"),
+        node.what.comments ? indent(print("what")) : print("what"),
       ];
     case "silent":
-      return ["@", path.call(print, "expr")];
+      return ["@", print("expr")];
     case "halt":
       return [
         hasDanglingComments(node)
@@ -2269,8 +2240,8 @@ function printNode(path, options, print) {
       return group([
         "eval(",
         isStringOnItsOwnLine(node.source, options.originalText, options)
-          ? path.call(print, "source")
-          : [indent([softline, path.call(print, "source")]), softline],
+          ? print("source")
+          : [indent([softline, print("source")]), softline],
         ")",
       ]);
     case "echo": {
@@ -2299,8 +2270,8 @@ function printNode(path, options, print) {
       return [
         "print ",
         node.expression.comments
-          ? indent(path.call(print, "expression"))
-          : path.call(print, "expression"),
+          ? indent(print("expression"))
+          : print("expression"),
       ];
     }
     case "return": {
@@ -2309,7 +2280,7 @@ function printNode(path, options, print) {
       parts.push("return");
 
       if (node.expr) {
-        const printedExpr = path.call(print, "expr");
+        const printedExpr = print("expr");
 
         parts.push(" ", node.expr.comments ? indent(printedExpr) : printedExpr);
       }
@@ -2332,7 +2303,7 @@ function printNode(path, options, print) {
     case "empty":
       return group([
         "empty(",
-        indent([softline, path.call(print, "expression")]),
+        indent([softline, print("expression")]),
         softline,
         ")",
       ]);
@@ -2354,13 +2325,7 @@ function printNode(path, options, print) {
       const openCurly = node.curly ? "{" : "";
       const closeCurly = node.curly ? "}" : "";
 
-      return [
-        ampersand,
-        dollar,
-        openCurly,
-        path.call(print, "name"),
-        closeCurly,
-      ];
+      return [ampersand, dollar, openCurly, print("name"), closeCurly];
     }
     case "constantstatement":
     case "classconstant": {
@@ -2388,10 +2353,10 @@ function printNode(path, options, print) {
     case "constant":
       return printAssignment(
         node.name,
-        path.call(print, "name"),
+        print("name"),
         " =",
         node.value,
-        path.call(print, "value"),
+        print("value"),
         false,
         options
       );
@@ -2422,10 +2387,10 @@ function printNode(path, options, print) {
     case "staticvariable": {
       return printAssignment(
         node.variable,
-        path.call(print, "variable"),
+        print("variable"),
         " =",
         node.defaultValue,
-        path.call(print, "defaultValue"),
+        print("defaultValue"),
         false,
         options
       );
@@ -2507,19 +2472,19 @@ function printNode(path, options, print) {
       return node.key
         ? printAssignment(
             node.key,
-            path.call(print, "key"),
+            print("key"),
             " =>",
             node.value,
-            path.call(print, "value"),
+            print("value"),
             ref,
             options
           )
-        : [ref, unpack, path.call(print, "value")];
+        : [ref, unpack, print("value")];
     }
     case "yield": {
       const printedKeyAndValue = [
-        node.key ? [path.call(print, "key"), " => "] : "",
-        path.call(print, "value"),
+        node.key ? [print("key"), " => "] : "",
+        print("value"),
       ];
 
       return [
@@ -2533,24 +2498,20 @@ function printNode(path, options, print) {
     case "yieldfrom":
       return [
         "yield from ",
-        node.value.comments
-          ? indent(path.call(print, "value"))
-          : path.call(print, "value"),
+        node.value.comments ? indent(print("value")) : print("value"),
       ];
     case "unary":
-      return [node.type, path.call(print, "what")];
+      return [node.type, print("what")];
     case "pre":
-      return [node.type + node.type, path.call(print, "what")];
+      return [node.type + node.type, print("what")];
     case "post":
-      return [path.call(print, "what"), node.type + node.type];
+      return [print("what"), node.type + node.type];
     case "cast":
       return [
         "(",
         node.type,
         ") ",
-        node.expr.comments
-          ? indent(path.call(print, "expr"))
-          : path.call(print, "expr"),
+        node.expr.comments ? indent(print("expr")) : print("expr"),
       ];
     case "assignref":
     case "assign": {
@@ -2558,10 +2519,10 @@ function printNode(path, options, print) {
 
       return printAssignment(
         node.left,
-        path.call(print, "left"),
+        print("left"),
         [" ", hasRef ? "=" : node.operator],
         node.right,
-        path.call(print, "right"),
+        print("right"),
         hasRef,
         options
       );
@@ -2665,8 +2626,8 @@ function printNode(path, options, print) {
 
       const printedFalseExpr =
         node.falseExpr.kind === "bin"
-          ? indent(path.call(print, "falseExpr"))
-          : path.call(print, "falseExpr");
+          ? indent(print("falseExpr"))
+          : print("falseExpr");
       const part = [
         node.trueExpr ? line : " ",
         "?",
@@ -2674,8 +2635,8 @@ function printNode(path, options, print) {
           ? [
               " ",
               node.trueExpr.kind === "bin"
-                ? indent(path.call(print, "trueExpr"))
-                : path.call(print, "trueExpr"),
+                ? indent(print("trueExpr"))
+                : print("trueExpr"),
               line,
             ]
           : "",
@@ -2709,7 +2670,7 @@ function printNode(path, options, print) {
       ];
       const breakClosingParens = breakLookupNodes.includes(pureParent.kind);
 
-      const printedTest = path.call(print, "test");
+      const printedTest = print("test");
 
       if (!node.trueExpr) {
         const printed = [
@@ -2818,7 +2779,7 @@ function printNode(path, options, print) {
           ? "}"
           : "";
 
-      return [open, path.call(print, "expression"), close];
+      return [open, print("expression"), close];
     }
     case "encapsed":
       switch (node.type) {
@@ -2866,7 +2827,7 @@ function printNode(path, options, print) {
     case "name":
       return [node.resolution === "rn" ? "namespace\\" : "", node.name];
     case "literal":
-      return path.call(print, "value");
+      return print("value");
     case "parentreference":
       return "parent";
     case "selfreference":
@@ -2884,7 +2845,7 @@ function printNode(path, options, print) {
         node.name = normalizeMagicMethodName(node.name);
       }
 
-      return path.call(print, "name");
+      return print("name");
     }
     case "match": {
       const lastArmIndex = node.arms.length - 1;
@@ -2914,7 +2875,7 @@ function printNode(path, options, print) {
                   [",", line, print(condPath)].slice(condIdx === 0 ? 2 : 0),
                 "conds"
               );
-        const body = armPath.call(print, "body");
+        const body = print("body");
         const maybeEmptyLineBetweenArms =
           armIdx > 0 &&
           isPreviousLineEmpty(options.originalText, armNode, options)
@@ -2937,7 +2898,7 @@ function printNode(path, options, print) {
       }, "arms");
       return group([
         "match (",
-        group([softline, indent(path.call(print, "cond")), softline]),
+        group([softline, indent(print("cond")), softline]),
         ") {",
         group(indent([...arms])),
         " ",
@@ -2951,19 +2912,19 @@ function printNode(path, options, print) {
         ? comments.printComments(path.getValue().comments, options)
         : "";
     case "namedargument":
-      return [node.name, ": ", path.call(print, "value")];
+      return [node.name, ": ", print("value")];
 
     case "enumcase":
       return group([
         "case ",
-        path.call(print, "name"),
+        print("name"),
         node.value
           ? [
               " =",
               printAssignmentRight(
                 node.name,
                 node.value,
-                path.call(print, "value"),
+                print("value"),
                 false,
                 options
               ),
diff --git a/yarn.lock b/yarn.lock
index 08053a4..a9c8a96 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2450,11 +2450,6 @@ combined-stream@^1.0.8:
   dependencies:
     delayed-stream "~1.0.0"
 
-command-exists@^1.2.9:
-  version "1.2.9"
-  resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69"
-  integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==
-
 commander@^2.20.0:
   version "2.20.3"
   resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@@ -5979,14 +5974,6 @@ yargs@^17.3.1:
     y18n "^5.0.5"
     yargs-parser "^21.0.0"
 
-yarpm@^1.1.1:
-  version "1.2.0"
-  resolved "https://registry.yarnpkg.com/yarpm/-/yarpm-1.2.0.tgz#5baaf5589f6237426cf76f812296dcf9b4254f55"
-  integrity sha512-gxN4Ali09uey8EpLfbYG+bTXf1hF6TA5oAXFPpKi5Nt5aztXU9AIEksXE0lpuvC50vL4De/KIeP8JXgYOZ8KbQ==
-  dependencies:
-    command-exists "^1.2.9"
-    cross-spawn "^7.0.3"
-
 yocto-queue@^0.1.0:
   version "0.1.0"
   resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"


Test patch:
diff --git a/tests/array/jsfmt.spec.js b/tests/array/jsfmt.spec.js
index 3073bc6..d43490a 100644
--- a/tests/array/jsfmt.spec.js
+++ b/tests/array/jsfmt.spec.js
@@ -1,2 +1,2 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { phpVersion: "5.3" });
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { phpVersion: "5.3" });
diff --git a/tests/arrowfunc/jsfmt.spec.js b/tests/arrowfunc/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/arrowfunc/jsfmt.spec.js
+++ b/tests/arrowfunc/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/assign/jsfmt.spec.js b/tests/assign/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/assign/jsfmt.spec.js
+++ b/tests/assign/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/assignref/jsfmt.spec.js b/tests/assignref/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/assignref/jsfmt.spec.js
+++ b/tests/assignref/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/attributes-trail-comma/jsfmt.spec.js b/tests/attributes-trail-comma/jsfmt.spec.js
index 8fd98a9..b6511ba 100644
--- a/tests/attributes-trail-comma/jsfmt.spec.js
+++ b/tests/attributes-trail-comma/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { trailingCommaPHP: true, phpVersion: "8.0" });
+run_spec(import.meta, ["php"], { trailingCommaPHP: true, phpVersion: "8.0" });
diff --git a/tests/attributes/jsfmt.spec.js b/tests/attributes/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/attributes/jsfmt.spec.js
+++ b/tests/attributes/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/bin/jsfmt.spec.js b/tests/bin/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/bin/jsfmt.spec.js
+++ b/tests/bin/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/block/jsfmt.spec.js b/tests/block/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/block/jsfmt.spec.js
+++ b/tests/block/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/boolean/jsfmt.spec.js b/tests/boolean/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/boolean/jsfmt.spec.js
+++ b/tests/boolean/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/brace-style/jsfmt.spec.js b/tests/brace-style/jsfmt.spec.js
index 09a6fcb..8ac8c68 100644
--- a/tests/brace-style/jsfmt.spec.js
+++ b/tests/brace-style/jsfmt.spec.js
@@ -1,4 +1,4 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { braceStyle: "psr-2" });
-run_spec(__dirname, ["php"], { braceStyle: "per-cs" });
-run_spec(__dirname, ["php"], { braceStyle: "1tbs" });
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { braceStyle: "psr-2" });
+run_spec(import.meta, ["php"], { braceStyle: "per-cs" });
+run_spec(import.meta, ["php"], { braceStyle: "1tbs" });
diff --git a/tests/break/jsfmt.spec.js b/tests/break/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/break/jsfmt.spec.js
+++ b/tests/break/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/call/jsfmt.spec.js b/tests/call/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/call/jsfmt.spec.js
+++ b/tests/call/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/case/jsfmt.spec.js b/tests/case/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/case/jsfmt.spec.js
+++ b/tests/case/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/cast/jsfmt.spec.js b/tests/cast/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/cast/jsfmt.spec.js
+++ b/tests/cast/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/class/jsfmt.spec.js b/tests/class/jsfmt.spec.js
index 5378de1..4d43d0c 100644
--- a/tests/class/jsfmt.spec.js
+++ b/tests/class/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
 // see https://github.com/prettier/plugin-php/issues/107
-// run_spec(__dirname, ["php"], { openingBraceNewLine: false });
+// run_spec(import.meta, ["php"], { openingBraceNewLine: false });
diff --git a/tests/classconstant/jsfmt.spec.js b/tests/classconstant/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/classconstant/jsfmt.spec.js
+++ b/tests/classconstant/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/clone/jsfmt.spec.js b/tests/clone/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/clone/jsfmt.spec.js
+++ b/tests/clone/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/closure/jsfmt.spec.js b/tests/closure/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/closure/jsfmt.spec.js
+++ b/tests/closure/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/comments/jsfmt.spec.js b/tests/comments/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/comments/jsfmt.spec.js
+++ b/tests/comments/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/constant/jsfmt.spec.js b/tests/constant/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/constant/jsfmt.spec.js
+++ b/tests/constant/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/continue/jsfmt.spec.js b/tests/continue/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/continue/jsfmt.spec.js
+++ b/tests/continue/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/declare/jsfmt.spec.js b/tests/declare/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/declare/jsfmt.spec.js
+++ b/tests/declare/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/do/jsfmt.spec.js b/tests/do/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/do/jsfmt.spec.js
+++ b/tests/do/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/echo/jsfmt.spec.js b/tests/echo/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/echo/jsfmt.spec.js
+++ b/tests/echo/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/empty/jsfmt.spec.js b/tests/empty/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/empty/jsfmt.spec.js
+++ b/tests/empty/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/encapsed/jsfmt.spec.js b/tests/encapsed/jsfmt.spec.js
index e2d8198..5279179 100644
--- a/tests/encapsed/jsfmt.spec.js
+++ b/tests/encapsed/jsfmt.spec.js
@@ -1,2 +1,2 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { phpVersion: "7.3" });
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { phpVersion: "7.3" });
diff --git a/tests/enum/jsfmt.spec.js b/tests/enum/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/enum/jsfmt.spec.js
+++ b/tests/enum/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/errors/jsfmt.spec.js b/tests/errors/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/errors/jsfmt.spec.js
+++ b/tests/errors/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/eval/jsfmt.spec.js b/tests/eval/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/eval/jsfmt.spec.js
+++ b/tests/eval/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/exit/jsfmt.spec.js b/tests/exit/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/exit/jsfmt.spec.js
+++ b/tests/exit/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/extensions/jsfmt.spec.js b/tests/extensions/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/extensions/jsfmt.spec.js
+++ b/tests/extensions/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/for/jsfmt.spec.js b/tests/for/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/for/jsfmt.spec.js
+++ b/tests/for/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/foreach/jsfmt.spec.js b/tests/foreach/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/foreach/jsfmt.spec.js
+++ b/tests/foreach/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/formatting/jsfmt.spec.js b/tests/formatting/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/formatting/jsfmt.spec.js
+++ b/tests/formatting/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/functions/jsfmt.spec.js b/tests/functions/jsfmt.spec.js
index 5378de1..4d43d0c 100644
--- a/tests/functions/jsfmt.spec.js
+++ b/tests/functions/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
 // see https://github.com/prettier/plugin-php/issues/107
-// run_spec(__dirname, ["php"], { openingBraceNewLine: false });
+// run_spec(import.meta, ["php"], { openingBraceNewLine: false });
diff --git a/tests/global/jsfmt.spec.js b/tests/global/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/global/jsfmt.spec.js
+++ b/tests/global/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/goto/jsfmt.spec.js b/tests/goto/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/goto/jsfmt.spec.js
+++ b/tests/goto/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/halt/jsfmt.spec.js b/tests/halt/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/halt/jsfmt.spec.js
+++ b/tests/halt/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/identifier-and-reference/jsfmt.spec.js b/tests/identifier-and-reference/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/identifier-and-reference/jsfmt.spec.js
+++ b/tests/identifier-and-reference/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/if/jsfmt.spec.js b/tests/if/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/if/jsfmt.spec.js
+++ b/tests/if/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/ignore/jsfmt.spec.js b/tests/ignore/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/ignore/jsfmt.spec.js
+++ b/tests/ignore/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/include/jsfmt.spec.js b/tests/include/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/include/jsfmt.spec.js
+++ b/tests/include/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/inline/jsfmt.spec.js b/tests/inline/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/inline/jsfmt.spec.js
+++ b/tests/inline/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/insert-pragma/jsfmt.spec.js b/tests/insert-pragma/jsfmt.spec.js
index 1a328b6..c1683e7 100644
--- a/tests/insert-pragma/jsfmt.spec.js
+++ b/tests/insert-pragma/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"], { insertPragma: true, endOfLine: "cr" });
-run_spec(__dirname, ["php"], { insertPragma: true, endOfLine: "crlf" });
-run_spec(__dirname, ["php"], { insertPragma: true, endOfLine: "lf" });
+run_spec(import.meta, ["php"], { insertPragma: true, endOfLine: "cr" });
+run_spec(import.meta, ["php"], { insertPragma: true, endOfLine: "crlf" });
+run_spec(import.meta, ["php"], { insertPragma: true, endOfLine: "lf" });
diff --git a/tests/interface/jsfmt.spec.js b/tests/interface/jsfmt.spec.js
index 5378de1..4d43d0c 100644
--- a/tests/interface/jsfmt.spec.js
+++ b/tests/interface/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
 // see https://github.com/prettier/plugin-php/issues/107
-// run_spec(__dirname, ["php"], { openingBraceNewLine: false });
+// run_spec(import.meta, ["php"], { openingBraceNewLine: false });
diff --git a/tests/intersection-types/jsfmt.spec.js b/tests/intersection-types/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/intersection-types/jsfmt.spec.js
+++ b/tests/intersection-types/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/isset/jsfmt.spec.js b/tests/isset/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/isset/jsfmt.spec.js
+++ b/tests/isset/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/kitchen_sink/jsfmt.spec.js b/tests/kitchen_sink/jsfmt.spec.js
index 2e19653..efafeca 100644
--- a/tests/kitchen_sink/jsfmt.spec.js
+++ b/tests/kitchen_sink/jsfmt.spec.js
@@ -1,2 +1,2 @@
-run_spec(__dirname, ["php"]);
-// run_spec(__dirname, ["php"], { openingBraceNewLine: false });
+run_spec(import.meta, ["php"]);
+// run_spec(import.meta, ["php"], { openingBraceNewLine: false });
diff --git a/tests/list/jsfmt.spec.js b/tests/list/jsfmt.spec.js
index 935da65..c0ec8a1 100644
--- a/tests/list/jsfmt.spec.js
+++ b/tests/list/jsfmt.spec.js
@@ -1,2 +1,2 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { phpVersion: "7.1" });
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { phpVersion: "7.1" });
diff --git a/tests/magic/jsfmt.spec.js b/tests/magic/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/magic/jsfmt.spec.js
+++ b/tests/magic/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/markdown/jsfmt.spec.js b/tests/markdown/jsfmt.spec.js
index 4503e4a..6c89822 100644
--- a/tests/markdown/jsfmt.spec.js
+++ b/tests/markdown/jsfmt.spec.js
@@ -1,4 +1,4 @@
-run_spec(__dirname, ["markdown"], {
+run_spec(import.meta, ["markdown"], {
   plugins: global.STANDALONE ? [require("prettier/parser-markdown")] : [],
   proseWrap: "always",
   tabWidth: 4,
diff --git a/tests/match/jsfmt.spec.js b/tests/match/jsfmt.spec.js
index c3743e7..97399d8 100644
--- a/tests/match/jsfmt.spec.js
+++ b/tests/match/jsfmt.spec.js
@@ -1,8 +1,8 @@
-run_spec(__dirname, ["php"], {
+run_spec(import.meta, ["php"], {
   trailingCommaPHP: false,
   phpVersion: "8.0",
 });
-run_spec(__dirname, ["php"], {
+run_spec(import.meta, ["php"], {
   trailingCommaPHP: true,
   phpVersion: "8.0",
 });
diff --git a/tests/member_chain/jsfmt.spec.js b/tests/member_chain/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/member_chain/jsfmt.spec.js
+++ b/tests/member_chain/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/method/jsfmt.spec.js b/tests/method/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/method/jsfmt.spec.js
+++ b/tests/method/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/namedarguments/jsfmt.spec.js b/tests/namedarguments/jsfmt.spec.js
index cc78763..d22c24d 100644
--- a/tests/namedarguments/jsfmt.spec.js
+++ b/tests/namedarguments/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { phpVersion: "8.0" });
+run_spec(import.meta, ["php"], { phpVersion: "8.0" });
diff --git a/tests/namespace/jsfmt.spec.js b/tests/namespace/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/namespace/jsfmt.spec.js
+++ b/tests/namespace/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/new/jsfmt.spec.js b/tests/new/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/new/jsfmt.spec.js
+++ b/tests/new/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/newline/jsfmt.spec.js b/tests/newline/jsfmt.spec.js
index e79d21a..4096c5d 100644
--- a/tests/newline/jsfmt.spec.js
+++ b/tests/newline/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"], { endOfLine: "cr" });
-run_spec(__dirname, ["php"], { endOfLine: "crlf" });
-run_spec(__dirname, ["php"], { endOfLine: "lf" });
+run_spec(import.meta, ["php"], { endOfLine: "cr" });
+run_spec(import.meta, ["php"], { endOfLine: "crlf" });
+run_spec(import.meta, ["php"], { endOfLine: "lf" });
diff --git a/tests/nowdoc/jsfmt.spec.js b/tests/nowdoc/jsfmt.spec.js
index e2d8198..5279179 100644
--- a/tests/nowdoc/jsfmt.spec.js
+++ b/tests/nowdoc/jsfmt.spec.js
@@ -1,2 +1,2 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { phpVersion: "7.3" });
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { phpVersion: "7.3" });
diff --git a/tests/nullsafepropertylookup/jsfmt.spec.js b/tests/nullsafepropertylookup/jsfmt.spec.js
index cc78763..d22c24d 100644
--- a/tests/nullsafepropertylookup/jsfmt.spec.js
+++ b/tests/nullsafepropertylookup/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { phpVersion: "8.0" });
+run_spec(import.meta, ["php"], { phpVersion: "8.0" });
diff --git a/tests/number/jsfmt.spec.js b/tests/number/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/number/jsfmt.spec.js
+++ b/tests/number/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/offsetlookup/jsfmt.spec.js b/tests/offsetlookup/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/offsetlookup/jsfmt.spec.js
+++ b/tests/offsetlookup/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/package.json b/tests/package.json
new file mode 100644
index 0000000..0038dff
--- /dev/null
+++ b/tests/package.json
@@ -0,0 +1,5 @@
+{
+  "//": "Remove this file after we migrate to ESM.",
+  "description": "Make Node.js treat .js files in this directory as module",
+  "type": "module"
+}
diff --git a/tests/parameter/jsfmt.spec.js b/tests/parameter/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/parameter/jsfmt.spec.js
+++ b/tests/parameter/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/parens/jsfmt.spec.js b/tests/parens/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/parens/jsfmt.spec.js
+++ b/tests/parens/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/preserve_line/jsfmt.spec.js b/tests/preserve_line/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/preserve_line/jsfmt.spec.js
+++ b/tests/preserve_line/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/print/jsfmt.spec.js b/tests/print/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/print/jsfmt.spec.js
+++ b/tests/print/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/program/jsfmt.spec.js b/tests/program/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/program/jsfmt.spec.js
+++ b/tests/program/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/property/jsfmt.spec.js b/tests/property/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/property/jsfmt.spec.js
+++ b/tests/property/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/propertylookup/jsfmt.spec.js b/tests/propertylookup/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/propertylookup/jsfmt.spec.js
+++ b/tests/propertylookup/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/propertystatement/jsfmt.spec.js b/tests/propertystatement/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/propertystatement/jsfmt.spec.js
+++ b/tests/propertystatement/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/require-pragma/jsfmt.spec.js b/tests/require-pragma/jsfmt.spec.js
index cbd3dbf..78361cf 100644
--- a/tests/require-pragma/jsfmt.spec.js
+++ b/tests/require-pragma/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"], { requirePragma: true, endOfLine: "cr" });
-run_spec(__dirname, ["php"], { requirePragma: true, endOfLine: "crlf" });
-run_spec(__dirname, ["php"], { requirePragma: true, endOfLine: "lf" });
+run_spec(import.meta, ["php"], { requirePragma: true, endOfLine: "cr" });
+run_spec(import.meta, ["php"], { requirePragma: true, endOfLine: "crlf" });
+run_spec(import.meta, ["php"], { requirePragma: true, endOfLine: "lf" });
diff --git a/tests/retif/jsfmt.spec.js b/tests/retif/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/retif/jsfmt.spec.js
+++ b/tests/retif/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/return/jsfmt.spec.js b/tests/return/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/return/jsfmt.spec.js
+++ b/tests/return/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/shebang/jsfmt.spec.js b/tests/shebang/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/shebang/jsfmt.spec.js
+++ b/tests/shebang/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/silent/jsfmt.spec.js b/tests/silent/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/silent/jsfmt.spec.js
+++ b/tests/silent/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/statement/jsfmt.spec.js b/tests/statement/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/statement/jsfmt.spec.js
+++ b/tests/statement/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/static/jsfmt.spec.js b/tests/static/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/static/jsfmt.spec.js
+++ b/tests/static/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/staticlookup/jsfmt.spec.js b/tests/staticlookup/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/staticlookup/jsfmt.spec.js
+++ b/tests/staticlookup/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/string-double-quote/jsfmt.spec.js b/tests/string-double-quote/jsfmt.spec.js
index 9b730dc..de55502 100644
--- a/tests/string-double-quote/jsfmt.spec.js
+++ b/tests/string-double-quote/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { singleQuote: false });
+run_spec(import.meta, ["php"], { singleQuote: false });
diff --git a/tests/string-single-quote/jsfmt.spec.js b/tests/string-single-quote/jsfmt.spec.js
index 251ce04..cfd1c79 100644
--- a/tests/string-single-quote/jsfmt.spec.js
+++ b/tests/string-single-quote/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { singleQuote: true });
+run_spec(import.meta, ["php"], { singleQuote: true });
diff --git a/tests/string/jsfmt.spec.js b/tests/string/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/string/jsfmt.spec.js
+++ b/tests/string/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/switch/jsfmt.spec.js b/tests/switch/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/switch/jsfmt.spec.js
+++ b/tests/switch/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/syntax-error/jsfmt.spec.js b/tests/syntax-error/jsfmt.spec.js
index 11b12c3..b712c6c 100644
--- a/tests/syntax-error/jsfmt.spec.js
+++ b/tests/syntax-error/jsfmt.spec.js
@@ -1,5 +1,5 @@
-const { prettier, plugin } = require("../../tests_config/get_engine");
-const stripAnsi = require("strip-ansi");
+import { prettier, plugin } from "../../tests_config/get_engine.js";
+import stripAnsi from "strip-ansi";
 
 async function raiseSyntaxError() {
   await prettier.format(`<?php _`, {
diff --git a/tests/sys/jsfmt.spec.js b/tests/sys/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/sys/jsfmt.spec.js
+++ b/tests/sys/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/trailing_comma_func/jsfmt.spec.js b/tests/trailing_comma_func/jsfmt.spec.js
index 69ee3aa..77f5693 100644
--- a/tests/trailing_comma_func/jsfmt.spec.js
+++ b/tests/trailing_comma_func/jsfmt.spec.js
@@ -1,9 +1,9 @@
-run_spec(__dirname, ["php"], {
+run_spec(import.meta, ["php"], {
   trailingComma: "all",
   trailingCommaPHP: false,
   phpVersion: "8.0",
 });
-run_spec(__dirname, ["php"], {
+run_spec(import.meta, ["php"], {
   trailingComma: "none",
   trailingCommaPHP: true,
   phpVersion: "8.0",
diff --git a/tests/trailing_commas/jsfmt.spec.js b/tests/trailing_commas/jsfmt.spec.js
index 6658b8a..695bbbc 100644
--- a/tests/trailing_commas/jsfmt.spec.js
+++ b/tests/trailing_commas/jsfmt.spec.js
@@ -1,8 +1,8 @@
-run_spec(__dirname, ["php"]);
-run_spec(__dirname, ["php"], { trailingCommaPHP: true, phpVersion: "5.0" });
-run_spec(__dirname, ["php"], { trailingCommaPHP: true, phpVersion: "7.2" });
-run_spec(__dirname, ["php"], { trailingCommaPHP: true, phpVersion: "7.3" });
-run_spec(__dirname, ["php"], {
+run_spec(import.meta, ["php"]);
+run_spec(import.meta, ["php"], { trailingCommaPHP: true, phpVersion: "5.0" });
+run_spec(import.meta, ["php"], { trailingCommaPHP: true, phpVersion: "7.2" });
+run_spec(import.meta, ["php"], { trailingCommaPHP: true, phpVersion: "7.3" });
+run_spec(import.meta, ["php"], {
   trailingCommaPHP: false,
   trailingComma: "all",
 });
diff --git a/tests/trailing_whitespace/jsfmt.spec.js b/tests/trailing_whitespace/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/trailing_whitespace/jsfmt.spec.js
+++ b/tests/trailing_whitespace/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/traitalias/jsfmt.spec.js b/tests/traitalias/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/traitalias/jsfmt.spec.js
+++ b/tests/traitalias/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/traits/jsfmt.spec.js b/tests/traits/jsfmt.spec.js
index 5378de1..4d43d0c 100644
--- a/tests/traits/jsfmt.spec.js
+++ b/tests/traits/jsfmt.spec.js
@@ -1,3 +1,3 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
 // see https://github.com/prettier/plugin-php/issues/107
-// run_spec(__dirname, ["php"], { openingBraceNewLine: false });
+// run_spec(import.meta, ["php"], { openingBraceNewLine: false });
diff --git a/tests/traituse/jsfmt.spec.js b/tests/traituse/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/traituse/jsfmt.spec.js
+++ b/tests/traituse/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/uniontypes/jsfmt.spec.js b/tests/uniontypes/jsfmt.spec.js
index cc78763..d22c24d 100644
--- a/tests/uniontypes/jsfmt.spec.js
+++ b/tests/uniontypes/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"], { phpVersion: "8.0" });
+run_spec(import.meta, ["php"], { phpVersion: "8.0" });
diff --git a/tests/unset/jsfmt.spec.js b/tests/unset/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/unset/jsfmt.spec.js
+++ b/tests/unset/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/use/jsfmt.spec.js b/tests/use/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/use/jsfmt.spec.js
+++ b/tests/use/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/variable/jsfmt.spec.js b/tests/variable/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/variable/jsfmt.spec.js
+++ b/tests/variable/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/variadic/jsfmt.spec.js b/tests/variadic/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/variadic/jsfmt.spec.js
+++ b/tests/variadic/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/while/jsfmt.spec.js b/tests/while/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/while/jsfmt.spec.js
+++ b/tests/while/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests/yield/jsfmt.spec.js b/tests/yield/jsfmt.spec.js
index e395434..8829c87 100644
--- a/tests/yield/jsfmt.spec.js
+++ b/tests/yield/jsfmt.spec.js
@@ -1,1 +1,1 @@
-run_spec(__dirname, ["php"]);
+run_spec(import.meta, ["php"]);
diff --git a/tests_config/get_engine.js b/tests_config/get_engine.js
index a37d0cb..cef2790 100644
--- a/tests_config/get_engine.js
+++ b/tests_config/get_engine.js
@@ -1,11 +1,14 @@
-"use strict";
+import path from "path";
+import url from "url";
+import { createRequire } from "module";
 
-const path = require("path");
+const require = createRequire(import.meta.url);
+const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
 
-if (global.STANDALONE) {
-  exports.prettier = require("prettier/standalone");
-  exports.plugin = require(path.join(__dirname, "..", "standalone.js"));
-} else {
-  exports.prettier = require("prettier");
-  exports.plugin = require(path.join(__dirname, ".."));
-}
+// TODO: Use ESM version
+export const prettier = require(global.STANDALONE
+  ? "prettier/standalone"
+  : "prettier");
+export const plugin = require(global.STANDALONE
+  ? path.join(__dirname, "../standalone.js")
+  : path.join(__dirname, ".."));
diff --git a/tests_config/package.json b/tests_config/package.json
new file mode 100644
index 0000000..0038dff
--- /dev/null
+++ b/tests_config/package.json
@@ -0,0 +1,5 @@
+{
+  "//": "Remove this file after we migrate to ESM.",
+  "description": "Make Node.js treat .js files in this directory as module",
+  "type": "module"
+}
diff --git a/tests_config/run_spec.js b/tests_config/run_spec.js
index 7fdbea8..b63e802 100644
--- a/tests_config/run_spec.js
+++ b/tests_config/run_spec.js
@@ -1,8 +1,8 @@
-"use strict";
-
-const fs = require("fs");
-const path = require("path");
-const raw = require("jest-snapshot-serializer-raw").wrap;
+import fs from "fs";
+import path from "path";
+import url from "url";
+import { wrap as raw } from "jest-snapshot-serializer-raw";
+import { prettier, plugin } from "./get_engine.js";
 
 const { AST_COMPARE, TEST_CRLF } = process.env;
 
@@ -10,9 +10,9 @@ const CURSOR_PLACEHOLDER = "<|>";
 const RANGE_START_PLACEHOLDER = "<<<PRETTIER_RANGE_START>>>";
 const RANGE_END_PLACEHOLDER = "<<<PRETTIER_RANGE_END>>>";
 
-const { prettier, plugin } = require("./get_engine");
+global.run_spec = (importMeta, parsers, options) => {
+  const dirname = path.dirname(url.fileURLToPath(importMeta.url));
 
-global.run_spec = (dirname, parsers, options) => {
   options = Object.assign({}, options, {
     plugins: [plugin, ...((options && options.plugins) || [])],
   });