使用 Rails 6,你把“页面特定”的 JavaScript 代码放在哪里?

Ada*_*ner 21 ruby-on-rails webpacker ruby-on-rails-6

我的问题与使用 Rails 3.1相同,您将“特定于页面的”JavaScript 代码放在哪里?,仅适用于 Rails 6 而不是 Rails 3.1。

假设我有一些 JavaScript 想要用于我的帖子索引页面。我把那个文件放在哪里,我如何包含它?

在上一个问题中,答案通常使用 Rails Asset Pipeline。但是,对于 Rails 6,我的理解是它使用 webpacker 而不是 JavaScript 文件的 Asset Pipeline。

注意:我不希望始终包含该文件。例如。如果我在作者索引页上,我不希望包含帖子索引页的 JavaScript 文件。为什么?想象一下,我$('li').on('click', changeColor);在 JS 文件中拥有帖子索引页面。我可能不希望该代码在作者索引页上运行,但如果包含该文件,它就会运行。您可以通过命名空间来解决这个问题,但我认为不包含不必要的文件会更干净(并且性能更高)。

ros*_*sta 18

我将按照 Webpack 和 Webpacker 体验的难度级别的顺序描述一些选项。

  1. 忘记页面特定的 JavaScript 并将所有内容放入application.js包中。这绝对是最容易理解的方法。对于一个小型应用程序,权衡可能是值得的,因为拥有一个更易于维护的应用程序可能会超过学习如何最好地使用 Webpack 拆分您的 JS 代码而几乎没有性能提升的额外成本。

  2. 使用动态导入延迟加载特定于页面的代码。在这种情况下,您仍会将所有 JavaScript 放在application.js依赖关系图中,但并非所有这些代码都会预先加载。Webpackimport()在编译您的 JS 时识别动态函数,并将导入的块拆分为一个单独的文件,该文件可以使用 JS 框架路由器或简单的触发器在浏览器中按需加载。

    例如,您的代码可能如下所示:

    if (document.querySelectorAll(".post-index").length) {
      import("./post/index") // webpack will load this JS async
    }
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用网页特定的“包”结合splitChunks配置API。在这种情况下,application.js您可以为要区别对待的每个页面构造一个包,而不是使用包,例如posts.jsadmin.js等。使用 splitChunks 插件意味着您的包可以正确共享代码。我强烈建议您谨慎使用这种方法,直到您了解 Webpack 的工作原理或愿意在选择此路径时经历学习 Webpack 的过程。Webpack 通常在假设您每页只使用一个入口点的情况下效果最佳,否则,除非您知道自己在做什么,否则最终可能会跨包重复代码。


小智 7

让我们在一个空的 Rails 6 应用程序中浏览这个目录的内容。

? tree app/javascript
app/javascript
??? channels
?   ??? consumer.js
?   ??? index.js
??? packs
    ??? application.js

2 directories, 3 files
Run Code Online (Sandbox Code Playgroud)

packs 目录对我们很重要,所以让我们看看它包含什么。

? tree app/javascript
app/javascript
??? channels
?   ??? consumer.js
?   ??? index.js
??? packs
    ??? application.js

2 directories, 3 files
Run Code Online (Sandbox Code Playgroud)

webpack 有一个入口点的概念,即它开始编译 JavaScript 代码时首先查找的文件。

Webpacker gem 在 app/javascript/packs 下以这个 application.js 文件的形式创建应用程序包。如果你还记得资产管道,这个文件相当于 app/assets/javascripts/application.js 文件

简单的例子

如何将 Javascript 添加到 Ruby on Rails(将 Javascript 添加为模块):

  1. 在 Javascript 路径中创建文件夹,app/javascript例如:'post'

  2. 将您的 javascript 文件添加到 index.js 等文件夹中

  3. 添加post模块app/javascript/application.js->require('post')

    require("@rails/ujs").start() require("turbolinks").start() require("@rails/activestorage").start() require("channels") require("post")

添加 post 模块后,让我们在 Rails 6 应用程序中查看此目录的内容

? tree app/javascript
app/javascript
??? channels
?   ??? consumer.js
?   ??? index.js
??? packs
|    ??? application.js
|??? post
     |__ index.js
Run Code Online (Sandbox Code Playgroud)

这种使用 webpack 的简单方法与旧 Rails 风格相同。

  • 我忘记在问题中提及这一点(我将更新问题以包含它),但通过这种方法,似乎“app/javascript/post/index.js”将始终包含在内,而我只想当您位于特定页面时将其包含在内。例如,我不希望在您访问作者索引页面时包含它,因为代码可能存在冲突。 (2认同)