Vite打包JS无法接收外部自定义jQuery trigger()问题求助
问题描述
在WordPress环境中使用Vite作为SCSS和JavaScript打包工具,尝试用jQuery的.on()方法监听WooCommerce的自定义事件found_variation,代码如下:
jQuery(document).on('found_variation', function(event, variation) { console.log(variation); });
这段代码作为内联脚本、引用脚本或模块脚本时均正常工作,但加入经Vite打包的app.js后却无法运行(无控制台输出)。已在语句前添加console.log()确认代码已执行,但仍无法接收事件。
原因分析
核心问题是Vite打包时注入的jQuery与WordPress全局的jQuery不是同一个实例:
- WordPress前台会默认加载全局的
jQuery对象(挂载在window.jQuery),WooCommerce的found_variation事件是在这个全局jQuery实例上触发的。 - 当前通过
@rollup/plugin-inject注入的是本地npm安装的jQuery模块,这个模块会被打包进app.js,形成一个独立的jQuery实例。监听代码绑定在这个本地实例的document上,自然接收不到全局实例触发的事件。
解决方案
修改Vite配置,让打包后的代码直接使用WordPress提供的全局jQuery实例,而不是打包本地的jQuery:
- 卸载本地安装的jQuery
执行命令移除项目中本地的jQuery依赖:
npm uninstall jquery
- 更新
vite.config.js配置
修改配置,将jquery标记为外部依赖(不打包进产物),并让Vite指向全局的jQuery实例:
import liveReload from 'vite-plugin-live-reload'; import mkcert from 'vite-plugin-mkcert'; import inject from '@rollup/plugin-inject'; import { defineConfig } from 'vite'; import sassGlobImports from 'vite-plugin-sass-glob-import'; const { resolve } = require('path'); // https://vitejs.dev/config export default defineConfig({ plugins: [ sassGlobImports(), liveReload(__dirname + '/**/*.(php|twig)'), mkcert(), inject({ $: 'jquery', jQuery: 'jquery', exclude: 'node_modules/**', }), ], base: process.env.NODE_ENV === 'development' ? '/content/themes/theme-child/' : '/content/themes/theme-child/dist/', build: { outDir: resolve(__dirname, './dist'), emptyOutDir: true, manifest: true, target: 'es2018', rollupOptions: { input: { app: resolve(__dirname + '/assets/js/app.js'), app_admin: resolve(__dirname + '/assets/js/app-admin.js'), print: resolve(__dirname + '/assets/js/print.js'), }, // 标记jquery为外部依赖,不打包进产物 external: ['jquery'], }, minify: 'terser', write: true, sourcemap: 'inline', }, server: { cors: true, strictPort: true, port: 3000, https: true, hmr: { host: 'localhost', }, }, resolve: { alias: { '@img': resolve(__dirname, './assets/img'), '@icons': resolve(__dirname, './assets/icons'), '@fonts': resolve(__dirname, './assets/fonts'), '@node_modules': resolve(__dirname, './node_modules'), // 让Vite解析jquery时指向全局window.jQuery 'jquery': 'window.jQuery', }, }, css: { devSourcemap: true, }, });
- 确保代码执行时机
将监听代码包裹在jQuery(document).ready()中,确保在DOM和WooCommerce脚本加载完成后执行:
jQuery(document).ready(function() { console.log('代码已执行'); jQuery(document).on('found_variation', function(event, variation) { console.log(variation); }); });
原理说明
external: ['jquery']告诉Rollup不要把jQuery打包进产物,保留对全局jquery变量的引用。resolve.alias让Vite在解析jquery依赖时,直接指向WordPress加载的全局window.jQuery实例。- 调整后,监听代码和WooCommerce使用的是同一个jQuery实例,事件就能正常触发和接收。
内容的提问来源于stack exchange,提问作者Stan Derksen
相关产品推荐
相关产品推荐

