【问题标题】:How to migrate requiring of select2.js from sprockets to webpacker如何将 select2.js 的需求从 sprockets 迁移到 webpacker
【发布时间】:2018-03-21 14:48:30
【问题描述】:

我正在将使用 CoffeeScript 的 Rails 5.1.5 项目从使用 sprocket 迁移到使用 webpacker。该项目还使用select2.js。使用链轮,我做了以下事情:

  1. 安装jquery-rails(jQuery 是select2 的依赖项)。
  2. select2.js代码放入vendor/assets/javscripts
  3. application.js.coffee,添加:

    #= require select2
    

之后,我可以在我的application.js.coffee 文件中使用 select2:

$(document).on 'turbolinks:load' ->
  $('select').select2

到目前为止,我已经描述了包含/使用带有链轮的 javascript 库的非常标准的方法。

但是,使用 webpacker 我无法使 select2 工作,我不知道为什么。我有两个假设:

  • 我没有正确导入/要求它;
  • 在加载过程的某个时刻找不到 jQuery;

所以对于 jQuery,我做了以下操作:

  • yarn add jquery
  • 包含在我的environment.js

    const webpack = require('webpack');
    
    environment.plugins.append('Provide', new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }));
    

我已经删除了 jquery-rails gem 和 #= require 'jquery' 并测试了 jquery 的工作原理,所以我想我已经正确地包含了它。但是,我尝试了几种导入 select2 的方法(使用 es6 导入),但都没有奏效。我试过了:

import select2 from 'select2';
import select2 from 'select2/dist/js/select2'
import select2 from 'select2/dist/js/select2.js'
import 'select2/dist/js/select2.js'

我什至尝试通过在app/javascript/pack/application.js.coffee 中写入来从旧的vendor location 导入它:

import '../../../vendor/assets/javascripts/select2'

我可以确认文件内容已导入,因为我在 node_modules/select2/dist/js/select.js 下的 select2 文件中放置了一个 console.log,它确实被打印了。但是,当我在浏览器的开发工具控制台中执行$('select').select2() 时,我也会收到错误TypeError: $(...).select2 is not a function

我错过了什么或做错了什么?

附:我可以提供更多信息,但我不想让我的问题变得更加臃肿。 附言凭借我的 JS 知识,我查看了 source code,但无法识别它们究竟在导出什么以及我应该如何导入它。

【问题讨论】:

    标签: ruby-on-rails webpack jquery-select2 es6-modules


    【解决方案1】:

    我知道这是一个旧帖子,但以防其他人受益:

    app/javascript/packs/application.js

    ...other requires...
    require('select2')
    
    window.Rails = Rails
    
    import 'bootstrap'
    ...other imports...
    import 'select2'
    import 'select2/dist/css/select2.css'
    
    $(document).on("turbolinks:load", () => {
      $('.select2').select2()
    })
    

    【讨论】:

      【解决方案2】:

      我的类似问题

      我在另一个 Web 组件 (Switchery) 上偶然发现了同样的问题:

      • 我用yarn add switchery 导入了组件(没有错误)
      • 我可以通过带有import 'switchery' 的WebPack 正确导入它(捆绑包没有错误)

      但是当我尝试在浏览器中使用 Switchery 对象时,就像他们在文档中所说的那样:

      var elem = document.querySelector('.js-switch');
      var init = new Switchery(elem);
      

      我会收到错误:ReferenceError: Switchery is not defined

      注意:我不想安装 RequireJS,因为 WebPack 现在应该做同样的事情(甚至更好)。

      我的解决方案:

      问题是 webpack 没有在全局范围内公开包生成的变量和类!

      所以要解决这个问题,我需要做两件事:

      • 明确地为从 Switchery 导入的类命名: import Switchery from 'switchery'
      • 仅在完成导入的同一个 JS 文件中使用该类

      测试技巧:

      如果您想尝试一下并“返回”到 sprocket 允许的混乱状态,则可以在同一个文件中“全局”公开变量,以便您可以从浏览器中使用:

      import Switchery from 'switchery'
      
      window.Switchery = Swicthery
      

      现在您可以像示例中一样执行切换: var init = new window.Switchery(elem);

      希望对您有所帮助...

      【讨论】:

        猜你喜欢
        • 2020-03-28
        • 2020-11-16
        • 1970-01-01
        • 2011-12-14
        • 2016-06-24
        • 2021-09-21
        • 2019-09-25
        • 2020-11-13
        • 2016-09-15
        相关资源
        最近更新 更多