我正在将旧应用程序升级到 Rails 6,它使用 webpacker
用于所有 JS Assets 管理。
我正在使用 pikaday
日历库,并已通过 yarn add pikaday
添加,已验证它显示在 packages.json
中然后添加到我的app/javascript/packs/application.js
通过 require("pikaday")
.
我有一个名为 Datepicker
的 JS 类我用来抽象实际的 pikaday
日历。我这样做是因为有一天我可能会更改 datepicker 实现,这样我只需要更改一个类而不是更新我所有的 pikaday
来电。
但是,我是否 require("pikaday")
似乎并不重要。在 application.js
是否打包文件;只要我import Pikaday from "pikaday"
在我引用它的类中,它没有区别。
问题
我试图了解正在发生的事情。
require("pikaday")
或 import Pikaday from "pikaday"
在 app/javascript/pack/application.js
文件?为什么或者为什么不? import CLASS from "class_file"
在每个引用它的 JS 文件上?在我的示例中,我想使用 Datepicker
在多个地方上课。我问的原因是因为我有10+这样的课,10+有点烦import
我想在其中使用的每个 JS 文件顶部的语句。有些类我总是想访问。我玩过 webpacker ProvidePlugin 功能,但它提示 Datepicker
不是构造函数,所以我可能遗漏了一些东西,但我没有足够的知识知道什么。 应用程序/javascript/custom/datepicker.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
}
}
}
应用程序/javascript/packs/application.js
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")
最佳答案
你问了几个问题:
import Pikaday from 'pikaday'
在您引用导入变量的文件中,Pikaday
.在这种情况下,您只需要在自定义日期选择器模块中进行此导入。您可以删除 require("pikaday")
从您的 application.js 包文件中。这样做的原因是 Webpack 会将您的 application.js 包作为依赖关系图的入口点;从那里开始,它将递归遍历每个必需/导入的模块,查找这些模块的依赖关系,依此类推,直到所有声明的模块都包含在包中。由于您已声明
import 'custom/datepicker'
在 application.js 包中,自定义日期选择器导入 pikaday
,它将作为依赖项包含在包中。 Datepicker
被编译为 ES 模块(更确切地说,Webpack 的 ES 模块实现),因为您使用的是 ES 模块语法 export default ...
.这对 ProvidePlugin 的工作方式很重要。来自 Webpack 4 documentation of ProvidePlugin
:For importing the default export of an ES2015 module, you have to specify the default property of module.
这意味着您为
Datepicker
的插件条目的 Webpack 配置看起来像这样(使用 Rails Webpacker 环境 api):const { environment } = require('@rails/webpacker')
const webpack = require('webpack')
const {resolve} = require('path');
environment.plugins.append('Provide', new webpack.ProvidePlugin({
Datepicker: [resolve('app/javascript/custom/datepicker'), 'default']
}))
module.exports = environment
意见:也就是说,我鼓励您明确导入,例如
import Datepicker from 'custom/datepicker'
在每个模块中,Datepicker
被引用。即使重复,与 ESlint 之类的工具集成也会变得更加容易,这些工具与某些代码编辑器一起可以提供有关编译错误的内联反馈——在每个模块中声明的显式依赖项更容易设置。 我在这里使用您的自定义 Datepicker 和 ProvidePlugin 制作了 Pikaday 的工作演示:https://github.com/rossta/rails6-webpacker-demo/commit/be3d20107c2b19baa8b9560bce05e0559f90086d
关于javascript - Rails,webpacker : where/when to use the import statement in classes, 以及在 pack/application.js 中要求的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59364809/