diff --git a/src/config.ts b/src/config.ts index b6a468e..89c257a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -28,7 +28,7 @@ import importMetaPlugin from './plugins/importMeta' import esmShimPlugin from './plugins/esmShim' import modulePathPlugin from './plugins/modulePath' import isolateEntriesPlugin from './plugins/isolateEntries' -import { isObject, isFilePathESM } from './utils' +import { isObject, isFilePathESM, deepClone } from './utils' export { defineConfig as defineViteConfig } from 'vite' @@ -266,10 +266,6 @@ export async function resolveConfig( return resolved } -function deepClone(data: T): T { - return JSON.parse(JSON.stringify(data)) -} - function resetOutDir(config: ViteConfig, outDir: string, subOutDir: string): void { let userOutDir = config.build?.outDir if (outDir === userOutDir) { diff --git a/src/utils.ts b/src/utils.ts index ffcebbd..75cf883 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-function-type */ import path from 'node:path' import fs from 'node:fs' import { createHash } from 'node:crypto' @@ -78,3 +79,35 @@ export function isFilePathESM(filePath: string): boolean { return pkg?.type === 'module' } } + +type DeepWritable = + T extends ReadonlyArray + ? { -readonly [P in keyof T]: DeepWritable } + : T extends RegExp + ? RegExp + : T[keyof T] extends Function + ? T + : { -readonly [P in keyof T]: DeepWritable } + +export function deepClone(value: T): DeepWritable { + if (Array.isArray(value)) { + return value.map(v => deepClone(v)) as DeepWritable + } + if (isObject(value)) { + const cloned: Record = {} + for (const key in value) { + cloned[key] = deepClone(value[key]) + } + return cloned as DeepWritable + } + if (typeof value === 'function') { + return value as DeepWritable + } + if (value instanceof RegExp) { + return new RegExp(value) as DeepWritable + } + if (typeof value === 'object' && value != null) { + throw new Error('Cannot deep clone non-plain object') + } + return value as DeepWritable +}