Vite开发环境import正常 生产构建后报dxDataGrid不是函数错误
问题原因
报错的核心原因是生产构建时存在多份jQuery实例:
- 开发模式下Vite会对依赖做预构建打包,所有模块引入的jQuery都会指向同一个实例,
devextreme/integration/jquery注入的dxDataGrid方法会正常挂载到组件使用的$对象上,所以开发环境运行正常。 - 生产构建时,Vite的Tree-Shaking和代码分包逻辑没有正确处理jQuery的插件挂载机制:
devextreme/integration/jquery内部依赖的jQuery,和组件中import $ from 'jquery'引入的jQuery被识别为两个独立的模块副本,dxDataGrid方法仅被挂载到devextreme依赖的那份jQuery原型上,组件中拿到的$是没有挂载插件的干净jQuery实例,调用时自然会抛出dxDataGrid is not a function的错误。
修复方案
优先选择第一种方案,一劳永逸不需要修改业务代码。
方案1:Vite配置强制统一jQuery实例(推荐)
修改项目根目录的vite.config.ts,通过别名强制所有jQuery的引入都指向同一个本地文件,从根源避免多实例问题:
import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import path from 'path' export default defineConfig({ plugins: [vue()], resolve: { alias: { // 所有jquery引入都强制指向同一个文件,杜绝多副本 'jquery': path.resolve(__dirname, 'node_modules/jquery/dist/jquery.js') } }, // 提前预构建相关依赖,避免开发/生产环境行为不一致 optimizeDeps: { include: ['jquery', 'devextreme/integration/jquery', 'devextreme/ui/data_grid'] } })
修改完成后重新执行yarn build,构建后的产物部署就不会再报这个错。
方案2:手动对齐jQuery原型方法
如果不方便修改Vite配置,可以在引入devextreme依赖后,手动把插件方法同步到当前引入的jQuery实例上,缺点是每个用到devextreme jQuery组件的文件都要加这段处理:
<script lang="ts"> import $ from 'jquery'; import 'devextreme/integration/jquery'; import 'devextreme/ui/data_grid'; // 同步devextreme挂载的插件方法到当前$实例 if (window.jQuery) { $.fn = Object.assign($.fn, window.jQuery.fn) } export default({ data() { return { msg: 'Hello there!', } }, mounted() { $('#testIt').dxDataGrid({ dataSource: [ { test1: '1', test2: '2' }, { test1: '3', test2: '4' }, { test1: '5', test2: '6' }, ], columns: [ { dataField: 'test1' }, { dataField: 'test2' } ] }); } }) </script>
方案3:全局挂载jQuery统一引用
在项目入口文件把jQuery挂载到window全局,所有业务代码都使用全局的$,避免模块引入导致的多实例问题:
- 修改入口文件
src/main.ts:
import { createApp } from 'vue' import App from './App.vue' import $ from 'jquery' // 全局挂载jQuery window.$ = window.jQuery = $ // 挂载完jQuery再引入devextreme依赖 import 'devextreme/integration/jquery' import 'devextreme/ui/data_grid' createApp(App).mount('#app')
- 组件中删除
import $ from 'jquery'的代码,直接使用全局$即可。 - 在
src/env.d.ts中补充全局类型声明,避免TS类型报错:
declare global { interface Window { $: JQueryStatic jQuery: JQueryStatic } } export {}
内容的提问来源于stack exchange,提问作者coure2011
相关产品推荐
相关产品推荐

