From a35008fb0a010f92c1002ee074c6a7f3c0d8da41 Mon Sep 17 00:00:00 2001 From: fisker Cheung Date: Tue, 29 Aug 2023 16:11:43 +0800 Subject: [PATCH] Support shared config that forbids `require()` (#15233) --- changelog_unreleased/api/15233.md | 9 +++++++++ src/config/load-external-config.js | 10 ++++++---- tests/integration/__tests__/config-resolution.js | 12 ++++++++++++ .../esm-package-forbids-require/index.js | 1 + .../prettier-config-forbids-require/index.js | 1 + .../prettier-config-forbids-require/package.json | 9 +++++++++ .../esm-package-forbids-require/package.json | 3 +++ 7 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 changelog_unreleased/api/15233.md create mode 100644 tests/integration/cli/config/external-config/esm-package-forbids-require/index.js create mode 100644 tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/index.js create mode 100644 tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/package.json create mode 100644 tests/integration/cli/config/external-config/esm-package-forbids-require/package.json diff --git a/changelog_unreleased/api/15233.md b/changelog_unreleased/api/15233.md new file mode 100644 index 000000000..cd64b782f --- /dev/null +++ b/changelog_unreleased/api/15233.md @@ -0,0 +1,9 @@ +#### Support shared config that forbids `require()` (#15233 by @fisker) + +If an external shared config package is used, and the package `exports` don't have `require` or `default` export. + +In Prettier stable Prettier fails when attempt to `require()` the package, and throws an error. + +```text +Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in /package.json +``` diff --git a/src/config/load-external-config.js b/src/config/load-external-config.js index 3cba4fabb..96988a08c 100644 --- a/src/config/load-external-config.js +++ b/src/config/load-external-config.js @@ -1,6 +1,11 @@ import requireFromFile from "../utils/require-from-file.js"; import importFromFile from "../utils/import-from-file.js"; +const requireErrorCodesShouldBeIgnored = new Set([ + "MODULE_NOT_FOUND", + "ERR_REQUIRE_ESM", + "ERR_PACKAGE_PATH_NOT_EXPORTED", +]); async function loadExternalConfig(config, filepath) { /* Try `require()` first, this is how it works in Prettier v2. @@ -12,10 +17,7 @@ async function loadExternalConfig(config, filepath) { try { return requireFromFile(config, filepath); } catch (/** @type {any} */ error) { - if ( - error?.code !== "MODULE_NOT_FOUND" && - error?.code !== "ERR_REQUIRE_ESM" - ) { + if (!requireErrorCodesShouldBeIgnored.has(error?.code)) { throw error; } } diff --git a/tests/integration/__tests__/config-resolution.js b/tests/integration/__tests__/config-resolution.js index 2885bad8b..4e0cb05d0 100644 --- a/tests/integration/__tests__/config-resolution.js +++ b/tests/integration/__tests__/config-resolution.js @@ -361,3 +361,15 @@ test(".json5 config file(invalid)", async () => { const error = /JSON5: invalid end of input at 2:1/; await expect(prettier.resolveConfig(file)).rejects.toThrow(error); }); + +test("support external module with `module` only `exports`", async () => { + const directory = path.join( + __dirname, + "../cli/config/external-config/esm-package-forbids-require", + ); + const file = path.join(directory, "index.js"); + + await expect(prettier.resolveConfig(file)).resolves.toMatchObject({ + printWidth: 79, + }); +}); diff --git a/tests/integration/cli/config/external-config/esm-package-forbids-require/index.js b/tests/integration/cli/config/external-config/esm-package-forbids-require/index.js new file mode 100644 index 000000000..b4639445c --- /dev/null +++ b/tests/integration/cli/config/external-config/esm-package-forbids-require/index.js @@ -0,0 +1 @@ +console.log("should have no semi"); diff --git a/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/index.js b/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/index.js new file mode 100644 index 000000000..613d68ff3 --- /dev/null +++ b/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/index.js @@ -0,0 +1 @@ +export default { printWidth: 79 } diff --git a/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/package.json b/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/package.json new file mode 100644 index 000000000..70af1f920 --- /dev/null +++ b/tests/integration/cli/config/external-config/esm-package-forbids-require/node_modules/prettier-config-forbids-require/package.json @@ -0,0 +1,9 @@ +{ + "name": "prettier-config-forbids-require", + "private": true, + "version": "0.0.0", + "type": "module", + "exports": { + "import": "./index.js" + } +} diff --git a/tests/integration/cli/config/external-config/esm-package-forbids-require/package.json b/tests/integration/cli/config/external-config/esm-package-forbids-require/package.json new file mode 100644 index 000000000..47197b278 --- /dev/null +++ b/tests/integration/cli/config/external-config/esm-package-forbids-require/package.json @@ -0,0 +1,3 @@ +{ + "prettier": "prettier-config-forbids-require" +}