我在使用 Webpacker 的 Rails 6 应用程序中有以下 Javascript 结构。
app/javascript
+ packs
- application.js
+ custom
- hello.js
下图是上述JS文件中的内容
app/javascript/custom/hello.js
export function greet(name) {
console.log("Hello, " + name);
}
app/javascript/packs/application.js
require("@rails/ujs").start()
require("jquery")
require("bootstrap")
import greet from '../custom/hello'
config/webpack/environment.js
const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
environment.plugins.prepend('Provide',
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
Popper: ['popper.js', 'default']
})
)
module.exports = environment
现在在我的 Rails View 中,我正在尝试使用导入函数 greet
,如下所示
app/views/welcome/index.html.haml
- name = 'Jignesh'
:javascript
var name = "#{name}"
greet(name)
当我加载 View 时,我在浏览器的控制台中看到了 ReferenceError: greet is not defined
错误。
我试图寻找这个问题的解决方案,并在网上找到了很多资源,但没有一个对我有帮助。最后当我在我发现的建议中起草这个问题时 How to execute custom javascript functions in Rails 6这确实接近我的需要但是解决方案显示了一个解决方法,但我正在寻找一个合适的解决方案因为我有很多 View 需要将数据从 Rails View 传递到要移动的 JS 函数app/javascript/custom
文件夹下的自定义文件。
此外,如果有人能帮助我理解我遇到的 ReferenceError
背后的原因,我将不胜感激。
注意:
我不精通 Node 领域的 Javascript 开发,也是 Webpacker、Webpack、Javascript 模块、import
、export
、require
语法等,所以如果您发现我所问的内容有任何愚蠢之处,请多多包涵。我在尝试升级现有 Rails 应用程序以使用版本 6 时遇到了上述情况。
最佳答案
默认情况下,Webpack 不会让模块在全局范围内可用。也就是说,有几种方法可以让您在 AJAX 请求之外将信息从 Ruby 传递到 JavaScript:
window.greet = function() { ... }
并按照您的建议从 View 调用函数是一个选项。我不喜欢在很多地方编写副作用代码,所以这是我最不喜欢的。你可以看看使用
expose-loader
.这意味着自定义您的 webpack 配置以将选定模块中的选定功能“公开”到全局范围。它可以很好地适用于少数情况,但对于许多用例来说会变得乏味。从您的入口点导出选定的函数并配置 webpack 以打包 your bundle as a library .如果您更喜欢从 View 调用全局函数,这是我最喜欢的方法。 I've written about this approach specifically for Webpacker on my blog .
// app/javascript/packs/application.js export * from '../myGlobalFunctions' // config/webpack/environment.js environment.config.merge({ output: { // Makes exports from entry packs available to global scope, e.g. // Packs.application.myFunction library: ['Packs', '[name]'], libraryTarget: 'var' }, })
// app/views/welcome/index.html.haml :javascript Packs.application.greet("#{name}")
采用完全不同的方法,将 Ruby 变量附加到 Controller 中的全局对象,例如
gon
gem .假设您按照说明设置 gem,gon
对象既可以作为 Ruby 对象使用,您可以在服务器端改变它,也可以在您的 JavaScript 代码中作为全局变量来读取。您可能需要想出一些其他方法来有选择地调用 greet 函数,例如对仅在给定页面或给定 url 上呈现的特定选择器进行 DOM 查询。# welcome_controller.rb def index gon.name = 'My name' end
// app/javascript/someInitializer.js window.addEventListener('DOMContentLoaded', function() { if (window.location.match(/posts/)) { greet(window.gon.name) } })
关于javascript - Rails 6 Webpacker 从 Rails View 调用 javascript 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61777360/