From 21ee89ada444a81409d6e4eebc625f9d0fcb6724 Mon Sep 17 00:00:00 2001 From: Marco Pasqualetti <24919330+marcalexiei@users.noreply.github.com> Date: Sat, 25 Jan 2025 18:12:57 +0100 Subject: [PATCH] fix(packages/tuono): build error when config contains vite plugins (#415) --- .../build/config/create-json-config.spec.ts | 32 +++++++++++++++++++ .../src/build/config/create-json-config.ts | 22 +++++++++++-- 2 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 packages/tuono/src/build/config/create-json-config.spec.ts diff --git a/packages/tuono/src/build/config/create-json-config.spec.ts b/packages/tuono/src/build/config/create-json-config.spec.ts new file mode 100644 index 00000000..decc9896 --- /dev/null +++ b/packages/tuono/src/build/config/create-json-config.spec.ts @@ -0,0 +1,32 @@ +import fs from 'fs/promises' + +import { describe, expect, it, vitest } from 'vitest' +import react from '@vitejs/plugin-react-swc' + +import { createJsonConfig } from './create-json-config' + +const writeFileSpy = vitest.spyOn(fs, 'writeFile').mockResolvedValue(void 0) + +describe('createJsonConfig', () => { + const sampleConfig = { server: { host: 'h', port: 1 } } + + it('should process config with only server property', async () => { + await createJsonConfig(sampleConfig) + + expect(writeFileSpy).toHaveBeenCalledWith( + expect.any(String), + expect.stringContaining(JSON.stringify(sampleConfig)), + expect.any(String), + ) + }) + + it('should process config with plugins', async () => { + await createJsonConfig({ ...sampleConfig, vite: { plugins: [react()] } }) + + expect(writeFileSpy).toHaveBeenCalledWith( + expect.any(String), + expect.stringContaining(JSON.stringify(sampleConfig)), + expect.any(String), + ) + }) +}) diff --git a/packages/tuono/src/build/config/create-json-config.ts b/packages/tuono/src/build/config/create-json-config.ts index 122c3aa6..cf8e6388 100644 --- a/packages/tuono/src/build/config/create-json-config.ts +++ b/packages/tuono/src/build/config/create-json-config.ts @@ -21,9 +21,25 @@ const CONFIG_PATH = path.join( function removeViteProperties( config: InternalTuonoConfig, ): Omit { - const newConfig = structuredClone(config) - delete newConfig['vite'] - return newConfig + /** + * Using {@link structuredClone} cause the following errors based on runtime env: + * ```text + * node + * DOMException [DataCloneError]: configureServer(s){a.push(s)} could not be cloned. + * + * vitest + * DataCloneError: (id) => id === runtimePublicPath ? id : void 0 could not be cloned. + * ``` + * when vite plugins are passed inside to the config. + * + * Since the purpose of this function is to remove the vite object + * we are going to use destructing rather than {@link structuredClone} and `delete` + * + * @see https://github.com/tuono-labs/tuono/issues/414 + */ + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { vite, ...configRest } = config + return structuredClone(configRest) } /**