ESM
ESM

Reputation: 53

Error on console when using an external JavaScript library on Rails. I'm Using Webpack

I used yarn to add an npm library called Swing to my project on Rails. https://github.com/gajus/swing

The problem is that, even though it is compiling successfully with the new library, I'm getting an error on the console and can't seem to be able to use the functions of the library.

I'm using webpack version 3.11.0 and Rails 5.1.5.

The code looks like this:

New rails project with template (includes gems: https://github.com/lewagon/rails-templates/blob/master/minimal.rb and Devise gem for authentication):

rails new <app name> \
  --webpack \
  --database postgresql
  -m https://raw.githubusercontent.com/lewagon/rails-templates/master/devise.rb

Generated model for Post

rails g model Post title:string photo:string content:text 

Generated controller for Post

rails g controller posts 

controllers/posts_controller.rb 

def index
  //generates posts to display 
end 

Generate index view for posts.

/index.html.erb
//iterate over posts and build a card for each 

<div class="card"> populate card with post  </div>

Added Swing npm package with Yarn (dependency does appear in package.json after install)

yarn add swing

Created js file for implementing swiping behavior for cards. Haven't been able to go further because at the beginning i am supposed to use an instance of Swing.Stack() (provided by the library) but the browser is not recognizing this.

js file is looking like this:

javacript/deck.js

import Swing from "swing";

const card = document.querySelectorAll(".card") 

const stack = Swing.Stack();

I include my deck.js module in the entry file that webpack bundles:

javascript/packs/application.js 

import "bootstrap";
import "../deck.js";

And the error i'm getting in the console says:

deck.js:9 Uncaught TypeError: Cannot read property 'Stack' of undefined
    at Object.<anonymous> (deck.js:9)
    at Object.defineProperty.value (deck.js:51)
    at __webpack_require__ (bootstrap d955d73d3325972391a3:19)
    at Object.<anonymous> (application.js:1)
    at __webpack_require__ (bootstrap d955d73d3325972391a3:19)
    at bootstrap d955d73d3325972391a3:62
    at bootstrap d955d73d3325972391a3:62

Thank you so much for your help!

Upvotes: 3

Views: 278

Answers (1)

James Hibbard
James Hibbard

Reputation: 17725

You'll need to use CommonJS syntax, which means changing your import statement from this:

import Swing from "swing";

to this:

const Swing = require("swing");

The reason that using import doesn't work lies in the way that this module makes itself available for consumption by other code.

If you open up node_modules/swing/package.json in your Rails project, you'll see that the entry point for the module (the main property), is set to "./dist/index.js".

If you then open up dist/index.js you'll see that the module uses the CommonJS syntax (meaning that ES6 syntax simply isn't available):

exports.Card = _Card2.default;
exports.Direction = _Direction2.default;
exports.Stack = _Stack2.default;

Ref: https://nodejs.org/docs/latest/api/modules.html#modules_exports

Upvotes: 1

Related Questions