EmberSherpa / ama

Ask me anything Ember!
22 stars 0 forks source link

Is it possible to add initializer directly from the code of an ember-cli addon? #14

Closed OrKoN closed 8 years ago

OrKoN commented 8 years ago

For example,

// addon/components/my-comp.js
var MyComp = Ember.Component.extend...

Ember.Application.initializer({
 name: 'my-comp',
 initialize: function() {
 }
});

export default MyComp;

It didn't work for me but since I don't use ember-cli a lot I am not really sure if this is supported. So is it possible? or one has to create a file in the initializers folder?

taras commented 8 years ago

tl;dr: Not without explicitly configuring that initializer in the app.js file.


This is not working because you're executing the initializer function too late in the booting process.

The initializers directory is important in EmberCLI because EmberCLI is configured to import initializers from that directory at the correct time in the booting process. If you look at an app blueprint in EmberCLI, you will find an /app/app.js file which imports loadInitializers function. loadInitializers is later used to configure the initializers before the app is instantiated.

The initializer from a Component module will only be called when the module is imported. Earliest that the module will be imported is when an instance of this component is created for the first time.

Why are you trying to put your initializer into a Component module?

taras commented 8 years ago

FYI: @tomdale description of the Ember application booting process

^^ coincidentally, answered to you :)

OrKoN commented 8 years ago

So the difference to the process described by Tom Dale is that add-on modules are evaluated lazily in ember-cli apps. Is it right? And, probably, if there is no initializer in the initializers directory of the add-on the component definition will not be evaluated at all?

In my current setup if I import a component I can have initializers in the same file (because it's the step 4 as per Tom's answer). Looking for the best way to port it to ember-cli:

var MyComp = Ember.Component.extend...

Utils.registerComponent('my-comp', MyComp);

export default MyComp;

so this cannot be used as-is in ember-cli projects.

Thanks for the answer and for the links to ember-cli example. That's what I need.

taras commented 8 years ago

add-on modules are evaluated lazily in ember-cli apps

All of the ES6 modules are evaluated when they're necessary.

And, probably, if there is no initializer in the initializers directory of the add-on the component definition will not be evaluated at all?

If you have an EmberCLI addon that has a component and an initializer then you should include in the initializer in the addon's app/initializers directory. This way it will be merged into the app tree when EmberCLI is building your app and your initializer will automatically execute.

In my current setup if I import a component I can have initializers in the same file (because it's the step 4 as per Tom's answer).

Yes, this make sense.

var MyComp = Ember.Component.extend... Utils.registerComponent('my-comp', MyComp); export default MyComp;

Don't do this ^^. If you're moving your addon to EmberCLI then you should just split up your component into a separate initializer file and a component file and place them in correct directories in your addon.

A common structure for an addon might look like this:

/addon/components/my-component.js
/addon/initializers/my-initializer.js
/app/components/my-component.js
/app/initializers/my-initializer.js

/addon/components/my-component.js

import Ember from 'ember';
export default Ember.Component.extend({
  // your component code goes here
});

/addon/initializers/my-initializer.js

export function initialize() {
  // actually initialization code
}
export default {
  name: 'my-component initializer',
  initialize: initialize
}

/app/components/my-component.js

import MyComponent from 'my-addon/components/my-component';

export default MyComponent:

/app/initializers/my-initializer.js

import MyInitializer from 'my-addon/initializers/my-initializer';

export default MyInitializer;

This might look like duplication of effort, but /addon directory and /app directory in your addon serve different purposes. /addon/ directory is the library that your addon provides. /app/ is merged into an app when an app that's using the addon is being compiled. In a sense, you're providing code that's merged into the app and it's using the library that your addon provides.

What does your initializer do?

OrKoN commented 8 years ago

I see. In my non-ember-cli case initializers usually just register corresponding components. So I guess in ember-cli I don't need initializers just for registering components if I re-export components via the app folder of my addon, right?

taras commented 8 years ago

Yes.

OrKoN commented 8 years ago

Thanks! The app makes sense then.