From 9d18c319c12c01f7f2bf38210db40dbeacaa3b0c Mon Sep 17 00:00:00 2001 From: Vincent Driessen Date: Wed, 5 Jul 2023 12:14:59 +0200 Subject: [PATCH] Don't enforce `module` to precede `import` per se (#50) --- pkg/index.d.ts | 5 +---- pkg/src/index.js | 37 +++++++++++++------------------------ pkg/src/message.js | 10 ++-------- pkg/tests/playground.js | 2 +- site/rules.md | 4 ++-- site/src/utils/message.js | 10 ++-------- 6 files changed, 21 insertions(+), 47 deletions(-) diff --git a/pkg/index.d.ts b/pkg/index.d.ts index 880c0cb..cc9a9f3 100644 --- a/pkg/index.d.ts +++ b/pkg/index.d.ts @@ -58,10 +58,7 @@ export type Message = } > | BaseMessage<'EXPORTS_TYPES_SHOULD_BE_FIRST'> - | BaseMessage< - 'EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE', - { conditions: string[] } - > + | BaseMessage<'EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE'> | BaseMessage<'EXPORTS_DEFAULT_SHOULD_BE_LAST'> | BaseMessage<'EXPORTS_MODULE_SHOULD_BE_ESM'> | BaseMessage<'EXPORTS_VALUE_INVALID', { suggestValue: string }> diff --git a/pkg/src/index.js b/pkg/src/index.js index 2e7069e..92ec0c1 100755 --- a/pkg/src/index.js +++ b/pkg/src/index.js @@ -493,30 +493,19 @@ export async function publint({ pkgDir, vfs, level, strict, _packedFiles }) { } } - // a 'module' export should always precede 'import' or 'require' - if ('module' in exports) { - const conditions = [] - if ( - 'require' in exports && - exportsKeys.indexOf('module') > exportsKeys.indexOf('require') - ) { - conditions.push('require') - } - if ( - 'import' in exports && - exportsKeys.indexOf('module') > exportsKeys.indexOf('import') - ) { - conditions.push('import') - } - - if (conditions.length > 0) { - messages.push({ - code: 'EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE', - args: { conditions }, - path: currentPath.concat('module'), - type: 'error' - }) - } + // if there is a 'require' and a 'module' condition at the same level, + // then 'module' should always precede 'require' + if ( + 'module' in exports && + 'require' in exports && + exportsKeys.indexOf('module') > exportsKeys.indexOf('require') + ) { + messages.push({ + code: 'EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE', + args: {}, + path: currentPath.concat('module'), + type: 'error' + }) } // the default export should be the last condition diff --git a/pkg/src/message.js b/pkg/src/message.js index de996c5..8a6879c 100644 --- a/pkg/src/message.js +++ b/pkg/src/message.js @@ -56,15 +56,9 @@ export function printMessage(m, pkg) { case 'EXPORTS_TYPES_SHOULD_BE_FIRST': // prettier-ignore return `${c.bold(fp(m.path))} should be the first in the object as required by TypeScript.` - case 'EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE': { - let conditions = `the ${m.args.conditions - .map((cond) => `"${c.bold(cond)}"`) - .join(' and ')} condition` - if (m.args.conditions.length !== 1) { - conditions += 's' - } + case 'EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE': { // prettier-ignore - return `${c.bold(fp(m.path))} should come before ${conditions} so it can take precedence when used by a bundler.` + return `${c.bold(fp(m.path))} should come before the "require" condition so it can take precedence when used by a bundler.` } case 'EXPORTS_DEFAULT_SHOULD_BE_LAST': // prettier-ignore diff --git a/pkg/tests/playground.js b/pkg/tests/playground.js index 4e7229f..87c1071 100644 --- a/pkg/tests/playground.js +++ b/pkg/tests/playground.js @@ -28,7 +28,7 @@ testFixture('missing-files', [ testFixture('no-exports-module', []) -testFixture('exports-module', ['EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE']) +testFixture('exports-module', ['EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE']) testFixture('publish-config', ['USE_EXPORTS_BROWSER', 'FILE_DOES_NOT_EXIST']) diff --git a/site/rules.md b/site/rules.md index 3c4bf6e..72bc5a3 100644 --- a/site/rules.md +++ b/site/rules.md @@ -57,9 +57,9 @@ If the `"exports"` field contains glob paths, but it doesn't match any files, re The `"exports"` field should not have globs defined with trailing slashes. It is [deprecated](https://nodejs.org/docs/latest-v16.x/api/packages.html#subpath-folder-mappings) and should use [subpath patterns](https://nodejs.org/api/packages.html#subpath-patterns), e.g. a trailing `/*` instead. -## `EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE` +## `EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE` -Ensure the `"module"` condition comes before the `"import"` and `"require"` conditions. Due to the way conditions are matched top-to-bottom, the `"module"` condition (used in bundler contexts only) must come before an `"import"` or `"require"` condition, so it has the opportunity to take precedence. +Ensure the `"module"` condition comes before the `"require"` condition. Due to the way conditions are matched top-to-bottom, the `"module"` condition (used in bundler contexts only) must come before a `"require"` condition, so it has the opportunity to take precedence. ## `EXPORTS_TYPES_SHOULD_BE_FIRST` diff --git a/site/src/utils/message.js b/site/src/utils/message.js index 7d39521..f02100a 100644 --- a/site/src/utils/message.js +++ b/site/src/utils/message.js @@ -62,15 +62,9 @@ function messageToString(m, pkg) { case 'EXPORTS_TYPES_SHOULD_BE_FIRST': // prettier-ignore return `Should be the first in the object as required by TypeScript.` - case 'EXPORTS_MODULE_SHOULD_PRECEDE_IMPORT_REQUIRE': { - let conditions = `the ${m.args.conditions - .map((cond) => `"${bold(cond)}"`) - .join(' and ')} condition` - if (m.args.conditions.length !== 1) { - conditions += 's' - } + case 'EXPORTS_MODULE_SHOULD_PRECEDE_REQUIRE': { // prettier-ignore - return `Should come before ${conditions} so it can take precedence when used by a bundler.` + return `Should come before the "require" condition so it can take precedence when used by a bundler.` } case 'EXPORTS_DEFAULT_SHOULD_BE_LAST': // prettier-ignore