我创建了新的 Rails 7 项目rails new my_project,但在包含要由 Rails 处理的自定义 JS 文件时遇到问题。
我的“javascript/application.js”
import "@hotwired/turbo-rails"
import "controllers"
import "chartkick"
import "Chart.bundle"
import "custom/uni_toggle"
我的自定义 JS 文件:“javascript/custom/uni_toggle.js”
function uniToggleShow() {
    document.querySelectorAll(".uni-toggle").forEach(e => e.classList.remove("hidden"))
}
function uniToggleHide() {
    console.log("uni toggle hide")
    document.querySelectorAll(".uni-toggle").forEach(e => e.classList.add("hidden"))
}
window.uniToggleShow = uniToggleShow
window.uniToggleHide = uniToggleHide
我在我的布局中使用<%= javascript_importmap_tags %>
和我的“config/importmap.rb”
pin "application", 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_all_from "app/javascript/controllers", under: "controllers"
我已经尽可能多地寻找有关在 Rails 7 (7.0.2.3) 中安装 jQuery 的帮助。我想在我的视图中的脚本标签中使用它,但我似乎无法将其导出到全局可用的位置,呃...任何地方。
当然 importmaps 就安装和映射包而言很容易操作。太棒了。之后,整个文档分崩离析,笼罩在这种使用 js 包的新方式上。环顾四周,有很多混乱。
也就是说,我如何添加这个或类似的东西:
import jquery from "jquery"
window.jQuery = jquery;
window.$ = jquery;
到 application.js 或任何让这些全局函数工作的地方,比如 $. 我希望 $ 在我的所有视图中可用。
至于我所做的:
./bin/importmap pin jquery --download
给我 importmap 行:
pin "jquery" # @3.6.0
好的。然后查看 importmap JSON:
{
  "imports": {
    "application": "/assets/application-37a24e4747cc3cde854cbbd628efbdf8f909f7b031a9ec5d22c5052b06207eb8.js",
    "@hotwired/turbo-rails": "/assets/turbo.min-96cbf52c71021ba210235aaeec4720012d2c1df7d2dab3770cfa49eea3bb09da.js",
    "@hotwired/stimulus": "/assets/stimulus.min-900648768bd96f3faeba359cf33c1bd01ca424ca4d2d05f36a5d8345112ae93c.js",
    "@hotwired/stimulus-loading": "/assets/stimulus-loading-1fc59770fb1654500044afd3f5f6d7d00800e5be36746d55b94a2963a7a228aa.js",
    "jquery": "/assets/jquery-498b35766beec7b412bab57a5acbe41761daa65aa7090857db4e973fa88a5623.js",
    "controllers/application": "/assets/controllers/application-368d98631bccbf2349e0d4f8269afb3fe9625118341966de054759d96ea86c7e.js",
    "controllers/hello_controller": "/assets/controllers/hello_controller-549135e8e7c683a538c3d6d517339ba470fcfb79d62f738a0a089ba41851a554.js",
    "controllers": "/assets/controllers/index-7a8fc081f7e391bd7b6fba95a75e36f88ba813da2c4c8787adad248afb9a0a06.js"
  }
}
丁。看来它就在那里。然后在 application.html.erb 中添加一个简单的脚本标签:
<script type="text/javascript" charset="utf-8">
        $(document).ready(function (){
            console.log('jQuery working.');
        })
</script>
失败。检查员说:
(index):41 …我目前使用的是 Rails 6.0.4,我想使用 Stimulus 构建一个新页面。在升级到 Rails 7 之前还有很多工作要做,因此如果可能的话,我想在 Rails 6 中使用导入映射和刺激。但到目前为止我还无法让刺激控制器工作。我按照以下步骤操作:
gem 'importmap-rails'
gem 'stimulus-rails'
rails importmap:install这给了我config/importmap.rb, 和app/javascript/application.js,它在配置文件中被固定为“应用程序”。
application.js文件我的电流application.js在 inside ,所以我暂时app/assets/application.js.coffee将其重命名为并更新为以下内容:old_application.js.coffeeapplication.html.haml
= javascript_include_tag "old_application", defer: true
= javascript_importmap_tags
这似乎有效,当我渲染页面时,它给了我以下导入映射:
{
  "imports": {
    "application": "/assets/application-920fceca960b509c1e98c9b27d167fa368d4b588ceb1be42d1667552714f94d5.js"
  }
}
rails stimulus:install这给了我里面app/javascript/controllers有index.js,application.js和的文件夹hello_controller.js。
它还更新config/importmap.rb为以下内容:
pin "application", preload: true
pin "@hotwired/stimulus", to: "stimulus.min.js", …javascript stimulusjs ruby-on-rails-6 import-maps ruby-on-rails-7
我已经在 importmap-rails gem github 存储库中提出了一个关于此问题的问题,但我想我会在这里抛出这个问题,以防有人可能有解决方法
这是我迄今为止发现的
使用 Rails 7 alpha 2 或 Rails 7.0 生成的新引擎rails plugin new custom_page --mountable --full会生成一个新引擎,该引擎在捆绑的 gem 中包含 importmap-rails gem,但无法使用它。添加spec.add_dependency 'importmap-rails'到enginename.gemspec 没有什么区别,添加arequire importmap-rails到engine.rb 也没有区别。bin 目录中没有 importmap 可执行文件。调用bundle info importmap-rails
产生一个有希望的结果,表明默认情况下安装了 gem
* importmap-rails (0.8.1)
    Summary: Use ESM with importmap to manage modern JavaScript in Rails without transpiling or bundling.
    Homepage: https://github.com/rails/importmap-rails
    Source Code: https://github.com/rails/importmap-rails
    Path: /home/jamie/.rvm/gems/ruby-3.0.0@custom_page/gems/importmap-rails-0.8.1
致电rails --tasks节目
rails app:importmap:install # Setup Importmap for the …我有一个新的 Rails 7 应用程序。我目前正在尝试学习自 Rails 5 以来的所有新功能。我想在我的 javascript 文件中使用以下代码,但到目前为止我收到以下错误:Uncaught ReferenceError: $ is not defined。
$(document).on("turbo:load", () => {
  console.log("turbo!");
});
这是另外两个相关文件。如果我需要发布其他内容,请告诉我。
导入映射.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"
应用程序.js
import "@hotwired/turbo-rails"
import "jquery"
$(document).on("turbo:load", () => {
  console.log("turbo!");
});
我正在尝试在新的 Rails 7 应用程序上使用 Select2,但遇到的困难如下:
我已将其固定到导入映射中并像这样导入:
pin "application", 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_all_from "app/javascript/controllers", under: "controllers"
pin "trix"
pin "@rails/actiontext", to: "actiontext.js"
pin "select2", to: "https://ga.jspm.io/npm:select2@4.1.0-rc.0/dist/js/select2.js"
pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.6.0/dist/jquery.js"
(最后两行是在我运行 bin/importmap pin select2 时添加的)
import "jquery";
import "select2";
import "@hotwired/turbo-rails";
import "controllers";
import "trix";
import "@rails/actiontext";
(已将 jquery 和 select2 移至末尾和开头 - 没有改变任何事情)。
当我处于表单中时,我可以使用 $ 访问元素,如下所示:
$('#book_genre_ids');
...(returns the element)
但是当我在控制台中手动尝试在元素上运行 select2() 时,会发生以下情况: …
我正在尝试加载我的自定义 js。但出现错误。
\n错误如下。
\n无法注册控制器:通知(controllers/notification_controller)错误:无法解析从http://localhost:3000/assets/controllers/notification_contr导入的说明符“@noty”...
\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 javascript\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 controllers\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 application.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 index.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 notification_controller.js\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 lib\n\xe2\x94\x82\xc2\xa0\xc2\xa0 \xe2\x94\x82\xc2\xa0\xc2\xa0     \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 noty.js\nimport { Controller } from "@hotwired/stimulus"\nimport Noty from "@noty"\n\nexport default class extends Controller {\n  static targets = [ 'type', 'message' ]\n\n  ....// some codes.\n\n}\n# Pin npm packages by running ./bin/importmap\n\npin "application", preload: true\npin "@hotwired/turbo-rails", to: "turbo.min.js", preload: true\npin "@hotwired/stimulus", …在应用程序中,我需要从 JS 文件实例化音频文件(我正在使用 AudioContext API),或多或少如下所示:
playAudio(url) {
  this.audioContext = new (window.AudioContext || window.webkitAudioContext)();
  let data = await fetch(url).then(response => response.arrayBuffer());
  let buffer = await this.audioContext.decodeAudioData(data)
  const source = this.audioContext.createBufferSource()
  source.buffer = buffer
  source.connect(this.audioContext.destination)
  source.start()
}
此 JS 文件是在使用 importmap 和 Sprockets 的新 Rails 7 应用程序中加载的 Stimulus 控制器。
在开发环境中,JS 可以猜测路径,因为 Sprockets 将以规范名称(例如/assets/audio/file.wav)来服务资产。然而,在生产中,在资源预编译期间,Sprockets 在文件名后添加一个哈希值,并且只能使用/assets/audio/file-f11ef113f11ef113f113.wav.
该文件名无法进行硬编码,因为它取决于预编译(从技术上讲,我可能可以使用哈希对路径进行硬编码,因为文件不会经常更改,但我不想对此哈希进行任何假设)。
除公共文件夹中的其他资产外,Sprockets 在预编译期间生成的清单中引用了该文件。使用Rails.application.assets_manifest.files我可以访问清单数据并安全地进行映射。
这是我为此编写的助手:
  def audio_assets_json
    audio_assets = Rails.application.assets_manifest.files.select do |_key, file|
      file['logical_path'].start_with?('audio/')
    end
    JSON.pretty_generate(
      audio_assets.to_h { |_k, f| [f['logical_path'], asset_url(f['logical_path'])] } …尝试使用 Rails 7 并导入地图。尝试使用一些自定义 JS 导入文件夹。
# config/importmap.rb
pin_all_from "app/javascript/custom", under: "custom"
# app/javascript/application.js
import "custom"
Uncaught TypeError: Failed to resolve module specifier "custom"在 Chrome 和Uncaught Error: Unable to resolve specifier 'custom' from [shim]Firefox 上提供
有趣的是,import "custom/script"效果很好。
我究竟做错了什么?
因此,我通过执行以下操作来设置我的 Rails 7 应用程序。
rails new .
为了添加引导程序,我使用 importmap (无 webpacker)实现了它,如下所示
./bin/importmap pin bootstrap
加载了这些行(我添加了预加载:true)
pin 'bootstrap', to: https://ga.jspm.io/npm:bootstrap@5.1.3/dist/js/bootstrap.esm.js', preload: true
pin '@popperjs/core', to: 'https://ga.jspm.io/npm:@popperjs/core@2.11.2/lib/index.js', preload: true
然后在我的 application.js 上,我添加了
import "bootstrap"
import "@popperjs/core"
我可以通过执行以下操作来使用 toast 元素
 # toast_controller.js
import { Controller } from "@hotwired/stimulus"
import * as bootstrap from 'bootstrap'
// Connects to data-controller="toast"
export default class extends Controller {
  connect() {
    const toast = new bootstrap.Toast(this.element, {
      delay: 5000,
      animation: true,
      autohide: true
    })
    toast.show()
  }
}
它运行良好,但是当我尝试使用菜单上的工具提示时,我开始遇到引导问题 …