fix(ngcc): correctly retrieve a package's version from its package.json
(#37040)
In order to retrieve the ngcc configuration (if any) for an entry-point, ngcc has to detect the containing package's version. Previously, ngcc would try to read the version from the entry-point's `package.json` file, which was different than the package's top-level `package.json` for secondary entry-points. For example, it would try to read it from `node_modules/@angular/common/http/package.json` for entry-point `@angular/common/http`. However, the `package.json` files for secondary entry-points are not guaranteed to include a `version` property. This commit fixes this by first trying to read the version from the _package's_ `package.json` (falling back to the entry-point's `package.json`). For example, it will first try to read it from `@angular/common/package.json` for entry-point `@angular/common/http`. PR Close #37040
This commit is contained in:

committed by
Misko Hevery

parent
eabe3b4c39
commit
11c04027ab
@ -125,21 +125,25 @@ export type GetEntryPointResult =
|
||||
export function getEntryPointInfo(
|
||||
fs: FileSystem, config: NgccConfiguration, logger: Logger, packagePath: AbsoluteFsPath,
|
||||
entryPointPath: AbsoluteFsPath): GetEntryPointResult {
|
||||
const packageJsonPath = resolve(entryPointPath, 'package.json');
|
||||
const loadedEntryPointPackageJson = loadPackageJson(fs, packageJsonPath);
|
||||
const packageVersion = getPackageVersion(loadedEntryPointPackageJson);
|
||||
const packagePackageJsonPath = resolve(packagePath, 'package.json');
|
||||
const entryPointPackageJsonPath = resolve(entryPointPath, 'package.json');
|
||||
const loadedPackagePackageJson = loadPackageJson(fs, packagePackageJsonPath);
|
||||
const loadedEntryPointPackageJson = (packagePackageJsonPath === entryPointPackageJsonPath) ?
|
||||
loadedPackagePackageJson :
|
||||
loadPackageJson(fs, entryPointPackageJsonPath);
|
||||
const packageVersion = getPackageVersion(loadedPackagePackageJson);
|
||||
const entryPointConfig =
|
||||
config.getPackageConfig(packagePath, packageVersion).entryPoints[entryPointPath];
|
||||
let entryPointPackageJson: EntryPointPackageJson;
|
||||
|
||||
if (entryPointConfig === undefined) {
|
||||
if (!fs.exists(packageJsonPath)) {
|
||||
if (!fs.exists(entryPointPackageJsonPath)) {
|
||||
// No `package.json` and no config.
|
||||
return NO_ENTRY_POINT;
|
||||
} else if (loadedEntryPointPackageJson === null) {
|
||||
// `package.json` exists but could not be parsed and there is no redeeming config.
|
||||
logger.warn(
|
||||
`Failed to read entry point info from invalid 'package.json' file: ${packageJsonPath}`);
|
||||
logger.warn(`Failed to read entry point info from invalid 'package.json' file: ${
|
||||
entryPointPackageJsonPath}`);
|
||||
|
||||
return INCOMPATIBLE_ENTRY_POINT;
|
||||
} else {
|
||||
@ -302,13 +306,12 @@ function guessTypingsFromPackageJson(
|
||||
/**
|
||||
* Find the version of the package at `packageJsonPath`.
|
||||
*
|
||||
* The version is read off of the `version` property of `packageJson`. It is assumed that even if
|
||||
* `packageJson` corresponds to a secondary entry-point (e.g. `@angular/common/http`) it will still
|
||||
* contain the same version as the main package (e.g. `@angular/common`).
|
||||
* The version is read off of the `version` property of the package's `package.json` file (if
|
||||
* available).
|
||||
*
|
||||
* @param packageJson the parsed `package.json` of the package or one of its entry-points (if
|
||||
* available).
|
||||
* @returns the version string or `null` if the `package.json` is not available.
|
||||
* @param packageJson the parsed `package.json` of the package (if available).
|
||||
* @returns the version string or `null` if the `pckage.json` file is missing or doesn't contain a
|
||||
* version.
|
||||
*/
|
||||
function getPackageVersion(packageJson: EntryPointPackageJson|null): string|null {
|
||||
return packageJson?.version ?? null;
|
||||
|
Reference in New Issue
Block a user