如何使用 Webpack 在 Rails 6 中使 JavaScript 函数全局可用?

How do I make a JavaScript function available globally in Rails 6 with Webpack?

作为 Rails 6 的初学者。每当我单击 Roar Link 时,都会出现以下错误。下面附上以下文件。我只想将自定义文件 (demo.js) 添加到我的代码中,以便我可以在下面的代码中测试 JavaScript 的行为。 Java Rails 5 上的脚本行为不同于 Rails 6.

请给我更好的解决方案,以便我可以解决我的问题。我尝试了所有关于堆栈溢出的答案。

Application.html.erb (views/layouts/application.html.erb)

<!DOCTYPE html>
<html>
  <head>
    <title>SimpleCms</title>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    
  </head>

  <body>
    <%= yield %>
  </body>
</html>

demo.js (app/javascript/packs/demo.js)

function jsRoar(name) {
    alert('I am ' + name + '. Hear me roar!');
  }

application.js (app/javascript/packs/application.js)

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

index.html.erb (views/demo/index.html.erb)

<h1>This is the index Page</h1>
<br/>
<%= link_to('All Subjects',subjects_path) %>

<%= link_to('Roar', '#', :onclick => "jsRoar('JavaScript'); return true;") %>

demo_controller.rb

class DemoController < ApplicationController
  
  layout 'application'
  
  def index
  render ('index')
  end

  def hello
  render ('hello')
  end

end

GEM 文件

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.6'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.3', '>= 6.0.3.2'
# Use mysql as the database for Active Record
gem 'mysql2', '>= 0.4.4'
# Use Puma as the app server
gem 'puma', '~> 4.1'
# Use SCSS for stylesheets
gem 'sass-rails', '>= 6'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '~> 4.0'
# Turbolinks makes navigating your web application faster. Read more: 
https://github.com/turbolinks/turbolinks
gem 'turbolinks', '~> 5'
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
gem 'jbuilder', '~> 2.7'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.2', require: false

group :development, :test do
  # Call 'byebug' anywhere in the code to stop execution and get a debugger console
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  # Access an interactive console on exception pages or by calling 'console' anywhere in the code.
  gem 'web-console', '>= 3.3.0'
end

group :test do
  # Adds support for Capybara system testing and selenium driver
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  # Easy installation and use of web drivers to run system tests with browsers
  gem 'webdrivers'
end

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

您正在考虑使用旧方法。我已经在这里解释过了:

这是一种更现代的方法来完成您正在尝试的事情。

<%= link_to('Roar', '#', data: {roar: 'JavaScript'}) %>

在demo.js中:

document.addEventListener("turbolinks:load", function() {
  document.querySelectorAll('[data-roar]').forEach(function(roaring_link) {
    roaring_link.addEventListener('click', function(event) {
      let name = roaring_link.dataset['roar']
       alert('I am ' + name + '. Hear me roar!');
       event.preventDefault();
       event.stopPropagation();
       return false;
    });
  });
});

请注意 demo.js 中的代码是 self-contained,只需查看文档并将所需的功能附加到链接即可。您可以通过添加一个包含您希望传递给 javascript 函数的数据的数据属性来指定这些链接。

这可能看起来很复杂,但掌握了它之后,您会发现您的 javascript 非常干净且易于维护。