From e60368f937f7b2b223811321e66c4aacad72fa6a Mon Sep 17 00:00:00 2001 From: Bjorn Lu Date: Fri, 29 Jul 2022 15:59:24 +0800 Subject: [PATCH] fix(ssr): allow virtual paths on node modules (#9405) --- packages/vite/src/node/ssr/ssrExternal.ts | 33 +++++++++++-------- .../ssr-deps/__tests__/ssr-deps.spec.ts | 5 +++ playground/ssr-deps/package.json | 3 +- playground/ssr-deps/pkg-exports/index.js | 1 + playground/ssr-deps/pkg-exports/package.json | 9 +++++ playground/ssr-deps/server.js | 18 +++++++++- playground/ssr-deps/src/app.js | 3 ++ pnpm-lock.yaml | 11 +++++++ 8 files changed, 67 insertions(+), 16 deletions(-) create mode 100644 playground/ssr-deps/pkg-exports/index.js create mode 100644 playground/ssr-deps/pkg-exports/package.json diff --git a/packages/vite/src/node/ssr/ssrExternal.ts b/packages/vite/src/node/ssr/ssrExternal.ts index 5fa073ddc2d58a..04b60afdd263eb 100644 --- a/packages/vite/src/node/ssr/ssrExternal.ts +++ b/packages/vite/src/node/ssr/ssrExternal.ts @@ -129,20 +129,25 @@ export function createIsConfiguredAsSsrExternal( if (!bareImportRE.test(id) || id.includes('\0')) { return false } - return !!tryNodeResolve( - id, - undefined, - resolveOptions, - ssr?.target === 'webworker', - undefined, - true, - // try to externalize, will return undefined or an object without - // a external flag if it isn't externalizable - true, - // Allow linked packages to be externalized if they are explicitly - // configured as external - !!configuredAsExternal - )?.external + try { + return !!tryNodeResolve( + id, + undefined, + resolveOptions, + ssr?.target === 'webworker', + undefined, + true, + // try to externalize, will return undefined or an object without + // a external flag if it isn't externalizable + true, + // Allow linked packages to be externalized if they are explicitly + // configured as external + !!configuredAsExternal + )?.external + } catch (e) { + // may be an invalid import that's resolved by a plugin + return false + } } // Returns true if it is configured as external, false if it is filtered diff --git a/playground/ssr-deps/__tests__/ssr-deps.spec.ts b/playground/ssr-deps/__tests__/ssr-deps.spec.ts index 8f4e097aec1c81..f20dca26263f65 100644 --- a/playground/ssr-deps/__tests__/ssr-deps.spec.ts +++ b/playground/ssr-deps/__tests__/ssr-deps.spec.ts @@ -103,3 +103,8 @@ test('msg from linked no external', async () => { await page.goto(url) expect(await page.textContent('.linked-no-external')).toMatch('Hello World!') }) + +test('msg from linked no external', async () => { + await page.goto(url) + expect(await page.textContent('.dep-virtual')).toMatch('[success]') +}) diff --git a/playground/ssr-deps/package.json b/playground/ssr-deps/package.json index 20f840d0f27133..13e7c627a2139e 100644 --- a/playground/ssr-deps/package.json +++ b/playground/ssr-deps/package.json @@ -27,7 +27,8 @@ "optimized-cjs-with-nested-external": "file:./optimized-with-nested-external", "external-using-external-entry": "file:./external-using-external-entry", "external-entry": "file:./external-entry", - "linked-no-external": "link:./linked-no-external" + "linked-no-external": "link:./linked-no-external", + "pkg-exports": "file:./pkg-exports" }, "devDependencies": { "cross-env": "^7.0.3", diff --git a/playground/ssr-deps/pkg-exports/index.js b/playground/ssr-deps/pkg-exports/index.js new file mode 100644 index 00000000000000..edb72725b9e7c6 --- /dev/null +++ b/playground/ssr-deps/pkg-exports/index.js @@ -0,0 +1 @@ +export default undefined diff --git a/playground/ssr-deps/pkg-exports/package.json b/playground/ssr-deps/pkg-exports/package.json new file mode 100644 index 00000000000000..6947a065e74cea --- /dev/null +++ b/playground/ssr-deps/pkg-exports/package.json @@ -0,0 +1,9 @@ +{ + "name": "pkg-exports", + "private": true, + "version": "0.0.0", + "exports": { + ".": "./index.js" + }, + "type": "module" +} diff --git a/playground/ssr-deps/server.js b/playground/ssr-deps/server.js index 764e5b5d8da657..aa47a6055321ac 100644 --- a/playground/ssr-deps/server.js +++ b/playground/ssr-deps/server.js @@ -45,7 +45,23 @@ export async function createServer(root = process.cwd(), hmrPort) { optimizeDeps: { disabled: 'build' } - } + }, + plugins: [ + { + name: 'dep-virtual', + enforce: 'pre', + resolveId(id) { + if (id === 'pkg-exports/virtual') { + return 'pkg-exports/virtual' + } + }, + load(id) { + if (id === 'pkg-exports/virtual') { + return 'export default "[success]"' + } + } + } + ] }) // use vite's connect instance as middleware app.use(vite.middlewares) diff --git a/playground/ssr-deps/src/app.js b/playground/ssr-deps/src/app.js index 987eaa3e1b43e9..0b0fe2d9b968ec 100644 --- a/playground/ssr-deps/src/app.js +++ b/playground/ssr-deps/src/app.js @@ -12,6 +12,7 @@ import requireAbsolute from 'require-absolute' import noExternalCjs from 'no-external-cjs' import importBuiltinCjs from 'import-builtin-cjs' import { hello as linkedNoExternal } from 'linked-no-external' +import virtualMessage from 'pkg-exports/virtual' // This import will set a 'Hello World!" message in the nested-external non-entry dependency import 'non-optimized-with-nested-external' @@ -79,5 +80,7 @@ export async function render(url, rootDir) { const linkedNoExternalMessage = linkedNoExternal() html += `\n

message from linked-no-external: ${linkedNoExternalMessage}

` + html += `\n

message from dep-virtual: ${virtualMessage}

` + return html + '\n' } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3d8f46d5cd0af3..4c9742082efe58 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -915,6 +915,7 @@ importers: only-object-assigned-exports: file:./only-object-assigned-exports optimized-cjs-with-nested-external: file:./optimized-with-nested-external optimized-with-nested-external: file:./optimized-with-nested-external + pkg-exports: file:./pkg-exports primitive-export: file:./primitive-export read-file-content: file:./read-file-content require-absolute: file:./require-absolute @@ -935,6 +936,7 @@ importers: only-object-assigned-exports: file:playground/ssr-deps/only-object-assigned-exports optimized-cjs-with-nested-external: file:playground/ssr-deps/optimized-with-nested-external optimized-with-nested-external: file:playground/ssr-deps/optimized-with-nested-external + pkg-exports: file:playground/ssr-deps/pkg-exports primitive-export: file:playground/ssr-deps/primitive-export read-file-content: file:playground/ssr-deps/read-file-content require-absolute: file:playground/ssr-deps/require-absolute @@ -1003,6 +1005,9 @@ importers: dependencies: nested-external: file:playground/ssr-deps/nested-external + playground/ssr-deps/pkg-exports: + specifiers: {} + playground/ssr-deps/primitive-export: specifiers: {} @@ -9190,6 +9195,12 @@ packages: nested-external: file:playground/ssr-deps/nested-external dev: false + file:playground/ssr-deps/pkg-exports: + resolution: {directory: playground/ssr-deps/pkg-exports, type: directory} + name: pkg-exports + version: 0.0.0 + dev: false + file:playground/ssr-deps/primitive-export: resolution: {directory: playground/ssr-deps/primitive-export, type: directory} name: primitive-export