如何在HTML文件中正确引入带Pinia的Vue3打包组件?
问题描述
我有一个基于Vue3的基础应用,包含3个组件,用Pinia做状态管理。现在需要把它打包成可在纯HTML文件中引入的.js文件。未集成Pinia时功能正常,开发模式下搭配Pinia也能正常运行,但打包后在HTML中使用时出现报错,问题出在Pinia的初始化代码:
const pinia = Pinia.createPinia(); app.use(pinia);
打包命令
npm run build
vite.config.ts 配置
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], build: { lib: { entry: './src/App.vue', name: 'MyComponent', fileName: (format) => `my-component.${format}.js` }, rollupOptions: { external: ['vue'], output: { globals: { vue: 'Vue' } } } } });
项目中的main.js
import { createApp } from 'vue'; import { createPinia } from 'pinia'; import App from './App.vue'; const app = createApp(App); const pinia = createPinia(); app.use(pinia); app.mount('#app');
报错信息
ReferenceError: Pinia is not defined
测试用HTML文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue Component in HTML</title> <link rel="stylesheet" href="dist/style.css"> </head> <body> <div id="app"> <my-component></my-component> </div> <!-- Polyfill process.env for browser compatibility --> <script> window.process = { env: { NODE_ENV: 'production' } }; </script> <script src="https://cdn.jsdelivr.net/npm/vue@3"></script> <script src="https://unpkg.com/pinia@2.0.0-beta.0/dist/pinia.iife.js"></script> <script src="dist/my-component.umd.js"></script> <script> document.addEventListener('DOMContentLoaded', function () { console.log(Vue); console.log(Pinia); console.log(window.Pinia); const app = Vue.createApp({}); const pinia = Pinia.createPinia(); app.use(pinia); app.component('my-component', MyComponent); app.mount('#app'); }); </script> </body> </html>
解决方案
问题核心是Vite打包配置未将Pinia设为外部依赖,导致打包时Pinia被打包进组件库,但你又在HTML中通过CDN引入了Pinia,两者冲突,组件库内部也找不到全局的Pinia变量。
按以下步骤修改:
- 更新vite.config.ts,将
pinia加入外部依赖列表,并配置对应全局变量名:
import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], build: { lib: { entry: './src/App.vue', name: 'MyComponent', fileName: (format) => `my-component.${format}.js` }, rollupOptions: { // 把pinia和vue一同设为外部依赖 external: ['vue', 'pinia'], output: { globals: { vue: 'Vue', // 指定pinia对应的全局变量名,与CDN引入的全局对象一致 pinia: 'Pinia' } } } } });
确保组件内Pinia使用正常:
组件或store文件中正常导入Pinia相关方法即可,比如:// store示例 import { defineStore } from 'pinia'; export const useMyStore = defineStore('myStore', { state: () => ({ count: 0 }) });打包后会自动关联全局的
Pinia对象,无需额外修改。重新打包:
npm run build
- 验证HTML代码:
你HTML中的Pinia初始化逻辑是正确的,CDN引入的pinia.iife.js会在全局暴露Pinia对象,修改打包配置后,组件库会使用这个全局实例,不再触发报错。
另外建议将Pinia升级到稳定版,避免beta版本的潜在问题。
内容的提问来源于stack exchange,提问作者Tomáš Mastný
相关产品推荐
相关产品推荐

