fix(ngcc): ensure that more dependencies are found by `EsmDependencyHost` (#37075)

Previously this host was skipping files if they had imports that spanned
multiple lines, or if the import was a dynamic import expression.

PR Close #37075
This commit is contained in:
Pete Bacon Darwin 2020-06-04 08:43:04 +01:00 committed by atscott
parent c61decf7e5
commit 7f98b87ca0
2 changed files with 28 additions and 4 deletions

View File

@ -93,7 +93,7 @@ export class EsmDependencyHost extends DependencyHostBase {
* in this file, true otherwise. * in this file, true otherwise.
*/ */
export function hasImportOrReexportStatements(source: string): boolean { export function hasImportOrReexportStatements(source: string): boolean {
return /(import|export)\s.+from/.test(source); return /(?:import|export)[\s\S]+?(["'])(?:(?:\\\1|.)*?)\1/.test(source);
} }

View File

@ -180,13 +180,13 @@ runInEachFileSystem(() => {
{name: _('/no/imports/or/re-exports/index.metadata.json'), contents: 'MOCK METADATA'}, {name: _('/no/imports/or/re-exports/index.metadata.json'), contents: 'MOCK METADATA'},
{ {
name: _('/external/imports/index.js'), name: _('/external/imports/index.js'),
contents: `import {X} from 'lib-1';\nimport {Y} from 'lib-1/sub-1';` contents: `import {\n X\n} from 'lib-1';\nimport {Y, Z} from 'lib-1/sub-1';`
}, },
{name: _('/external/imports/package.json'), contents: '{"esm2015": "./index.js"}'}, {name: _('/external/imports/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/imports/index.metadata.json'), contents: 'MOCK METADATA'}, {name: _('/external/imports/index.metadata.json'), contents: 'MOCK METADATA'},
{ {
name: _('/external/re-exports/index.js'), name: _('/external/re-exports/index.js'),
contents: `export {X} from 'lib-1';\nexport {Y} from 'lib-1/sub-1';` contents: `export {X} from 'lib-1';\nexport {\n Y,\n Z\n} from 'lib-1/sub-1';`
}, },
{name: _('/external/re-exports/package.json'), contents: '{"esm2015": "./index.js"}'}, {name: _('/external/re-exports/package.json'), contents: '{"esm2015": "./index.js"}'},
{name: _('/external/re-exports/index.metadata.json'), contents: 'MOCK METADATA'}, {name: _('/external/re-exports/index.metadata.json'), contents: 'MOCK METADATA'},
@ -288,20 +288,44 @@ runInEachFileSystem(() => {
describe('hasImportOrReexportStatements', () => { describe('hasImportOrReexportStatements', () => {
it('should return true if there is an import statement', () => { it('should return true if there is an import statement', () => {
expect(hasImportOrReexportStatements('import {X} from "some/x";')).toBe(true); expect(hasImportOrReexportStatements('import {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('import {X} from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements('import * as X from "some/x";')).toBe(true); expect(hasImportOrReexportStatements('import * as X from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('import * as X from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements('blah blah\n\n import {X} from "some/x";\nblah blah')) expect(hasImportOrReexportStatements('blah blah\n\n import {X} from "some/x";\nblah blah'))
.toBe(true); .toBe(true);
expect(
hasImportOrReexportStatements('blah blah\n\n import {X} from \'some/x\';\nblah blah'))
.toBe(true);
expect(hasImportOrReexportStatements('\t\timport {X} from "some/x";')).toBe(true); expect(hasImportOrReexportStatements('\t\timport {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('\t\timport {X} from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements('\t\timport {\n X,\n Y\n} from "some/x";'))
.toBe(true);
expect(hasImportOrReexportStatements('\t\timport {\n X,\n Y\n} from \'some/x\';'))
.toBe(true);
expect(hasImportOrReexportStatements('\t\timport "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('\t\timport \'some/x\';')).toBe(true);
}); });
it('should return true if there is a re-export statement', () => { it('should return true if there is a re-export statement', () => {
expect(hasImportOrReexportStatements('export {X} from "some/x";')).toBe(true); expect(hasImportOrReexportStatements('export {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('export {X} from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements('blah blah\n\n export {X} from "some/x";\nblah blah')) expect(hasImportOrReexportStatements('blah blah\n\n export {X} from "some/x";\nblah blah'))
.toBe(true); .toBe(true);
expect(
hasImportOrReexportStatements('blah blah\n\n export {X} from \'some/x\';\nblah blah'))
.toBe(true);
expect(hasImportOrReexportStatements('\t\texport {X} from "some/x";')).toBe(true); expect(hasImportOrReexportStatements('\t\texport {X} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('\t\texport {X} from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements('export {\n X,\n Y\n} from "some/x";')).toBe(true);
expect(hasImportOrReexportStatements('export {\n X,\n Y\n} from \'some/x\';')).toBe(true);
expect(hasImportOrReexportStatements( expect(hasImportOrReexportStatements(
'blah blah\n\n export * from "@angular/core;\nblah blah')) 'blah blah\n\n export * from "@angular/core";\nblah blah'))
.toBe(true);
expect(hasImportOrReexportStatements(
'blah blah\n\n export * from \'@angular/core\';\nblah blah'))
.toBe(true); .toBe(true);
}); });
it('should return false if there is no import nor re-export statement', () => { it('should return false if there is no import nor re-export statement', () => {
expect(hasImportOrReexportStatements('blah blah')).toBe(false); expect(hasImportOrReexportStatements('blah blah')).toBe(false);
expect(hasImportOrReexportStatements('export function moo() {}')).toBe(false); expect(hasImportOrReexportStatements('export function moo() {}')).toBe(false);