copenndthagen
copenndthagen

Reputation: 50742

Ember why do we have to use import for certain bower dependencies

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 ?

Upvotes: 1

Views: 865

Answers (2)

Lux
Lux

Reputation: 18240

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

Upvotes: 1

NullVoxPopuli
NullVoxPopuli

Reputation: 65143

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).

Upvotes: 1

Related Questions