@@ -58,14 +58,17 @@ module.exports = function (babel) {
5858 reverseMapping [ importRoot ] [ importName ] = imported ;
5959 } ) ;
6060
61- function getMemberExpressionFor ( global ) {
61+ function getMemberExpressionFor ( global , emberIdentifier ) {
6262 let parts = global . split ( '.' ) ;
6363
6464 let object = parts . shift ( ) ;
6565 let property = parts . shift ( ) ;
6666
67+ let objectIdentifier =
68+ object === 'Ember' ? emberIdentifier : t . identifier ( object ) ;
69+
6770 let memberExpression = t . MemberExpression (
68- t . identifier ( object ) ,
71+ objectIdentifier ,
6972 t . identifier ( property )
7073 ) ;
7174
@@ -84,8 +87,49 @@ module.exports = function (babel) {
8487 return {
8588 name : 'ember-modules-api-polyfill' ,
8689 visitor : {
90+ Program ( path , state ) {
91+ let options = state . opts || { } ;
92+ let useEmberModule = Boolean ( options . useEmberModule ) ;
93+
94+ let preexistingEmberImportDeclaration = path
95+ . get ( 'body' )
96+ . filter ( ( n ) => n . type === 'ImportDeclaration' )
97+ . find ( ( n ) => n . get ( 'source' ) . get ( 'value' ) . node === 'ember' ) ;
98+
99+ if (
100+ // an import was found
101+ preexistingEmberImportDeclaration &&
102+ // this accounts for `import from 'ember'` without a local identifier
103+ preexistingEmberImportDeclaration . node . specifiers . length > 0
104+ ) {
105+ state . emberIdentifier =
106+ preexistingEmberImportDeclaration . node . specifiers [ 0 ] . local ;
107+ }
108+
109+ state . ensureEmberImport = ( ) => {
110+ if ( ! useEmberModule ) {
111+ // ensures that we can always assume `state.emberIdentifier` is set
112+ state . emberIdentifier = t . identifier ( 'Ember' ) ;
113+ return ;
114+ }
115+
116+ if ( state . emberIdentifier ) return ;
117+
118+ state . emberIdentifier = path . scope . generateUidIdentifier ( 'Ember' ) ;
119+
120+ let emberImport = t . importDeclaration (
121+ [ t . importDefaultSpecifier ( state . emberIdentifier ) ] ,
122+ t . stringLiteral ( 'ember' )
123+ ) ;
124+
125+ path . unshiftContainer ( 'body' , emberImport ) ;
126+ } ;
127+ } ,
128+
87129 ImportDeclaration ( path , state ) {
88- let ignore = ( state . opts && state . opts . ignore ) || [ ] ;
130+ let options = state . opts || { } ;
131+ let ignore = options . ignore || [ ] ;
132+ let useEmberModule = Boolean ( options . useEmberModule ) ;
89133 let node = path . node ;
90134 let declarations = [ ] ;
91135 let removals = [ ] ;
@@ -105,10 +149,14 @@ module.exports = function (babel) {
105149
106150 if ( specifierPath ) {
107151 let local = specifierPath . node . local ;
108- if ( local . name !== 'Ember' ) {
109- path . scope . rename ( local . name , 'Ember' ) ;
152+
153+ // when `useEmberModule` is set, we don't need to do anything here
154+ if ( ! useEmberModule ) {
155+ if ( local . name !== 'Ember' ) {
156+ path . scope . rename ( local . name , 'Ember' ) ;
157+ }
158+ removals . push ( specifierPath ) ;
110159 }
111- removals . push ( specifierPath ) ;
112160 } else {
113161 // import 'ember';
114162 path . remove ( ) ;
@@ -168,12 +216,15 @@ module.exports = function (babel) {
168216
169217 removals . push ( specifierPath ) ;
170218
219+ // ensure that the Ember global is imported if needed
220+ state . ensureEmberImport ( ) ;
221+
171222 if (
172223 path . scope . bindings [ local . name ] . referencePaths . find (
173224 ( rp ) => rp . parent . type === 'ExportSpecifier'
174225 )
175226 ) {
176- // not safe to use path.scope.rename directly
227+ // not safe to use path.scope.rename directly when this identifier is being directly re-exported
177228 declarations . push (
178229 t . variableDeclaration ( 'var' , [
179230 t . variableDeclarator (
@@ -215,7 +266,10 @@ module.exports = function (babel) {
215266 // Replace the occurrences of the imported name with the global name.
216267 referencePaths . forEach ( ( referencePath ) => {
217268 if ( ! isTypescriptNode ( referencePath . parentPath ) ) {
218- const memberExpression = getMemberExpressionFor ( global ) ;
269+ const memberExpression = getMemberExpressionFor (
270+ global ,
271+ state . emberIdentifier
272+ ) ;
219273
220274 try {
221275 referencePath . replaceWith ( memberExpression ) ;
0 commit comments