如何利用Vite库模式将组件库各组件单独打包为UMD格式?
用Vite Library Mode生成独立UMD组件包的实现方案
1. 调整组件目录结构
确保每个组件拥有独立的目录与入口文件,示例结构:
src/ └── components/ ├── Button/ │ ├── Button.vue │ └── index.ts # 组件导出入口 ├── Input/ │ ├── Input.vue │ └── index.ts └── ...
每个组件的index.ts需导出组件本身,比如Button的入口文件:
import Button from './Button.vue' export default Button
2. 配置Vite多入口打包
在vite.config.ts中,通过Rollup的多入口配置指定每个组件的入口,推荐用Node.js文件系统API动态读取组件目录,避免手动维护入口列表:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import fs from 'fs' import path from 'path' // 动态读取components目录下的所有组件入口 const getComponentEntries = () => { const componentsDir = path.resolve(__dirname, 'src/components') const componentEntries = {} fs.readdirSync(componentsDir).forEach(dir => { const componentDir = path.join(componentsDir, dir) const entryFile = path.join(componentDir, 'index.ts') if (fs.existsSync(entryFile)) { componentEntries[`components/${dir}/index`] = entryFile } }) return componentEntries } export default defineConfig({ plugins: [vue()], build: { // 开启Library Mode lib: { formats: ['umd'] // 指定输出UMD格式 }, rollupOptions: { // 外部化Vue,避免打包进UMD包(组件库依赖Vue时配置) external: ['vue'], input: getComponentEntries(), output: { // 全局变量映射,Vue对应全局的Vue对象 globals: { vue: 'Vue' }, // 输出文件命名规则,每个组件打包到对应子目录 entryFileNames: '[name].umd.js', chunkFileNames: '[name].umd.js', assetFileNames: '[name].[ext]' } } } })
3. 自定义全局变量名(可选)
如果需要给每个组件的UMD包设置独立的全局变量名,可在output中针对性配置:
output: [ { format: 'umd', globals: { vue: 'Vue' }, entryFileNames: '[name].umd.js', // 生成类似MyLib.Button的全局变量名 name: (chunk) => { const componentName = chunk.name.split('/')[1] return `MyLib.${componentName}` } } ]
4. 执行打包
在package.json中添加打包脚本:
{ "scripts": { "build:components": "vite build" } }
运行npm run build:components后,dist目录会生成每个组件的独立UMD包,比如dist/components/Button/index.umd.js。
5. 验证使用
在HTML中引入单个组件的UMD包测试:
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script> <script src="./dist/components/Button/index.umd.js"></script> <script> const app = Vue.createApp({ template: '<MyLib.Button>测试按钮</MyLib.Button>' }) app.mount('#app') </script>
内容的提问来源于stack exchange,提问作者yingting nie
相关产品推荐
相关产品推荐

