如何在Webpack Rails项目中初始化Bootstrap Popover及解决初始化失败问题
解决Bootstrap Popover初始化报错:Uncaught TypeError: bootstrap.Popover is not a constructor
我之前在Rails项目里也碰到过完全一样的问题!这个错误基本是两个核心原因导致的:要么Bootstrap没有正确暴露全局的bootstrap对象,要么没处理好Turbolinks的页面加载时机。下面给你几个可行的解决方案:
1. 正确暴露Bootstrap全局对象(或按需导入组件)
当你用import 'bootstrap'这种方式导入时,默认是ES模块模式,不会自动把Bootstrap挂载到window对象上,所以你的test_popover.js里直接调用bootstrap.Popover会找不到构造函数。
方案A:手动挂载全局对象
修改packs/application.js里的Bootstrap导入代码:
require("@rails/ujs").start() require("turbolinks").start() require("@rails/activestorage").start() require("channels") // 改成这样导入并挂载到window import * as bootstrap from 'bootstrap'; window.bootstrap = bootstrap; import '../javascripts/test_popover';
这样window.bootstrap就存在了,你的原有test_popover.js代码就能正常运行。
方案B:按需导入Popover组件(更推荐,符合你精简体积的需求)
直接在test_popover.js里导入需要的Popover组件,不用依赖全局对象:
// 只导入需要的Popover(Bootstrap 5会自动关联依赖的Popper) import { Popover } from 'bootstrap'; // 用Turbolinks的加载事件包裹初始化代码 document.addEventListener('turbolinks:load', function() { // 用ES6扩展语法替代slice.call,更简洁 const popoverTriggerList = [...document.querySelectorAll('[data-bs-toggle="popover"]')]; popoverTriggerList.forEach(popoverTriggerEl => { new Popover(popoverTriggerEl); }); });
2. 确保安装了Popper依赖
Bootstrap 5的Popover、Tooltip这类组件依赖@popperjs/core,如果没安装的话也会导致初始化失败。执行以下命令安装:
# npm npm install @popperjs/core # 或者yarn yarn add @popperjs/core
3. 处理Turbolinks的加载时机
因为你的项目用了Turbolinks,它会让页面不刷新就完成导航,普通的DOMContentLoaded事件只会在第一次页面加载时触发,后续Turbolinks跳转时不会重新执行初始化代码。所以必须把初始化代码包裹在turbolinks:load事件里,确保每次页面加载(包括Turbolinks导航)都能正确初始化Popover。
按照上面的步骤调整后,你的Popover应该就能正常工作了!
内容的提问来源于stack exchange,提问作者Ken Ratanachai S.
相关产品推荐
相关产品推荐

