Rails 6 - 加载自定义 JS 文件的正确方法是啥?

Posted

技术标签:

【中文标题】Rails 6 - 加载自定义 JS 文件的正确方法是啥?【英文标题】:Rails 6 - what is the proper way to load custom JS files?Rails 6 - 加载自定义 JS 文件的正确方法是什么? 【发布时间】:2021-07-24 12:47:09 【问题描述】:

我很难正确配置和设置我自己的 JS 文件,其中包含用于特定任务的 JS 函数。

我浏览了一些文章,发现我需要将我的自定义 JS 放到 JS packs 文件夹中 -> app/javascript/packs/currency_calculations.js:

currency_calculations.js

function convert_curr(from, to) 
  ...


function show_convertion(curr) 
  ...

...

然后我尝试将此自定义 JS 文件添加到 app/javascript/packs/application.js:

import Rails from "@rails/ujs";
import "@hotwired/turbo-rails";
import * as ActiveStorage from "@rails/activestorage";
import "channels";
import "controllers";

Rails.start();
ActiveStorage.start();

import "stylesheets/application";

// my custom JS file
import "packs/currency_calculations" // I also tried import "currency_calculations" -- same result

我还尝试将以下内容添加到 application.html.erb 文件中:

 = javascript_pack_tag 'currency_calculations'

它也没有用。

我仍然收到此错误:

Uncaught Error: Cannot find module 'currency_calculations'

当尝试从视图调用函数时,则:

Uncaught ReferenceError: convert_curr is not defined

连接它的正确方法是什么?我从 Rails 5 开始使用将我所有的 JS 函数放到一个 js 文件中,而这个文件只是为了添加到 app/assets/javascripts/application.js 中,如下所示:

//= require currency_calculations

然后,在一个视图中,我可以简单地调用想要的 JS 函数,如 convert_curr("a", "b")

提前谢谢你。

【问题讨论】:

【参考方案1】:

一些可能对您有帮助的 cmets:

1 ) 当你将一个 js 文件放在 /packs 时,它将被编译为一个独立的资源,你可以使用 javascript_pack_tag 引用,所以你不需要将它添加到 application.js 包中

根据您的需要,您有两种选择:

将文件移动到 javascript/src/currency_calculations.js 并将其导入您的 application.js 为 import 'src/currency_calculations'import '../src/currency_calculations' 将其作为一个包使用,将其从 application.js 中删除并像 javascript_pack_tag 'currency_calculations' 一样使用加载它

(您可以在 application.js 和作为独立包中加载文件,但您将获得两次代码)

2 ) 如果您想在视图中访问该文件中的功能,则不能像 sprocket 那样做。 sprockets 将该文件的内容添加到全局范围内,而 webpacker 包含捆绑上下文中的函数。如果您希望这些功能在您的视图中全局可用,则必须使它们全局化,例如

global.convert_curr = function(from, to) 
  ...

(你也可以使用window.convert_curr = ...

【讨论】:

【参考方案2】:

在 Rails 6 中有几种方法可以做到这一点。

首先是创建一个自定义目录并在 application.js 文件中要求它。在这种情况下,您可以像这样创建一个目录:

app/javascript/custom/currency_calculations.js

然后你需要在你的 application.js 文件中要求它:

// app/javascript/packs/application.js

// ...

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

require("custom/currency_calculations")

如果您将自定义文件夹命名为“货币”,然后将 .js 文件命名为 index.js,那么同样的方法也可以简化。

你可以这样称呼它:

require("currency")

Require 默认会在文件夹中查找索引文件。但在这种情况下,索引文件必须存在,否则会失败。

如果您不希望 JS 与其他所有内容一起编译,另一种方法是使用 javascript_pack_tag。

在这种情况下,请将 js 文件添加到您的 app/javascript/packs 目录中。然后在需要的地方使用 pack 标签助手,例如:

<%= javascript_pack_tag 'currency_converter' %>

我要提到的最后一件事...您确定不需要其他库来使其工作(例如 JQuery)吗?在这种情况下,您需要先安装该库并将其导入您的 application.js,然后再调用您尝试执行的 js 文件。

【讨论】:

【参考方案3】:

我认为问题在于您没有在 js 文件中导出任何内容。尝试在 currency_calculations.js 中执行此操作

const funcs = 
   convert_curr()  console.log('foo') , 
   show_convertion()  console.log('bar') ,


export default funcs;

然后在您的代码中使用funcs.convert_curr() 调用它们

另外,currency_calculation 似乎不应该是它自己的包(你可以认为一个包有点像 sprockets 中的 application.js),所以最好只是包目录之外的独立 js 文件。 (可以是javascript/currency_calculations.jsjavascript/utils/currency_calculations.js)

【讨论】:

以上是关于Rails 6 - 加载自定义 JS 文件的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

加载资源失败:404(未找到)- Rails 自定义字体

将 Bootstrap 主题(带有自定义 CSS 和 JS 插件)与带有 Webpacker 和 Yarn/NPM 的 Rails 6 集成

Rails 6 javascript文件没有正确抓取html元素

Rails webpack 错误:第 3 方 gem 无法解析 jQuery

用于 JavaScript 的 Rails 3.1 资产管道

Rails + 延迟作业:存储自定义作业类的正确位置在哪里?