如何使用 importmap 在 Rails 7 中安装 jQuery?

dav*_*mcd 10 jquery ruby-on-rails import-maps

我有一个新的 Rails 7 应用程序。我目前正在尝试学习自 Rails 5 以来的所有新功能。我想在我的 javascript 文件中使用以下代码,但到目前为止我收到以下错误:Uncaught ReferenceError: $ is not defined

$(document).on("turbo:load", () => {
  console.log("turbo!");
});
Run Code Online (Sandbox Code Playgroud)

这是另外两个相关文件。如果我需要发布其他内容,请告诉我。

导入映射.rb

pin "application", preload: true
pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js", preload: true
pin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", preload: true
pin "@hotwired/stimulus-loading", to: "stimulus-loading.js", preload: true
pin "el-transition", to: "https://ga.jspm.io/npm:el-transition@0.0.7/index.js"

pin_all_from "app/javascript/controllers", under: "controllers"
Run Code Online (Sandbox Code Playgroud)

应用程序.js

import "@hotwired/turbo-rails"
import "jquery"

$(document).on("turbo:load", () => {
  console.log("turbo!");
});
Run Code Online (Sandbox Code Playgroud)

Ale*_*lex 19

只需切换到jspm以外的 CDN ,jQuery在导入时将是全局的:

# config/importmap.rb

# NOTE: pin jquery to jsdelivr instead of jspm
pin "jquery", to: "https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.js"
Run Code Online (Sandbox Code Playgroud)
// app/javascript/application.js

import "jquery"; // this import first
import "script"; // then your other imports that use `$`

// NOTE: don't use relative imports: `import "./script"`
//       add `pin "script"` to `importmap.rb`

console.log($); // ok
Run Code Online (Sandbox Code Playgroud)
// app/javascript/script.js
console.log($)  // ok
Run Code Online (Sandbox Code Playgroud)

一切都正常,一次导入,多次导入,jquery 插件。无需额外吊装。


使用 jspm 时,必须在需要时显式导入jQuery ,就像任何其他模块一样:

// app/javascript/script.js
console.log($)  // ok
Run Code Online (Sandbox Code Playgroud)

澄清并window平息事情。它与刺激一起工作,因为控制器是通过动态导入的import(),该动态通常在加载 jquery 之后运行,并且有时间将其分配给window,但这并不能保证。这就是为什么你必须做提升工作以确保$在任何其他进口之前成为全球性的。

  • @FredWillmore `jspm` 用于 ESM 模块。由于模块的构建/初始化方式“$”和“jQuery”不会[暴露](https://github.com/jquery/jquery/blob/3.6.3/src/exports/global.js #L30-L32)全球范围内。我想还涉及一些额外的处理,因为这个[部分](https://github.com/jquery/jquery/blob/3.6.3/src/wrapper.js#L18-L37)是[更改](https ://jspm.dev/npm:jquery@3.6.3!cjs) 并且不再有全局 jquery。(jsdelivr 也有 esm 选项,其作用相同)。 (4认同)
  • 哦,我发现他们非常不同。这对任何人来说有何意义 (3认同)

Jua*_*ora 8

按照其他答案所说的操作会起作用,但是当您固定新包时它将停止工作。

原因是所谓的 javascript 提升工作方式,这意味着它将重新排序代码,您必须重新组织块中的导入。这将破坏 jQuery 窗口分配。

为了避免这种情况,请提取

import jquery from "jquery"
window.jQuery = jquery
window.$ = jquery
Run Code Online (Sandbox Code Playgroud)

在另一个文件中并在单次导入时调用它。

就我而言,我有:

应用程序.js

import "./src/jquery"

$(function(){
  console.log("Hey!")
})
Run Code Online (Sandbox Code Playgroud)

和 src/jquery.js 以及上面的代码。

  • 这个答案的赞成票较少,但它是更好的答案。即使有多个引脚,这也适用。谢谢分享! (2认同)