From 2e5a438b3ed5155cdec417bbaf16b026504d1662 Mon Sep 17 00:00:00 2001 From: TrickyPi <530257315@qq.com> Date: Sat, 5 Mar 2022 17:40:26 +0800 Subject: [PATCH 1/3] fix(ssr): always throw error when evaluating an wrong SSR module --- .../__tests__/fixtures/ssrModuleLoader-bad.js | 2 ++ .../ssr/__tests__/ssrModuleLoader.spec.ts | 29 +++++++++++++++++++ packages/vite/src/node/ssr/ssrModuleLoader.ts | 1 + 3 files changed, 32 insertions(+) create mode 100644 packages/vite/src/node/ssr/__tests__/fixtures/ssrModuleLoader-bad.js create mode 100644 packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts diff --git a/packages/vite/src/node/ssr/__tests__/fixtures/ssrModuleLoader-bad.js b/packages/vite/src/node/ssr/__tests__/fixtures/ssrModuleLoader-bad.js new file mode 100644 index 00000000000000..a51a0519d34003 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/fixtures/ssrModuleLoader-bad.js @@ -0,0 +1,2 @@ +export const bad = 1 +throw new Error('it is an expected error') diff --git a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts new file mode 100644 index 00000000000000..335a2eb5921c37 --- /dev/null +++ b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts @@ -0,0 +1,29 @@ +import { createServer } from '../../index' +import { resolve } from 'path' + +const badjs = resolve(__dirname, './fixtures/ssrModuleLoader-bad.js') +const THROW_MESSAGE = 'it is an expected error' + +test('always throw error when evaluating an wrong SSR module', async () => { + const viteServer = await createServer() + const spy = jest.spyOn(console, 'error').mockImplementation(() => {}) + const expectedErrors = [] + for (const i of [0, 1]) { + try { + await viteServer.ssrLoadModule(badjs) + } catch (e) { + expectedErrors.push(e) + } + } + await viteServer.close() + expect(expectedErrors).toHaveLength(2) + expectedErrors.forEach((error) => { + expect(error?.message).toContain(THROW_MESSAGE) + }) + expect(spy).toBeCalledTimes(2) + spy.mock.calls.forEach(([info]) => { + expect(info).toContain('Error when evaluating SSR module') + expect(info).toContain(THROW_MESSAGE) + }) + spy.mockClear() +}) diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts index de31c6a20266c5..32f30b20c30e89 100644 --- a/packages/vite/src/node/ssr/ssrModuleLoader.ts +++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts @@ -202,6 +202,7 @@ async function instantiateModule( ssrExportAll ) } catch (e) { + mod.ssrModule = null if (e.stack && fixStacktrace !== false) { const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph) rebindErrorStacktrace(e, stacktrace) From 458c4c5ef6905f751b16a5fa1dd23de69e0fef93 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 6 Mar 2022 21:58:15 -0500 Subject: [PATCH 2/3] fix: reuse mod.ssrError --- packages/vite/src/node/server/moduleGraph.ts | 1 + .../vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts | 4 +--- packages/vite/src/node/ssr/ssrModuleLoader.ts | 6 +++++- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/vite/src/node/server/moduleGraph.ts b/packages/vite/src/node/server/moduleGraph.ts index f09e741f430983..7b55d942b42ca5 100644 --- a/packages/vite/src/node/server/moduleGraph.ts +++ b/packages/vite/src/node/server/moduleGraph.ts @@ -31,6 +31,7 @@ export class ModuleNode { transformResult: TransformResult | null = null ssrTransformResult: TransformResult | null = null ssrModule: Record | null = null + ssrError: Error | null = null lastHMRTimestamp = 0 constructor(url: string) { diff --git a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts index 335a2eb5921c37..ef52d778819c9e 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts @@ -17,9 +17,7 @@ test('always throw error when evaluating an wrong SSR module', async () => { } await viteServer.close() expect(expectedErrors).toHaveLength(2) - expectedErrors.forEach((error) => { - expect(error?.message).toContain(THROW_MESSAGE) - }) + expect(expectedErrors[0]).toBe(expectedErrors[1]) expect(spy).toBeCalledTimes(2) spy.mock.calls.forEach(([info]) => { expect(info).toContain('Error when evaluating SSR module') diff --git a/packages/vite/src/node/ssr/ssrModuleLoader.ts b/packages/vite/src/node/ssr/ssrModuleLoader.ts index 32f30b20c30e89..8b3a423f58aeab 100644 --- a/packages/vite/src/node/ssr/ssrModuleLoader.ts +++ b/packages/vite/src/node/ssr/ssrModuleLoader.ts @@ -77,6 +77,10 @@ async function instantiateModule( const { moduleGraph } = server const mod = await moduleGraph.ensureEntryFromUrl(url, true) + if (mod.ssrError) { + throw mod.ssrError + } + if (mod.ssrModule) { return mod.ssrModule } @@ -202,7 +206,7 @@ async function instantiateModule( ssrExportAll ) } catch (e) { - mod.ssrModule = null + mod.ssrError = e if (e.stack && fixStacktrace !== false) { const stacktrace = ssrRewriteStacktrace(e.stack, moduleGraph) rebindErrorStacktrace(e, stacktrace) From 2a8bca2159d7dfa8d4135fdfc635ca0453660dcf Mon Sep 17 00:00:00 2001 From: TrickyPi <33021497+TrickyPi@users.noreply.github.com> Date: Mon, 7 Mar 2022 12:19:30 +0800 Subject: [PATCH 3/3] test: tweaks --- .../src/node/ssr/__tests__/ssrModuleLoader.spec.ts | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts index ef52d778819c9e..6a45a2b70509d0 100644 --- a/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts +++ b/packages/vite/src/node/ssr/__tests__/ssrModuleLoader.spec.ts @@ -1,5 +1,5 @@ -import { createServer } from '../../index' import { resolve } from 'path' +import { createServer } from '../../index' const badjs = resolve(__dirname, './fixtures/ssrModuleLoader-bad.js') const THROW_MESSAGE = 'it is an expected error' @@ -18,10 +18,12 @@ test('always throw error when evaluating an wrong SSR module', async () => { await viteServer.close() expect(expectedErrors).toHaveLength(2) expect(expectedErrors[0]).toBe(expectedErrors[1]) - expect(spy).toBeCalledTimes(2) - spy.mock.calls.forEach(([info]) => { - expect(info).toContain('Error when evaluating SSR module') - expect(info).toContain(THROW_MESSAGE) + expectedErrors.forEach((error) => { + expect(error?.message).toContain(THROW_MESSAGE) }) + expect(spy).toBeCalledTimes(1) + const [firstParameter] = spy.mock.calls[0] + expect(firstParameter).toContain('Error when evaluating SSR module') + expect(firstParameter).toContain(THROW_MESSAGE) spy.mockClear() })