Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Import dependencies in ember-cli (e.g., import math.js)

I am puzzled about importing dependencies in ember-cli, especially about the standard AMD case, as mentioned in the official Ember Cli document. The document doesn't provide much of examples, and seems to me it assumes the readers have good knowledge about AMD, which is not the case for me. My immediate use case is import math.js. Unfortunately, the official document of math.js doesn't provide example about importing with Ember Cli. Then, I found this post with relatively clearer examples, in particular, the following one seems quite relevant.

app.import({
  development: 'vendor/lodash/dist/lodash.js',
  production:  'vendor/lodash/dist/lodash.min.js'
}, {
  'lodash': [
    'default'
  ]
}); 

Then, I did similar thing with math.js like below:

app.import({
  development: 'bower_components/mathjs/dist/math.js',
  production:  'bower_components/mathjs/dist/math.min.js'
}, {
  'mathjs': [
    'default'
  ]
});

However, it doesn't work. When I tried to use it with

import mathjs from 'mathjs'

I got an error. Eventually, I used the following solution:

// Brocfile.js
app.import('bower_components/mathjs/dist/math.min.js');

// some controller.js
var math = window.math

Although above solution works, I don't like it as it may be subject to name conflict. Besides, based on math.js's document, it seems to me it should support standard AMD type of import.

So, my questions are the following.
1. In the lodash example above, what does the 'default' mean? Is that a general reference to whatever exported in the corresponding module? How can I tell whether I can use it in general (for example, math.js)?
2. Is it true that if a module supports require.js, then it is a standard AMD module? If so, given code like below:

require.config({
  paths: {
    mathjs: 'path/to/mathjs',
  }
});
require(['mathjs'], function (math) {
  // use math.js
  math.sqrt(-4); // 2i
});

how can I map it to Ember Cli code?

like image 636
JBT Avatar asked May 25 '15 17:05

JBT


1 Answers

It's a bit of a pain but since mathjs does not expose/support a named AMD module you can't use the extra syntax in app.import.

You have two options:

  1. ember-browserify (if the library supports CommonJS - which mathjs does)
  2. "shimming" the dependant library yourself

1. ember-browserify

  1. Install ember-browserify

    ember install ember-browserify

  2. Install the CommonJS library as an NPM package

    npm install --save-dev mathjs

  3. Use the NPM package with regular import syntax

    import mathjs from 'npm:mathjs';

2. Shimming

What you need to do is "shim" the library to make it available via import statements. I still don't know what the word shim means <:

If you're interested in creating a bower package, e.g. ember-cli-mathjs-shim you could then use that and give others the ability to use it too. Some examples of this are:

ember-cli-shims

ember-cli-moment-shim

ember-cli-sockjs-shim

But if you're not comfortable doing that, I would recommend adding the following to your project:

vendor/shims/math.js - Create a shims folder under vendor (vendor is where your dependancies go that don't come from NPM or Bower - and the Brocfile doesn't appear to be able to app.import from anywhere other than here - e.g. app/shims or simple shims at the root level doesn't work)

vendor/shims/math.js

(function() {
  /* globals define, math */

  function mathJSModule() {
    'use strict';

    return { 'default': math };
  }

  define('mathjs', [], mathJSModule);

})();

Brocfile.js

app.import('bower_components/mathjs/dist/math.js');
app.import('vendor/shims/math.js', {
  exports: {
    'mathjs': [ 'default' ]
  }
});

The order here is important.

like image 134
jmurphyau Avatar answered Oct 19 '22 23:10

jmurphyau