Unknown global Ember.inject
Dhaulagiri opened this issue · comments
Moved from ember-cli/ember-rfc176-data#34
If you have inject destructured like this the ember-modules-codemod fails stating this in an unkown global:
const { inject } = Ember;
This form of destructing does work:
const { inject: { service } } = Ember;
Can/should the first case be supported?
Yes, we should definitely handle this a bit better.
If the Ember.computed
case that I mentioned in ember-cli/ember-rfc176-data#34 is working properly, you should checkout https://github.com/ember-cli/ember-modules-codemod/blob/master/transform.js#L230-L270 to see what updates are required to make the same work for Ember.inject
...
Same issue also if you use const { inject } = Ember;
with inject.controller
. Taking a look to see if I can't figure out how to fix...
The Ember.computed
case works ok because import { computed } from '@ember/object';
is valid whereas import { inject } from '@ember/service';
is not
Ah, that makes sense. Though, I do think we should actually update it to import things directly. I don't think we intend to allow the following (it only happens to work due to the way the globals are setup):
import computed from '@ember/computed';
export default Component.extend({
derp: computed.alias('otherThing.derp')
})
My suggestion would be to add some additional logic to handle these sorts of namespaces (Ember.computed
and Ember.inject
might be the only examples?) so that we transform:
const { computed, inject } = Ember;
export default Component.extend({
derp: computed.alias('otherThing.derp'),
thing: inject.service()
})
Into:
import { alias } from '@ember/computed';
import { inject } from '@ember/service';
export default Component.extend({
derp: alias('otherThing.derp'),
thing: inject()
})
👍 that seems prudent.
Having never worked on a codemod before I'm honestly finding it a little hard to grok the best way to accomplish this, but I'll poke around at it some more. It's not super hard to manually migrate these either, but it'd obviously be nice if the codemod worked here as well.
Although I think import { inject } from '@ember/service';
should end up as import { inject as service } from '@ember/service';
in the example above?
Ya, maybe name it injectService
?
Not sure if it matters, but the json data shows them like this:
However this yields:
inject.service is not a function
in practice
You can ignore my last comment, I was doing it wrong.
import { inject } from '@ember/controller';
...
foo: inject('myControllerName') //works
foo: inject.controller('myControllerName') // does not work
Hmm, I've been doing some brainstorming on this, and it's a really weird case.
The tricky bit: if we have an instance of const { inject } from Ember
, this means the codemod might need to replace it with either import { inject } from '@ember/service'
, or import { inject } from '@ember/controller'
, or both, and which of the two (or both) to use depends on the presence of any inject.service
or inject.controller
instances later on in the file.
Is there anything in the codemod currently that does this type of lookahead? This seems a bit can-of-worms-y, but having to do this case by-hand isn't handy (heh) either.
Also we'll need to figure out what to do in the case of injecting both a controller and a service in the same file, since the imports can't both be named inject
. That seems like a change request for RFC176 itself, though.
[EDIT] corrected some things above -- I keep instinctively writing import
instead of const
. :P
This should fix it: #46