diff --git a/packages/compiler-cli/src/ngcc/src/packages/entry_point.ts b/packages/compiler-cli/src/ngcc/src/packages/entry_point.ts index 7b9bec669d..59742bfb31 100644 --- a/packages/compiler-cli/src/ngcc/src/packages/entry_point.ts +++ b/packages/compiler-cli/src/ngcc/src/packages/entry_point.ts @@ -50,6 +50,21 @@ interface EntryPointPackageJson { typings?: string; // TypeScript .d.ts files } +/** + * Parses the JSON from a package.json file. + * @param packageJsonPath the absolute path to the package.json file. + * @returns JSON from the package.json file if it is valid, `null` otherwise. + */ +function loadEntryPointPackage(packageJsonPath: string): {[key: string]: any}|null { + try { + return JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); + } catch (e) { + // We may have run into a package.json with unexpected symbols + console.warn(`Failed to read entry point info from ${packageJsonPath} with error ${e}.`); + return null; + } +} + /** * Try to get entry point info from the given path. * @param pkgPath the absolute path to the containing npm package @@ -62,6 +77,11 @@ export function getEntryPointInfo(pkgPath: string, entryPoint: string): EntryPoi return null; } + const entryPointPackageJson = loadEntryPointPackage(packageJsonPath); + if (!entryPointPackageJson) { + return null; + } + // If there is `esm2015` then `es2015` will be FESM2015, otherwise ESM2015. // If there is `esm5` then `module` will be FESM5, otherwise it will be ESM5. const { @@ -75,8 +95,7 @@ export function getEntryPointInfo(pkgPath: string, entryPoint: string): EntryPoi esm2015, esm5, main - }: EntryPointPackageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')); - + } = entryPointPackageJson; // Minimum requirement is that we have typings and one of esm2015 or fesm2015 formats. if (!typings || !(fesm2015 || esm2015)) { return null; diff --git a/packages/compiler-cli/src/ngcc/test/packages/entry_point_spec.ts b/packages/compiler-cli/src/ngcc/test/packages/entry_point_spec.ts index 3cae131478..d84733aaf5 100644 --- a/packages/compiler-cli/src/ngcc/test/packages/entry_point_spec.ts +++ b/packages/compiler-cli/src/ngcc/test/packages/entry_point_spec.ts @@ -78,6 +78,11 @@ describe('getEntryPointInfo()', () => { umd: `/some_package/material_style/bundles/material_style.umd.js`, }); }); + + it('should return null if the package.json is not valid JSON', () => { + const entryPoint = getEntryPointInfo('/some_package', '/some_package/unexpected_symbols'); + expect(entryPoint).toBe(null); + }); }); function createMockFileSystem() { @@ -115,8 +120,15 @@ function createMockFileSystem() { "module": "./esm5/material_style.es5.js", "es2015": "./esm2015/material_style.js" }`, - 'material_style.metadata.json': 'some meta data' - } + 'material_style.metadata.json': 'some meta data', + }, + 'unexpected_symbols': { + // package.json might not be a valid JSON + // for example, @schematics/angular contains a package.json blueprint + // with unexpected symbols + 'package.json': + '{"devDependencies": {<% if (!minimal) { %>"@types/jasmine": "~2.8.8" <% } %>}}', + }, } }); }