Javascript Rails,webpacker:在类中何时何地使用import语句,以及what';在pack/application.js中要求的目的是什么?
我正在将一个较旧的应用程序升级到Rails 6,它使用Javascript Rails,webpacker:在类中何时何地使用import语句,以及what';在pack/application.js中要求的目的是什么?,javascript,es6-modules,webpacker,ruby-on-rails-6,Javascript,Es6 Modules,Webpacker,Ruby On Rails 6,我正在将一个较旧的应用程序升级到Rails 6,它使用webpacker进行所有JS资产管理 我正在使用pikaday日历库,并通过warn add pikaday添加它,验证它是否显示在packages.json中,然后通过require(“pikaday”)将它添加到我的app/javascript/packs/application.js 我有一个名为Datepicker的JS类,用于抽象实际的pikaday日历。我这样做是因为有一天我可能会更改datepicker实现,这样我只需更改一个
webpacker
进行所有JS资产管理
我正在使用pikaday
日历库,并通过warn add pikaday
添加它,验证它是否显示在packages.json
中,然后通过require(“pikaday”)将它添加到我的app/javascript/packs/application.js
我有一个名为Datepicker
的JS类,用于抽象实际的pikaday
日历。我这样做是因为有一天我可能会更改datepicker实现,这样我只需更改一个类,而不必更新我所有的pikaday
调用
但是,在application.js
pack文件中是否需要(“pikaday”)
似乎并不重要;只要我在引用它的类中从“Pikaday”
导入Pikaday,就没有什么区别
问题
我正试图了解正在发生的事情
app/javascript/pack/application.js
文件中添加require(“pikaday”)
或从“pikaday”
导入pikaday?为什么Datepicker
类。我问这个问题的原因是因为我有10多个这样的类,在我想在其中使用的每个JS文件的顶部都有10+import
语句,这有点烦人。我总是想访问某些类。我使用过webpacker ProvidePlugin功能,但它抱怨Datepicker
不是构造函数,所以我可能遗漏了一些东西,但我没有足够的知识知道是什么你问了几个问题:
Pikaday
从“Pikaday”导入Pikaday即可。在这种情况下,您只需要在自定义日期选择器模块中进行此导入。您可以从application.js包文件中删除require(“pikaday”)
原因是Webpack将把application.js包作为依赖关系图的入口点;从那里开始,它将递归地遍历每个必需/导入的模块,查找这些模块的依赖项,依此类推,直到所有声明的模块都包含在包中。由于您在application.js包中声明了import'custom/datepicker'
,并且custom datepicker导入了pikaday
,因此它将作为依赖项包含在包中export default…
,因此您的自定义Datepicker
将编译为ES模块(而是Web包的ES模块实现)。这对ProvidePlugin的工作方式很重要。从:
要导入ES2015模块的默认导出,必须指定模块的默认属性
这意味着Datepicker
插件项的网页包配置如下所示(使用Rails网页包环境api):
const{environment}=require(“@rails/webpacker”)
const webpack=require('webpack')
const{resolve}=require('path');
environment.plugins.append('Provide',new webpack.ProvidePlugin({
日期选择器:[解析('app/javascript/custom/Datepicker'),'default']
}))
module.exports=环境
意见:也就是说,我鼓励您明确导入,例如在引用Datepicker
的每个模块中,从“custom/Datepicker”导入Datepicker。即使是重复的,它也会变得更容易与ESlint之类的工具集成,而ESlint与某些代码编辑器一起,可以提供有关编译错误的内联反馈,并且更容易在每个模块中声明显式依赖项进行设置我在这里使用您的定制日期选择器和ProvidePlugin制作了一个Pikaday的工作演示:感谢您的详细回复和回复,非常感谢!我有一个快速跟进的问题。在Rails中使用资产管道时,它似乎只是将所有单独的JS文件合并到一个大文件中,这样,如果我在文件的前面定义
class Datepicker{…}
,我可以在文件的后面全局引用它。当webpack将所有JS组合到一个包中时,它不是做了同样的事情吗?我不能引用以前定义的类吗?除了复制/粘贴工作解决方案之外,我还试图了解正在发生的事情。简单的回答是不,Webpack在这方面不像Sprocket。默认情况下,按Webpack捆绑的导出在全局范围内不可用。Webpack将所有内容视为一个模块。出于许多原因,这样做更好。有关这意味着什么的更多信息:。有关链轮和网页包之间差异的更多信息:。视频非常有用!你揭示了我自己的许多痛点。链轮和webpacker是解决同一问题的两种截然不同的方法。当我切换到webpacker时,我需要对我的JS代码进行更多的挖掘和重构。谢谢
import Pikaday from "pikaday"
export default class Datepicker {
constructor(element, options) {
if (options == null) { options = {} }
// Store DOM element for reference
this.element = element
// Do not re-run on elements that already have datepickers
if (this.element.datepicker === undefined) {
options = Object.assign({},
this.defaultOptions(),
options
)
const picker = new Pikaday(options)
// Store picker on element for reference
this.element.datepicker = picker
return picker
} else {
console.log("Datepicker already attached")
return
}
}
// Overridden by `options` in constructor
defaultOptions() {
return {
field: this.element,
format: "M/D/YYYY",
bound: true,
keyboardInput: false,
showDaysInNextAndPreviousMonths: true
}
}
}
require("@rails/ujs").start()
require("turbolinks").start()
require("moment")
// Note: if using `@rails/ujs`, you do not need to use `jquery-ujs`.
import "jquery"
// Does not matter if I require this or not, as long as it is imported in the
// class file, I can remove this require statement and everything still works.
require("pikaday")
// StimulusJS
// Webpack's `require` looks for `controllers/index.js` by default
require("controllers")
require("custom/datepicker")