diff --git a/packages/compiler-cli/linker/babel/src/es2015_linker_plugin.ts b/packages/compiler-cli/linker/babel/src/es2015_linker_plugin.ts index 121f3ba7f3952..9edd2294b3e4b 100644 --- a/packages/compiler-cli/linker/babel/src/es2015_linker_plugin.ts +++ b/packages/compiler-cli/linker/babel/src/es2015_linker_plugin.ts @@ -134,11 +134,12 @@ function insertIntoFunction( */ function insertIntoProgram(program: NodePath, statements: t.Statement[]): void { const body = program.get('body'); - const importStatements = body.filter((statement) => statement.isImportDeclaration()); - if (importStatements.length === 0) { + const insertBeforeIndex = body.findIndex((statement) => !statement.isImportDeclaration()); + + if (insertBeforeIndex === -1) { program.unshiftContainer('body', statements); } else { - importStatements[importStatements.length - 1].insertAfter(statements); + body[insertBeforeIndex].insertBefore(statements); } } diff --git a/packages/compiler-cli/linker/babel/test/es2015_linker_plugin_spec.ts b/packages/compiler-cli/linker/babel/test/es2015_linker_plugin_spec.ts index e1734320ac1da..0ed0d8112921b 100644 --- a/packages/compiler-cli/linker/babel/test/es2015_linker_plugin_spec.ts +++ b/packages/compiler-cli/linker/babel/test/es2015_linker_plugin_spec.ts @@ -69,7 +69,6 @@ describe('createEs2015LinkerPlugin()', () => { ); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); babel.transformSync( [ @@ -115,7 +114,6 @@ describe('createEs2015LinkerPlugin()', () => { ); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ 'var core;', @@ -138,7 +136,6 @@ describe('createEs2015LinkerPlugin()', () => { spyOnLinkPartialDeclarationWithConstants(o.literal('REPLACEMENT')); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ "import * as core from 'some-module';", @@ -159,11 +156,35 @@ describe('createEs2015LinkerPlugin()', () => { ); }); + it('should return a Babel plugin that adds shared statements after the first group of imports', () => { + spyOnLinkPartialDeclarationWithConstants(o.literal('REPLACEMENT')); + const fileSystem = new MockFileSystemNative(); + const logger = new MockLogger(); + const result = babel.transformSync( + [ + "import * as core from 'some-module';", + "import {id} from 'other-module';", + `ɵɵngDeclareDirective({minVersion: '0.0.0-PLACEHOLDER', version: '0.0.0-PLACEHOLDER', ngImport: core})`, + `ɵɵngDeclareDirective({minVersion: '0.0.0-PLACEHOLDER', version: '0.0.0-PLACEHOLDER', ngImport: core})`, + `ɵɵngDeclareDirective({minVersion: '0.0.0-PLACEHOLDER', version: '0.0.0-PLACEHOLDER', ngImport: core})`, + "import {second} from 'second-module';", + ].join('\n'), + { + plugins: [createEs2015LinkerPlugin({fileSystem, logger})], + filename: '/test.js', + parserOpts: {sourceType: 'unambiguous'}, + generatorOpts: {compact: true}, + }, + ); + expect(result!.code).toEqual( + 'import*as core from\'some-module\';import{id}from\'other-module\';const _c0=[1];const _c1=[2];const _c2=[3];"REPLACEMENT";"REPLACEMENT";"REPLACEMENT";import{second}from\'second-module\';', + ); + }); + it('should return a Babel plugin that adds shared statements at the start of the program if it is an ECMAScript Module and there are no imports', () => { spyOnLinkPartialDeclarationWithConstants(o.literal('REPLACEMENT')); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ 'var core;', @@ -188,7 +209,6 @@ describe('createEs2015LinkerPlugin()', () => { spyOnLinkPartialDeclarationWithConstants(o.literal('REPLACEMENT')); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ 'function run(core) {', @@ -213,7 +233,6 @@ describe('createEs2015LinkerPlugin()', () => { spyOnLinkPartialDeclarationWithConstants(o.literal('REPLACEMENT')); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ 'function run() {', @@ -244,7 +263,6 @@ describe('createEs2015LinkerPlugin()', () => { spyOnLinkPartialDeclarationWithConstants(o.fn([], [], null, null, 'FOO')); const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ `ɵɵngDeclareDirective({minVersion: '0.0.0-PLACEHOLDER', version: '0.0.0-PLACEHOLDER', ngImport: core}); FOO;`, @@ -298,7 +316,6 @@ describe('createEs2015LinkerPlugin()', () => { const fileSystem = new MockFileSystemNative(); const logger = new MockLogger(); - const plugin = createEs2015LinkerPlugin({fileSystem, logger}); const result = babel.transformSync( [ "import * as core from 'some-module';",