diff --git a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts index 270c810d39ffd6..c934bf538b4703 100644 --- a/packages/vite/src/node/optimizer/esbuildDepPlugin.ts +++ b/packages/vite/src/node/optimizer/esbuildDepPlugin.ts @@ -8,6 +8,7 @@ import { isBuiltin, isCSSRequest, isExternalUrl, + isNodeBuiltin, moduleListContains, normalizePath, } from '../utils' @@ -337,10 +338,10 @@ export function esbuildCjsExternalPlugin( build.onLoad( { filter: /.*/, namespace: cjsExternalFacadeNamespace }, (args) => ({ - contents: - `import * as m from ${JSON.stringify( - nonFacadePrefix + args.path, - )};` + `module.exports = { ...m };`, + contents: `\ +import * as m from ${JSON.stringify(nonFacadePrefix + args.path)}; +module.exports = ${isNodeBuiltin(args.path) ? 'm.default' : '{ ...m }'}; +`, }), ) }, diff --git a/playground/optimize-deps/__tests__/optimize-deps.spec.ts b/playground/optimize-deps/__tests__/optimize-deps.spec.ts index f9f34d50bcbb45..65260405969c8c 100644 --- a/playground/optimize-deps/__tests__/optimize-deps.spec.ts +++ b/playground/optimize-deps/__tests__/optimize-deps.spec.ts @@ -365,8 +365,11 @@ test('external package name with asset extension', async () => { ).toBe(String(isServe)) }) -test('dependency with external sub-dependency', async () => { +test('dependency with external sub-dependencies', async () => { await expectWithRetry(() => - page.textContent('.dep-cjs-with-external-dep'), + page.textContent('.dep-cjs-with-external-deps-object'), ).toBe('ok') + await expectWithRetry(() => + page.textContent('.dep-cjs-with-external-deps-node-builtin'), + ).toBe('foo bar') }) diff --git a/playground/optimize-deps/dep-cjs-with-external-dep/index.js b/playground/optimize-deps/dep-cjs-with-external-dep/index.js deleted file mode 100644 index 18b7d613194bae..00000000000000 --- a/playground/optimize-deps/dep-cjs-with-external-dep/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const external = require('@vitejs/test-dep-esm-external') -// eslint-disable-next-line no-prototype-builtins -const result = external.hasOwnProperty('foo') ? 'ok' : 'error' -module.exports = { result } diff --git a/playground/optimize-deps/dep-cjs-with-external-dep/package.json b/playground/optimize-deps/dep-cjs-with-external-dep/package.json deleted file mode 100644 index 39e8bf01d732d0..00000000000000 --- a/playground/optimize-deps/dep-cjs-with-external-dep/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "@vitejs/test-dep-cjs-with-external-dep", - "private": true, - "version": "0.0.0", - "main": "index.js", - "dependencies": { - "@vitejs/test-dep-esm-external": "file:../dep-esm-external" - } -} diff --git a/playground/optimize-deps/dep-cjs-with-external-deps/index.js b/playground/optimize-deps/dep-cjs-with-external-deps/index.js new file mode 100644 index 00000000000000..93fe8c56557cf3 --- /dev/null +++ b/playground/optimize-deps/dep-cjs-with-external-deps/index.js @@ -0,0 +1,8 @@ +// `stream` is used as the package name for `@vitejs/test-dep-esm-dummy-node-builtin` so that it is treated like a Node builtin +// eslint-disable-next-line import-x/no-nodejs-modules +const externalDummyNodeBuiltin = require('stream') +const external = require('@vitejs/test-dep-esm-external') +// eslint-disable-next-line no-prototype-builtins +const externalResult = external.hasOwnProperty('foo') ? 'ok' : 'error' +const externalDummyNodeBuiltinResult = `${externalDummyNodeBuiltin()} ${externalDummyNodeBuiltin.bar}` +module.exports = { externalResult, externalDummyNodeBuiltinResult } diff --git a/playground/optimize-deps/dep-cjs-with-external-deps/package.json b/playground/optimize-deps/dep-cjs-with-external-deps/package.json new file mode 100644 index 00000000000000..877db9d13be18e --- /dev/null +++ b/playground/optimize-deps/dep-cjs-with-external-deps/package.json @@ -0,0 +1,10 @@ +{ + "name": "@vitejs/test-dep-cjs-with-external-deps", + "private": true, + "version": "0.0.0", + "main": "index.js", + "dependencies": { + "@vitejs/test-dep-esm-external": "file:../dep-esm-external", + "stream": "file:../dep-esm-dummy-node-builtin" + } +} diff --git a/playground/optimize-deps/dep-esm-dummy-node-builtin/index.js b/playground/optimize-deps/dep-esm-dummy-node-builtin/index.js new file mode 100644 index 00000000000000..b48be1f1a732a7 --- /dev/null +++ b/playground/optimize-deps/dep-esm-dummy-node-builtin/index.js @@ -0,0 +1,9 @@ +function foo() { + return 'foo' +} + +foo.bar = 'bar' + +export const bar = 'bar' + +export default foo diff --git a/playground/optimize-deps/dep-esm-dummy-node-builtin/package.json b/playground/optimize-deps/dep-esm-dummy-node-builtin/package.json new file mode 100644 index 00000000000000..42403c772cd08b --- /dev/null +++ b/playground/optimize-deps/dep-esm-dummy-node-builtin/package.json @@ -0,0 +1,7 @@ +{ + "name": "@vitejs/test-dep-esm-dummy-node-builtin", + "private": true, + "version": "0.0.0", + "main": "index.js", + "type": "module" +} diff --git a/playground/optimize-deps/index.html b/playground/optimize-deps/index.html index c3493cc412baec..da0bf2ce834f2e 100644 --- a/playground/optimize-deps/index.html +++ b/playground/optimize-deps/index.html @@ -310,12 +310,22 @@

Pre-bundle transitive dependency 'some-package.pdf'

import * as all from '@vitejs/test-dep-source-map-no-sources/all.js' -

Pre-bundle dependency with external sub-dependency

+

Pre-bundle dependency with external sub-dependencies

- require('some-external-sub-dependency') returns a plain object: - ??? + require('some-external-sub-dependency') returns a plain object rather than a + module namespace object: + ??? +
+
+ require('some-external-sub-dependency') returns the default export if the + dependency is a Node builtin: + ???
diff --git a/playground/optimize-deps/package.json b/playground/optimize-deps/package.json index 5ebad36a3bfc65..23868a4e9e8471 100644 --- a/playground/optimize-deps/package.json +++ b/playground/optimize-deps/package.json @@ -18,7 +18,7 @@ "@vitejs/test-dep-cjs-compiled-from-cjs": "file:./dep-cjs-compiled-from-cjs", "@vitejs/test-dep-cjs-compiled-from-esm": "file:./dep-cjs-compiled-from-esm", "@vitejs/test-dep-cjs-with-assets": "file:./dep-cjs-with-assets", - "@vitejs/test-dep-cjs-with-external-dep": "file:./dep-cjs-with-external-dep", + "@vitejs/test-dep-cjs-with-external-deps": "file:./dep-cjs-with-external-deps", "@vitejs/test-dep-css-require": "file:./dep-css-require", "@vitejs/test-dep-esbuild-plugin-transform": "file:./dep-esbuild-plugin-transform", "@vitejs/test-dep-incompatible": "file:./dep-incompatible", diff --git a/playground/optimize-deps/vite.config.js b/playground/optimize-deps/vite.config.js index 4e6f1c7fc16ecc..adcea2df9bc3f2 100644 --- a/playground/optimize-deps/vite.config.js +++ b/playground/optimize-deps/vite.config.js @@ -23,12 +23,13 @@ export default defineConfig({ '@vitejs/test-dep-optimize-exports-with-glob/**/*', '@vitejs/test-dep-optimize-exports-with-root-glob/**/*.js', '@vitejs/test-dep-optimize-with-glob/**/*.js', - '@vitejs/test-dep-cjs-with-external-dep', + '@vitejs/test-dep-cjs-with-external-deps', ], exclude: [ '@vitejs/test-nested-exclude', '@vitejs/test-dep-non-optimized', '@vitejs/test-dep-esm-external', + 'stream', ], esbuildOptions: { plugins: [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 192b00269fffed..3bd53a49c50361 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -959,9 +959,9 @@ importers: '@vitejs/test-dep-cjs-with-assets': specifier: file:./dep-cjs-with-assets version: file:playground/optimize-deps/dep-cjs-with-assets - '@vitejs/test-dep-cjs-with-external-dep': - specifier: file:./dep-cjs-with-external-dep - version: file:playground/optimize-deps/dep-cjs-with-external-dep + '@vitejs/test-dep-cjs-with-external-deps': + specifier: file:./dep-cjs-with-external-deps + version: file:playground/optimize-deps/dep-cjs-with-external-deps '@vitejs/test-dep-css-require': specifier: file:./dep-css-require version: file:playground/optimize-deps/dep-css-require @@ -1094,16 +1094,21 @@ importers: playground/optimize-deps/dep-cjs-with-assets: {} - playground/optimize-deps/dep-cjs-with-external-dep: + playground/optimize-deps/dep-cjs-with-external-deps: dependencies: '@vitejs/test-dep-esm-external': specifier: file:../dep-esm-external version: file:playground/optimize-deps/dep-esm-external + stream: + specifier: file:../dep-esm-dummy-node-builtin + version: '@vitejs/test-dep-esm-dummy-node-builtin@file:playground/optimize-deps/dep-esm-dummy-node-builtin' playground/optimize-deps/dep-css-require: {} playground/optimize-deps/dep-esbuild-plugin-transform: {} + playground/optimize-deps/dep-esm-dummy-node-builtin: {} + playground/optimize-deps/dep-esm-external: {} playground/optimize-deps/dep-incompatible: {} @@ -3654,8 +3659,8 @@ packages: '@vitejs/test-dep-cjs-with-assets@file:playground/optimize-deps/dep-cjs-with-assets': resolution: {directory: playground/optimize-deps/dep-cjs-with-assets, type: directory} - '@vitejs/test-dep-cjs-with-external-dep@file:playground/optimize-deps/dep-cjs-with-external-dep': - resolution: {directory: playground/optimize-deps/dep-cjs-with-external-dep, type: directory} + '@vitejs/test-dep-cjs-with-external-deps@file:playground/optimize-deps/dep-cjs-with-external-deps': + resolution: {directory: playground/optimize-deps/dep-cjs-with-external-deps, type: directory} '@vitejs/test-dep-conditions@file:packages/vite/src/node/__tests__/fixtures/test-dep-conditions': resolution: {directory: packages/vite/src/node/__tests__/fixtures/test-dep-conditions, type: directory} @@ -3666,6 +3671,9 @@ packages: '@vitejs/test-dep-esbuild-plugin-transform@file:playground/optimize-deps/dep-esbuild-plugin-transform': resolution: {directory: playground/optimize-deps/dep-esbuild-plugin-transform, type: directory} + '@vitejs/test-dep-esm-dummy-node-builtin@file:playground/optimize-deps/dep-esm-dummy-node-builtin': + resolution: {directory: playground/optimize-deps/dep-esm-dummy-node-builtin, type: directory} + '@vitejs/test-dep-esm-external@file:playground/optimize-deps/dep-esm-external': resolution: {directory: playground/optimize-deps/dep-esm-external, type: directory} @@ -9289,9 +9297,10 @@ snapshots: '@vitejs/test-dep-cjs-with-assets@file:playground/optimize-deps/dep-cjs-with-assets': {} - '@vitejs/test-dep-cjs-with-external-dep@file:playground/optimize-deps/dep-cjs-with-external-dep': + '@vitejs/test-dep-cjs-with-external-deps@file:playground/optimize-deps/dep-cjs-with-external-deps': dependencies: '@vitejs/test-dep-esm-external': file:playground/optimize-deps/dep-esm-external + stream: '@vitejs/test-dep-esm-dummy-node-builtin@file:playground/optimize-deps/dep-esm-dummy-node-builtin' '@vitejs/test-dep-conditions@file:packages/vite/src/node/__tests__/fixtures/test-dep-conditions': {} @@ -9299,6 +9308,8 @@ snapshots: '@vitejs/test-dep-esbuild-plugin-transform@file:playground/optimize-deps/dep-esbuild-plugin-transform': {} + '@vitejs/test-dep-esm-dummy-node-builtin@file:playground/optimize-deps/dep-esm-dummy-node-builtin': {} + '@vitejs/test-dep-esm-external@file:playground/optimize-deps/dep-esm-external': {} '@vitejs/test-dep-including-a@file:playground/preload/dep-including-a':