【问题标题】:Whats the best way to manage JavaScript with Ruby on Rails 6?使用 Ruby on Rails 6 管理 JavaScript 的最佳方式是什么?
【发布时间】:2020-04-28 20:40:32
【问题描述】:

我正在尝试 RoR 6(我来自 MEAN,但我没有接触过版本 3 的 RoR),但在寻找管理 JavaScript 代码的最佳方法时遇到了一些麻烦。也许是因为我的背景。

我已经阅读了很多关于该主题的内容(包括官方指南https://guides.rubyonrails.org/working_with_javascript_in_rails.html),但似乎官方文档已经过时了。

根据文档,当您从 cli 生成控制器时,它应该为该控制器创建一个 .js 文件,但它不会发生。此外,现在 Webpack 已经被添加到 RoR 6 并且 JavaScript 不再由 Asset Pipeline 管理(我对吗?)但是没有任何关于这件事的参考。

我想找到一种方法来为每个视图编写代码 JS 并将该代码与其他代码隔离。

  • 我应该把所有的JS代码放在哪里?
  • 如何隔离每个视图的 JS 代码?
  • 由于 Bootstrap(通过使用 Yarn)和 Webpack 这种方式,我已将 jQuery 添加到项目中,但 $ 或 jQuery 未定义:
const { environment } = require('@rails/webpacker')

const webpack = require("webpack")

environment.plugins.append("Provide", new webpack.ProvidePlugin({
  $: 'jquery',
  jQuery: 'jquery',
  Popper: ['popper.js', 'default']
}))

module.exports = environment

我将不胜感激。

谢谢!

解决方案:

我找到了我要找的东西 --> https://stimulusjs.org

由 Basecamp 创建的 Stimulusjs 为每个 HTML 视图添加了一个 JS 层,让我们在编写 JS 代码时保持秩序和清晰。它将 JS 文件与 DOM 连接起来,仅此而已。足以添加一些 JS 来改进功能。

它与 Turbolinks 完美搭配,可以与 Webpack 一起使用。此外,它可以在 10 分钟内学会(不再)。安装也非常简单。

无论如何,如果你需要了解一些关于 RoR 和 Webpack/Webpacker 的知识,你可以访问这些链接:

最后,如果你不想使用像 Stimulus 这样的 JS 框架来管理 RoR 下的 JS 代码,你可以随时为特定页面 JS 尝试这些 gem:

【问题讨论】:

    标签: javascript jquery ruby-on-rails webpack ruby-on-rails-6


    【解决方案1】:

    对 Webpack 的更改是非常新的,文档还没有完全跟上。

    在运行生成器时生成资产文件仅使用旧资产管道完成,即便如此也不是一个好主意。它依赖于 Sprockets 特殊的 require_tree 指令,该指令将吞食目录中的所有文件并将它们添加到清单中。按字母顺序,因此您无法控制执行顺序。

    它还让初学者误以为他们放入 users.js 的 js 只在他们的用户控制器中执行,而实际上它只是被整合到一个清单中。

    使用 Webpack,您可以显式导入资产。

    我应该把所有的JS代码放在哪里?

    我们鼓励您将实际的应用程序逻辑放在app/javascript 内的相关结构中。

    如何隔离每个视图的 JS 代码?

    虽然您可以在视图本身中使用 javascript_pack_tag 来要求特定文件,但这并不是一个真正的习惯用法,因为它会创建不必要的 HTTP 请求和难以遵循的逻辑。

    如果您想确保在加载特定视图时执行代码,您可以将数据属性添加到 body 标签并创建特殊事件:

    # app/layouts/application.html.erb
    <body data-action="<%= action_name >" data-controller="<%= controller_name %>">
    

    // fired when turbolinks changes pages.
    $(document).on('turbolinks:load', ()=>{
      let data = $(body).data();
      // replace myns with whatever you want
      $(this).trigger(`myns:${data.controller}`, data)
             .trigger(`myns:${data.controller}#${data.action}`, data)
             .trigger(`myns:#${data.action}`, data)
    });
    

    然后,您可以通过侦听您的自定义事件来包装特殊页面加载时应该发生的功能。

    $(document).on('myns:users#show', ()=>{
      console.log("We are on users#show");
    });
    

    【讨论】:

    • 我将忽略您的 jquery 问题,因为这已经回答了 2 个问题并在其他地方得到了回答。
    • 感谢您的回答。它澄清了我一些重要的概念。 jQuery 已经在工作,我已经尝试过您的解决方案,仅在加载特定视图时才运行代码,但我必须遗漏一些东西。我将触发代码放在 app/javascript 下的 application.js 中引用的 index.js 中。这个 index.js 应该会触发事件,我可以在控制台中确认事件的名称(kigen:registrations#new)。我在 new.js 中有监听器,它也在 application.js 中引用,在索引之后,它不打印任何东西。
    • 我必须对其进行测试。它是对我很久以前写的一个包含这个成语的 gem 的记忆快速而草率的重写。 github.com/maxcal/pagescript
    • 没问题,我去看看。感谢您的帮助!
    • 啊,我发现了这个问题。该事件是turbolinks:load 而不是turbolinks:change
    猜你喜欢
    • 2011-05-06
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多