Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Rails,webpacker:在类中何时何地使用import语句,以及what';在pack/application.js中要求的目的是什么?_Javascript_Es6 Modules_Webpacker_Ruby On Rails 6 - Fatal编程技术网

Javascript Rails,webpacker:在类中何时何地使用import语句,以及what';在pack/application.js中要求的目的是什么?

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实现,这样我只需更改一个

我正在将一个较旧的应用程序升级到Rails 6,它使用
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?为什么

  • 我很熟悉全局变量是不好的,应该避免,但是有没有一种方法可以避免在引用它的每个JS文件上从“CLASS_file”导入类?在我的示例中,我想在多个位置使用
    Datepicker
    类。我问这个问题的原因是因为我有10多个这样的类,在我想在其中使用的每个JS文件的顶部都有10+
    import
    语句,这有点烦人。我总是想访问某些类。我使用过webpacker ProvidePlugin功能,但它抱怨
    Datepicker
    不是构造函数,所以我可能遗漏了一些东西,但我没有足够的知识知道是什么

  • app/javascript/custom/datepicker.js app/javascript/packs/application.js
    你问了几个问题:

  • 您只需在引用导入变量的文件中,
    Pikaday
    从“Pikaday”导入Pikaday即可。在这种情况下,您只需要在自定义日期选择器模块中进行此导入。您可以从application.js包文件中删除
    require(“pikaday”)

    原因是Webpack将把application.js包作为依赖关系图的入口点;从那里开始,它将递归地遍历每个必需/导入的模块,查找这些模块的依赖项,依此类推,直到所有声明的模块都包含在包中。由于您在application.js包中声明了
    import'custom/datepicker'
    ,并且custom datepicker导入了
    pikaday
    ,因此它将作为依赖项包含在包中

  • 由于您使用的是ES模块语法
    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")