You need to enable JavaScript to run this app. Ruby on Rails切换Webpacker后内联脚本报JQuery not defined如何解决?
优惠活动
大模型
产品
解决方案
定价
更多

Ruby on Rails切换Webpacker后内联脚本报JQuery not defined如何解决?

问题核心原因
  1. Rails的webpacker默认给javascript_pack_tag添加了defer属性,意味着webpack打包的代码会等到整个HTML DOM解析完成、所有内联JS执行完毕后才运行,你写在slim模板中的内联JS执行时,webpack暴露到全局的$还没有挂载,所以抛出未定义错误。
  2. application.html.slim中存在重复引入冲突:你已经在webpack中完整配置了jQuery,又额外通过javascript_include_tag 'jquery'从sprockets引入jQuery,两处引入的jQuery变量隔离,也会导致全局变量异常。
解决方案

按顺序执行以下操作即可解决:

  1. 删除冗余引入:直接删掉application.html.slim中的= javascript_include_tag 'jquery'行,避免重复加载jQuery导致的冲突。
  2. 修复执行顺序问题,二选一即可:
    • 方案A(推荐,改造成本最低):关闭webpacker的默认defer加载,将= javascript_pack_tag 'application'修改为:
      = javascript_pack_tag 'application', defer: false
      
      这样webpack打包的代码会在加载完成后立刻执行,早于后续body中内联JS的运行时机,全局$会提前挂载完成。
    • 方案B(保留defer特性):所有模板中的内联JS都包裹在DOMContentLoaded事件监听中,等webpack代码执行完成后再运行,比如_comments.slim中的内联代码修改为:
      document.addEventListener('DOMContentLoaded', function() {
        $(function(){
          var commentId = "#{ params[:comment_id] }";
          if(commentId) {
            var $comment = $('#' + commentId);
            $comment.get(0).scrollIntoView();
            $comment.addClass('notified');
          }
        });
      })
      
  3. 可选配置优化:当前environment.js中的ProvidePlugin存在重复配置,可以合并简化,避免后续维护混乱:
    合并两个ProvidePlugin的配置,删除单独的jquery插件引入,修改后的environment.js对应部分如下:
    environment.plugins.append(
      "Provide",
      new webpack.ProvidePlugin({
        $: "jquery",
        jQuery: "jquery",
        "window.jQuery": "jquery",
        "window.Tether": "tether",
        Popper: ["popper.js", "default"],
      })
    );
    // 可删除以下冗余行
    // environment.plugins.prepend("jquery", jquery);
    

内容的提问来源于stack exchange,提问作者Antarr Byrd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.12 21:03:04