使用Vue3构建Web Component如何调整Vite配置输出目标格式单文件
调整方案
你当前构建产物拆分、不符合单文件要求是因为默认Vite是按应用模式构建,会自动拆分公共依赖代码,需要切换为库构建模式并禁用代码分割,具体修改如下:
1. 调整vite.config.js配置
修改后的完整配置如下:
import { defineConfig } from "vite"; import vue from "@vitejs/plugin-vue"; export default defineConfig({ plugins: [vue({ customElement: true })], build: { // 启用库模式 lib: { // 替换为你的组件入口文件路径,比如src/components/CurrentTime.ce.vue entry: 'src/your-component-entry.vue', name: 'CurrentTime', // 输出es格式的单文件,也可添加umd格式兼容更多场景 formats: ['es'], // 输出文件名,最终会生成dist/current-time.js fileName: () => 'current-time.js' }, rollupOptions: { // 不把vue标记为外部依赖,将运行时一起打包进产物 external: [], output: { // 禁用代码分割,所有内容打包到单个文件 inlineDynamicImports: true } } } });
2. 调整组件入口文件
确保你的组件入口文件只保留组件定义和自定义元素注册逻辑,移除测试用的监听、调用代码,示例入口写法:
<template> <div> <slot name="prefix"></slot> {{ formattedTime }} </div> </template> <script setup> import { ref, computed } from 'vue' const props = defineProps({ timeZone: { type: String, default: "America/Los_Angeles" } }) const emit = defineEmits(['datechange']) const currentDate = ref(new Date()) const formattedTime = computed(() => { return currentDate.value.toLocaleString("en-US", { timeZone: props.timeZone }) }) setInterval(() => { currentDate.value = new Date() emit('datechange', formattedTime.value) }, 1000) </script> <!-- 如果你使用单独的js作为入口,写法如下: import CurrentTime from './CurrentTime.ce.vue' import { defineCustomElement } from 'vue' const CurrentTimeElement = defineCustomElement(CurrentTime) customElements.define('current-time', CurrentTimeElement) -->
如果需要样式隔离,将组件文件后缀改为.ce.vue,Vue会自动把样式注入到组件的shadow DOM中。调整完成后执行构建命令,即可得到无外部依赖的单个独立Web Component文件。
注意说明
因为你是基于Vue编写组件,构建产物会内置Vue的轻量运行时来处理响应式、props、插槽、事件等逻辑,不可能完全和纯手写原生Web Component的代码结构完全一致,但调整后得到的单个JS文件可直接在页面引入使用,符合业务使用要求。
内容的提问来源于stack exchange,提问作者JithinAji
相关产品推荐
相关产品推荐

