Search code examples
javascriptruby-on-railswebpackwebpacker

What's the cleanest way to import a third party library with webpacker?


I'm trying to use BeePlugin package in a Rails project and it raised the question of how to import properly a library using Webpacker?

I added jQuery but somehow I can't add bee-plugin. I wanna be able to import just what I need and only in the file I need it

So far what I did was

  1. Install the library with yarn yarn add @mailupinc/bee-plugin
  2. Created a new file to add my code and import it in application.js import ./bee
  3. In the new file import my library. I have tried
    • import "@mailupinc/bee-plugin"
    • import Bee from "@mailupinc/bee-plugin"
    • import * as Bee from "@mailupinc/bee-plugin"
    • const Bee = require "@mailupinc/bee-plugin"

None of them seem to work. Why?
I always get Uncaught ReferenceError: Bee is not defined

For reference application.js

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

import "./bee";

webpack/environment.js

const { environment } = require('@rails/webpacker')
const webpack = require("webpack");

// Avoid using require and import and alias jquery
environment.plugins.append(
  "Provide",
  new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
  })
);

module.exports = environment

bee.js

import Bee from "@mailupinc/bee-plugin";

function initBee() {
  $.ajax({ url: "/editor/token", success: startBee });
}

function beeConfig() {
  return {...} // Config params
}

function startBee(auth) {
  const beeInstance = Bee.create(auth, beeConfig(), (instance) => {
    $.ajax({
      url: $("#bee-plugin-container").data("template"),
      success: (template) => instance.start(template),
    });

    return instance;
  });
}

$(document).on("turbolinks:load", initBee);

Solution

  • So there was nothing wrong with the import.

    Turns out the library will asynchronously import an external script during the initialisation of an instance and that script was where the create method was defined (source code here)

    The file now looks like

    import Bee from "@mailupinc/bee-plugin";
    
    function initBee() {
      $.ajax({ url: "/editor/token", success: startBee });
    }
    
    function beeConfig() {
      return {...}
    }
    
    function startBee(auth) {
      $.ajax({
        url: $("#bee-plugin-container").data("template"),
        success: (template) => new Bee(auth).start(beeConfig(), template),
      });
    }
    
    $(document).on("turbolinks:load", initBee);