Skip to content

Commit 3b7873d

Browse files
author
Robert Jackson
authored
Merge pull request #176 from ember-cli/make-ensure-import-lazy
Make ensureImport lazy
2 parents 88b8048 + 6a9a9d7 commit 3b7873d

2 files changed

Lines changed: 53 additions & 31 deletions

File tree

__tests__/index-test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ describe('options', () => {
253253
it(`adds the ember import when used in sub-modules`, () => {
254254
let input = `import Component from '@ember/component';export default class extends Component {}`;
255255
let actual = transform(input, [[Plugin, { useEmberModule: true }]]);
256-
let expected = `import _Ember from 'ember';\nexport default class extends _Ember.Component {}`;
256+
let expected = `import _ember from 'ember';\nexport default class extends _ember.Component {}`;
257257

258258
expect(actual).toEqual(expected);
259259
});

src/index.js

Lines changed: 52 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -90,39 +90,64 @@ module.exports = function (babel) {
9090
Program(path, state) {
9191
let options = state.opts || {};
9292
let useEmberModule = Boolean(options.useEmberModule);
93+
let allAddedImports = {};
9394

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-
}
95+
state.ensureImport = (exportName, moduleName) => {
96+
let addedImports = (allAddedImports[moduleName] =
97+
allAddedImports[moduleName] || {});
10898

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-
}
99+
if (addedImports[exportName]) return addedImports[exportName];
115100

116-
if (state.emberIdentifier) return;
101+
if (
102+
exportName === 'default' &&
103+
moduleName === 'ember' &&
104+
!useEmberModule
105+
) {
106+
addedImports[exportName] = t.identifier('Ember');
107+
return addedImports[exportName];
108+
}
117109

118-
state.emberIdentifier = path.scope.generateUidIdentifier('Ember');
110+
let importDeclarations = path
111+
.get('body')
112+
.filter((n) => n.type === 'ImportDeclaration');
119113

120-
let emberImport = t.importDeclaration(
121-
[t.importDefaultSpecifier(state.emberIdentifier)],
122-
t.stringLiteral('ember')
114+
let preexistingImportDeclaration = importDeclarations.find(
115+
(n) => n.get('source').get('value').node === moduleName
123116
);
124117

125-
path.unshiftContainer('body', emberImport);
118+
if (preexistingImportDeclaration) {
119+
let importSpecifier = preexistingImportDeclaration
120+
.get('specifiers')
121+
.find(({ node }) => {
122+
return exportName === 'default'
123+
? t.isImportDefaultSpecifier(node)
124+
: node.imported.name === exportName;
125+
});
126+
127+
if (importSpecifier) {
128+
addedImports[exportName] = importSpecifier.node.local;
129+
}
130+
}
131+
132+
if (!addedImports[exportName]) {
133+
let uid = path.scope.generateUidIdentifier(
134+
exportName === 'default' ? moduleName : exportName
135+
);
136+
addedImports[exportName] = uid;
137+
138+
let newImportSpecifier =
139+
exportName === 'default'
140+
? t.importDefaultSpecifier(uid)
141+
: t.importSpecifier(uid, t.identifier(exportName));
142+
143+
let newImport = t.importDeclaration(
144+
[newImportSpecifier],
145+
t.stringLiteral(moduleName)
146+
);
147+
path.unshiftContainer('body', newImport);
148+
}
149+
150+
return addedImports[exportName];
126151
};
127152
},
128153

@@ -216,9 +241,6 @@ module.exports = function (babel) {
216241

217242
removals.push(specifierPath);
218243

219-
// ensure that the Ember global is imported if needed
220-
state.ensureEmberImport();
221-
222244
if (
223245
path.scope.bindings[local.name].referencePaths.find(
224246
(rp) => rp.parent.type === 'ExportSpecifier'
@@ -268,7 +290,7 @@ module.exports = function (babel) {
268290
if (!isTypescriptNode(referencePath.parentPath)) {
269291
const memberExpression = getMemberExpressionFor(
270292
global,
271-
state.emberIdentifier
293+
state.ensureImport('default', 'ember')
272294
);
273295

274296
try {

0 commit comments

Comments
 (0)