diff --git a/__tests__/tests.ts b/__tests__/tests.ts index a6dcfaa..774bf03 100644 --- a/__tests__/tests.ts +++ b/__tests__/tests.ts @@ -1478,6 +1478,66 @@ describe('htmlbars-inline-precompile', function () { `); }); + it('cleans up leftover imports when there is more than one template', function () { + plugins = [ + [ + HTMLBarsInlinePrecompile, + { + targetFormat: 'hbs', + }, + ], + ]; + let code = ` + import { template } from "@ember/template-compiler"; + import Component from '@glimmer/component'; + export default class Test extends Component { + foo = 1; + static{ + template("", { + component: this, + eval () { + return eval(arguments[0]); + } + }); + } + } + const Icon = template("Icon", { + eval () { + return eval(arguments[0]); + } + }); + `; + + let transformed = transform(code); + + expect(transformed).toEqualCode(` + import Component from "@glimmer/component"; + import { precompileTemplate } from "@ember/template-compilation"; + import { setComponentTemplate } from "@ember/component"; + import templateOnly from "@ember/component/template-only"; + export default class Test extends Component { + foo = 1; + static { + setComponentTemplate( + precompileTemplate("", { + strictMode: true, + scope: () => ({ + Icon, + }), + }), + this + ); + } + } + const Icon = setComponentTemplate( + precompileTemplate("Icon", { + strictMode: true, + }), + templateOnly() + ); + `); + }); + it("respects user's strict option on template()", function () { plugins = [ [ diff --git a/src/plugin.ts b/src/plugin.ts index 3bfd9d4..cbe4e03 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -635,7 +635,6 @@ function updateCallForm( // target = target.get('arguments.0') as NodePath; } - // We deliberately do updateScope at the end so that when it updates // references, those references will point to the accurate paths in the // final AST. @@ -764,18 +763,26 @@ function maybePruneImport( return; } let binding = identifier.scope.getBinding(identifier.node.name); - // this checks if the identifier (that we're about to remove) is used in - // exactly one place. - if ( - binding?.referencePaths.reduce((count, path) => (path.removed ? count : count + 1), 0) === 1 - ) { + + if (!binding) { + return; + } + + let found = binding.referencePaths.find((path) => path.node === identifier.node); + if (!found) { + return; + } + + binding.referencePaths.splice(binding.referencePaths.indexOf(found), 1); + binding.references--; + + if (binding.references === 0) { let specifier = binding.path; if (specifier.isImportSpecifier()) { let declaration = specifier.parentPath as NodePath; util.removeImport(declaration.node.source.value, name(specifier.node.imported)); } } - identifier.removed = true; } function precompileTemplate(i: Importer) {