Vue3+TS项目Vite构建报错:class constructors需用new调用
问题分析与修复方案
这个错误的核心原因是Vite构建时的代码压缩/优化工具(如esbuild或terser)将SideNavItemData类的构造函数误处理成了可直接调用的函数,导致构建后的代码出现new y(rA)(...)这种错误调用形式——先通过new实例化,又立即把实例当作函数调用,触发了类构造函数不能被当作普通函数调用的限制。
方案1:避免在模板中直接实例化类
Vue模板的表达式在构建时会经过编译转换,直接在模板里用new创建类实例容易被压缩工具误判。建议在组件的setup函数中提前创建实例,再传递给子组件:
<script setup lang="ts"> import { ref } from 'vue'; import SideNavItem from './SideNavItem.vue'; import SideNavItemData from './SideNavItemData'; import { SideNavItemName } from './enums'; // 在setup中提前创建实例 const homeNavItem = ref(new SideNavItemData({ itemName: SideNavItemName.Home })); </script> <template> <SideNavItem :sideNavItemData="homeNavItem" /> </template>
方案2:修改Vite压缩配置,保留类名/函数名
如果必须在模板中使用类实例化,可以调整Vite的构建配置,让压缩工具保留类和构造函数的名称,避免误转换。在vite.config.ts中修改:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], build: { // 改用terser压缩(esbuild默认压缩策略更激进) minify: 'terser', terserOptions: { // 保留类名称 keep_classnames: true, // 保留函数名称(包括构造函数) keep_fnames: true } } });
方案3:改用工厂函数替代类
如果类仅用于封装数据结构,可以换成接口+工厂函数的形式,彻底规避类构造函数的处理问题:
// 定义数据接口 export interface SideNavItemData { itemName: SideNavItemName; // 其他属性按需添加 } // 工厂函数创建实例 export function createSideNavItemData(data: { itemName: SideNavItemName }): SideNavItemData { return { ...data }; }
然后在模板中使用:
<template> <SideNavItem :sideNavItemData="createSideNavItemData({ itemName: SideNavItemName.Home })" /> </template> <script setup lang="ts"> import { createSideNavItemData } from './SideNavItemData'; import { SideNavItemName } from './enums'; </script>
内容的提问来源于stack exchange,提问作者STVN
相关产品推荐
相关产品推荐

