st-h
st-h

Reputation: 2553

Import SockJS as AMD in Ember CLI

I am desperately trying to include SockJS via Bower in Ember CLI. I have followed the docs as close as I could. These are the steps, which seemed to almost work:

This at least seems to compile and ember server runs without errors. However, as soon as I open the page in a browser, I receive the following error:

Uncaught ReferenceError: SockJS is not defined

The created source, which shows the error, looks like this:

SockJS = (function(){
              var _document = document;
              var _window = window;
              var utils = {};

<!-- include lib/reventtarget.js -->
<!-- include lib/simpleevent.js -->
<!-- include lib/eventemitter.js -->
<!-- include lib/utils.js -->
<!-- include lib/dom.js -->
<!-- include lib/dom2.js -->
<!-- include lib/sockjs.js -->
<!-- include lib/trans-websocket.js -->
<!-- include lib/trans-sender.js -->
<!-- include lib/trans-jsonp-receiver.js -->
<!-- include lib/trans-jsonp-polling.js -->
<!-- include lib/trans-xhr.js -->
<!-- include lib/trans-iframe.js -->
<!-- include lib/trans-iframe-within.js -->
<!-- include lib/info.js -->
<!-- include lib/trans-iframe-eventsource.js -->
<!-- include lib/trans-iframe-xhr-polling.js -->
<!-- include lib/trans-iframe-htmlfile.js -->
<!-- include lib/trans-polling.js -->
<!-- include lib/trans-receiver-eventsource.js -->
<!-- include lib/trans-receiver-htmlfile.js -->
<!-- include lib/trans-receiver-xhr.js -->
<!-- include lib/test-hooks.js -->
                  return SockJS;
          })();

What is the right way to include SockJS with Ember CLI?

EDIT

After some more trial and error I got the following working from a browsers perspective:

Brocoli.js:

app.import('vendor/bower-sockjs-client/sockjs.js', {
  'sockjs-client': ['sockjs-client']
});
module.exports = app.toTree();

bower.json:

  "dependencies": {
    "handlebars": "~1.3.0",
    "jquery": "^1.11.1",
    "qunit": "~1.12.0",
    "ember-qunit": "~0.1.5",
    "ember": "1.5.1",
    "ember-resolver": "~0.1.1",
    "loader": "stefanpenner/loader.js#1.0.0",
    "ember-cli-shims": "stefanpenner/ember-cli-shims#0.0.2",
    "ember-load-initializers": "stefanpenner/ember-load-initializers#0.0.2",
    "ember-qunit-notifications": "^0.0.1",
    "ember-cli-test-loader": "rjackson/ember-cli-test-loader#0.0.2",
    "bower-sockjs-client": "0.3.4"
  }

And no import whatsoever within the module.

This makes Ember CLI complain a lot: 'SockJS' is not defined. However it at least works for now. Is there anything wrong with what I am doing or is this a bug within Ember CLI?

Upvotes: 1

Views: 1467

Answers (3)

Akeem McLennon
Akeem McLennon

Reputation: 167

Given that SockJS doesn't have proper module loading support, I just put the following in my Brocfile

app.import('bower_components/sockjs-client/dist/sockjs-1.0.0-beta.12.js');

and then at the top of my controller, I have

import Ember from 'ember';
let SockJS = window.SockJS; 

Upvotes: 1

jmurphyau
jmurphyau

Reputation: 2309

I had similar issues so I developed an addon for Ember adding expected sockjs syntax etc.

ember-sockjs

Upvotes: 0

blessanm86
blessanm86

Reputation: 31779

I know you already got this solved. But here is an explanation of whats going wrong. I was also having issues, so I thought I'll see whats going on under the hood.

The library you downloaded via bower "sockjs-client" does not contain the distribution file. You will need to to build it your self. For this you need the make command. If you are linux or mac, you already have it. If on windows, you need to download cygwin or mingw

To build sockjs, go to vendor/sockjs-client/ in the terminal and execute the command

npm install
make build

This will generate 2 files sockjs.min.js and sockjs.js.

Now you can include this file in your Brocfile.js

app.import('vendor/sockjs-client/sockjs.min.js');

Now SockJS should be available as a global variable. The package you are using now 'bower-sockjs-client' is just a fork that shares the dist files. If you are using that, make sure it is up to date.

Since SockJS is a global, you need to add it to the jshintrc file.

{
  "predef": {
    "document": true,
    "window": true,
    "Demo1ENV": true,
    "SockJS": true
  }
}

Why import is not working -

The reason you are not able to import the package is because SockJS uses some kind of UMD syntax for amd. They do the following check to see if it can use the amd syntax.

typeof define == "function" && define.amd

ember-cli uses a minimal loader.js to load amd modules and define.amd is not set, so it will evaluate to false in the above code. Even if you modify the loader.js file, the amd definition of SockJS isn't compatible with the ES6 transpiler. ES6 transpiler expectes the module to be exported to the 'default' key.

import sockjs from 'sockjs';  will become something like
var sockjs = _dependency_1['default'];
but SockJS is _dependency_1, _dependency_1['default'] will be undefined.

Upvotes: 3

Related Questions