1

In an Ember app, when using certain dependencies like moment installed via bower, we have to also import the same in the ember-cli-build.js file:

app.import('bower_components/moment/moment.js');

My question is why is that needed, since I would assume everything inside node_modules as well as bower_components should be available for use inside the app. Also if that is not the case, how do we identify which dependencies would require such explicit import to be able to use them ?

copenndthagen
  • 49,230
  • 102
  • 290
  • 442

2 Answers2

1

You don't have to, actually.

There is a package now that lets you 'just import' things: https://github.com/ef4/ember-auto-import

Some reading on the topic of importing: https://discuss.emberjs.com/t/readers-questions-how-far-are-we-from-being-able-to-just-use-any-npm-package-via-the-import-statement/14462?u=nullvoxpopuli

In in-depth answer to your question and the reasons behind why things are the way they are is posted here: https://discuss.emberjs.com/t/readers-questions-why-does-ember-use-broccoli-and-how-is-it-different-from-webpack-rollup-parcel/15384?u=nullvoxpopuli (A bit too long for stack overflow, also on mobile, and I wouldn't want to lose all the links and references in a copy-paste)

Hope this helps

Edit:

To answer:

I just wanted to understand "in what cases" do we need to use the import statement in our ember-cli-build (meaning we do not do import for all the dependencies we have in our package/bower.json)...But only for specific ones...I wanted to know what is the criteria or use case for doing import.

Generally, for every package, hence the appeal of the auto-import and / or packagers (where webpack may be used instead of rollup in the future).

Though, it's common for ember-addons to define their own app.import so that you don't need to configure it, like any of these shims, specifically, here is how the c3 charting library is shimmed: https://github.com/mike-north/ember-c3-shim/blob/master/index.js#L7

Importing everything 'manually' like this is a bit of a nuisance, but it is, in part, due to the fact that js packages do not have a consistent distribution format. There is umd, amd, cjs, es6, etc. with the rollup and broccoli combo, we need to manually specify which format a file is. There are some big advantages to the rollup + broccoli approach, which can be demonstrated here and here

Sometimes, depending on the transform, you'll need a "vendor-shim". These are handy when a module has decided it wants to be available on the window / global object instead of available as a module export. Link: https://simplabs.com/blog/2017/02/13/npm-libs-in-ember-cli.html (self represents window/global)

however, webpack has already done the work of figuring out how to detect what format a js file is in, and abstracts all of that away from you. webpack is what ember-auto-import uses, and is what allows you to simply import { stuff} from 'package-name';. The downside to webpack is that you can't pipeline your transforms (which most people may not need, but it can be handy if you're doing Typescript -> Babel -> es5).

NullVoxPopuli
  • 61,906
  • 73
  • 206
  • 352
  • Thanks...The links provided seem to be more about the Ember internals and stuff...Also, I am not really looking at ember-auto-import.. I just wanted to understand "in what cases" do we need to use the import statement in our ember-cli-build (meaning we do not do import for all the dependencies we have in our package/bower.json)...But only for specific ones...I wanted to know what is the criteria or use case for doing import.. – copenndthagen Oct 08 '18 at 04:53
1

Actually: (almost) everything!

Ember does, by default, not add anything to your app except ember addons. There are however some addons that dynamically add stuff to your app like ember-browserify or ember-auto-import.

Also just because you do app.import this does not mean you can use the code with import ... from 'my-package'. The one thing app.import does is it adds the specified file to your vendor.js file. Noting else.

How you use this dependency depends completely on the provided JS file! Ember uses loader.js, an AMD module loader. So if the JS file you app.imported uses AMD (or UMD) this will work and you can import Foo from 'my-package'. (Because this is actually transpiled to AMD imports)

If the provided JS file provides a global you can just use the global. However there is also the concept of vendor-shims.. Thats basically just a tiny AMD module you can write to export the global as AMD module.

However there are a lot of ember addons that add stuff to your app. For example things like ember-cli-moment-shim just exist to automagically add a dependency to your project. However how it's done completely depends on the addon.


So the rule is:

  • If its an ember addon read the addon docs but usually you shouldn't app.import
  • In every other case you manually need to use the library either by app.import or manual broccoli transforms.

The only exception is if you use an addon that tries to generically add dependencies to your project like ember-browserify or ember-auto-import

Lux
  • 17,835
  • 5
  • 43
  • 73
  • Awesome answer..I have read whatever you have mentioned multiple times so as to grasp the content entirely...I have couple of related questions; 1. When you say that some addons dynamically add stuff to your app, could you please elaborate on the same, meaning does it add something within our 'app' / 'addon' project code itself ? 2. This is specific to numeral package, but you can also take that as a general dependency question...So we have numeral & ember-cli-numeral ...What is the difference between the 2 packages? Does using one of the techniques allow to use the global numeral variable? – copenndthagen Oct 19 '18 at 17:20
  • `ember-cli-numeral` wraps `numeral` so you can easaly use it in ember. It's like `ember-cli-moment-shim`. – Lux Oct 19 '18 at 17:44
  • So if I have to dig deep to understand where the magic happens, does that happen inside the index.js file (app.import() line) ? https://github.com/josemarluedke/ember-cli-numeral/blob/master/index.js – copenndthagen Oct 19 '18 at 18:05
  • yes. The `index.js` is some kind of the addon version of `ember-cli-build`. – Lux Oct 19 '18 at 19:23