From 91f859979a1fda78c00996d30c42b36064c6b36b Mon Sep 17 00:00:00 2001 From: Hiroshi Ogawa Date: Tue, 17 Sep 2024 14:45:02 +0900 Subject: [PATCH] fix(vite-node): fix esm false-detection inside comment (#6506) --- packages/vite-node/src/externalize.ts | 5 ++++- pnpm-lock.yaml | 8 ++++++++ test/core/deps/dep-esm-comment/index.js | 6 ++++++ test/core/deps/dep-esm-comment/package.json | 5 +++++ test/core/package.json | 1 + test/core/test/dual-package-hazard.test.ts | 11 +++++++++++ 6 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 test/core/deps/dep-esm-comment/index.js create mode 100644 test/core/deps/dep-esm-comment/package.json diff --git a/packages/vite-node/src/externalize.ts b/packages/vite-node/src/externalize.ts index 47abaefa27d9..567f3bfedfcc 100644 --- a/packages/vite-node/src/externalize.ts +++ b/packages/vite-node/src/externalize.ts @@ -11,6 +11,9 @@ const ESM_SYNTAX_RE const ESM_EXT_RE = /\.(es|esm|esm-browser|esm-bundler|es6|module)\.js$/ const ESM_FOLDER_RE = /\/(es|esm)\/(.*\.js)$/ +// https://stackoverflow.com/a/15123777 +const COMMENT_RE = /\/\*[\s\S]*?\*\/|([^\\:]|^)\/\/.*$/gm + const defaultInline = [ /virtual:/, /\.[mc]?ts$/, @@ -79,7 +82,7 @@ async function isValidNodeImport(id: string) { const code = await fsp.readFile(id, 'utf8').catch(() => '') - return !ESM_SYNTAX_RE.test(code) + return !ESM_SYNTAX_RE.test(code.replace(COMMENT_RE, '')) } const _defaultExternalizeCache = new Map>() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0e2e710c60cd..e09dbd5da3ff 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1229,6 +1229,9 @@ importers: '@vitest/runner': specifier: workspace:* version: link:../../packages/runner + '@vitest/test-dep-esm-comment': + specifier: file:./deps/dep-esm-comment + version: file:test/core/deps/dep-esm-comment '@vitest/test-dep1': specifier: file:./deps/dep1 version: file:test/core/deps/dep1 @@ -4035,6 +4038,9 @@ packages: '@vitest/pretty-format@2.0.5': resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + '@vitest/test-dep-esm-comment@file:test/core/deps/dep-esm-comment': + resolution: {directory: test/core/deps/dep-esm-comment, type: directory} + '@vitest/test-dep1@file:test/core/deps/dep1': resolution: {directory: test/core/deps/dep1, type: directory} @@ -12537,6 +12543,8 @@ snapshots: dependencies: tinyrainbow: 1.2.0 + '@vitest/test-dep-esm-comment@file:test/core/deps/dep-esm-comment': {} + '@vitest/test-dep1@file:test/core/deps/dep1': {} '@vitest/test-dep2@file:test/core/deps/dep2': diff --git a/test/core/deps/dep-esm-comment/index.js b/test/core/deps/dep-esm-comment/index.js new file mode 100644 index 000000000000..ff2b92607f33 --- /dev/null +++ b/test/core/deps/dep-esm-comment/index.js @@ -0,0 +1,6 @@ +// import x from "x" +/** import x from "x" */ +/** + * import x from "x" + */ +module.exports = { test: 'ok' } diff --git a/test/core/deps/dep-esm-comment/package.json b/test/core/deps/dep-esm-comment/package.json new file mode 100644 index 000000000000..5aa6a8a793e0 --- /dev/null +++ b/test/core/deps/dep-esm-comment/package.json @@ -0,0 +1,5 @@ +{ + "name": "@vitest/test-dep-esm-comment", + "type": "commonjs", + "exports": "./index.js" +} diff --git a/test/core/package.json b/test/core/package.json index 59de88e33c36..b3ce1e84b146 100644 --- a/test/core/package.json +++ b/test/core/package.json @@ -16,6 +16,7 @@ "@vitest/expect": "workspace:*", "@vitest/mocker": "workspace:*", "@vitest/runner": "workspace:*", + "@vitest/test-dep-esm-comment": "file:./deps/dep-esm-comment", "@vitest/test-dep1": "file:./deps/dep1", "@vitest/test-dep2": "file:./deps/dep2", "@vitest/utils": "workspace:*", diff --git a/test/core/test/dual-package-hazard.test.ts b/test/core/test/dual-package-hazard.test.ts index f751e594d877..54d09c57a128 100644 --- a/test/core/test/dual-package-hazard.test.ts +++ b/test/core/test/dual-package-hazard.test.ts @@ -1,3 +1,4 @@ +import { createRequire } from 'node:module' import { expect, test } from 'vitest' // @ts-expect-error no ts @@ -6,7 +7,17 @@ import * as dep1 from '@vitest/test-dep1' // @ts-expect-error no ts import * as dep2 from '@vitest/test-dep2' +// @ts-expect-error no ts +import depEsmComment from '@vitest/test-dep-esm-comment' + +const require = createRequire(import.meta.url) + test('no dual package hazard by externalizing esm deps by default', async () => { dep1.data.hello = 'world' expect(dep2.data.hello).toBe('world') }) + +test('externalize cjs with esm comment', async () => { + const depEsmCommentRequire = require('@vitest/test-dep-esm-comment') + expect(depEsmComment).toBe(depEsmCommentRequire) +})