feat(ngcc): support ignoreMissingDependencies in ngcc config (#33192)
Normally, when ngcc encounters a package with missing dependencies while attempting to determine a compilation ordering, it will ignore that package. This commit adds a configuration for a flag to tell ngcc to compile the package anyway, regardless of any missing dependencies. FW-1931 #resolve PR Close #33192
This commit is contained in:
parent
afcff73be3
commit
4da2dda647
|
@ -148,7 +148,7 @@ export class DependencyResolver {
|
|||
|
||||
const missingDependencies = Array.from(missing).filter(dep => !builtinNodeJsModules.has(dep));
|
||||
|
||||
if (missingDependencies.length > 0) {
|
||||
if (missingDependencies.length > 0 && !entryPoint.ignoreMissingDependencies) {
|
||||
// This entry point has dependencies that are missing
|
||||
// so remove it from the graph.
|
||||
removeNodes(entryPoint, missingDependencies);
|
||||
|
|
|
@ -43,6 +43,13 @@ export interface NgccEntryPointConfig {
|
|||
* entry-point's package.json file.
|
||||
*/
|
||||
override?: PackageJsonFormatPropertiesMap;
|
||||
|
||||
/**
|
||||
* Normally, ngcc will skip compilation of entrypoints that contain imports that can't be resolved
|
||||
* or understood. If this option is specified, ngcc will proceed with compiling the entrypoint
|
||||
* even in the face of such missing dependencies.
|
||||
*/
|
||||
ignoreMissingDependencies?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -36,6 +36,8 @@ export interface EntryPoint extends JsonObject {
|
|||
typings: AbsoluteFsPath;
|
||||
/** Is this EntryPoint compiled with the Angular View Engine compiler? */
|
||||
compiledByAngular: boolean;
|
||||
/** Should ngcc ignore missing dependencies and process this entrypoint anyway? */
|
||||
ignoreMissingDependencies: boolean;
|
||||
}
|
||||
|
||||
export type JsonPrimitive = string | number | boolean | null;
|
||||
|
@ -120,6 +122,8 @@ export function getEntryPointInfo(
|
|||
package: packagePath,
|
||||
path: entryPointPath,
|
||||
typings: resolve(entryPointPath, typings), compiledByAngular,
|
||||
ignoreMissingDependencies:
|
||||
entryPointConfig !== undefined ? !!entryPointConfig.ignoreMissingDependencies : false,
|
||||
};
|
||||
|
||||
return entryPointInfo;
|
||||
|
|
|
@ -43,33 +43,46 @@ runInEachFileSystem(() => {
|
|||
let third: EntryPoint;
|
||||
let fourth: EntryPoint;
|
||||
let fifth: EntryPoint;
|
||||
let sixthIgnoreMissing: EntryPoint;
|
||||
let dependencies: DepMap;
|
||||
|
||||
beforeEach(() => {
|
||||
first = {
|
||||
path: _('/first'),
|
||||
packageJson: {esm5: './index.js'},
|
||||
compiledByAngular: true
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
} as EntryPoint;
|
||||
second = {
|
||||
path: _('/second'),
|
||||
packageJson: {esm2015: './sub/index.js'},
|
||||
compiledByAngular: true
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
} as EntryPoint;
|
||||
third = {
|
||||
path: _('/third'),
|
||||
packageJson: {fesm5: './index.js'},
|
||||
compiledByAngular: true
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
} as EntryPoint;
|
||||
fourth = {
|
||||
path: _('/fourth'),
|
||||
packageJson: {fesm2015: './sub2/index.js'},
|
||||
compiledByAngular: true
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
} as EntryPoint;
|
||||
fifth = {
|
||||
path: _('/fifth'),
|
||||
packageJson: {module: './index.js'},
|
||||
compiledByAngular: true
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
} as EntryPoint;
|
||||
|
||||
sixthIgnoreMissing = {
|
||||
path: _('/sixth'),
|
||||
packageJson: {module: './index.js'},
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: true,
|
||||
} as EntryPoint;
|
||||
|
||||
dependencies = {
|
||||
|
@ -129,6 +142,30 @@ runInEachFileSystem(() => {
|
|||
]);
|
||||
});
|
||||
|
||||
it('should cope with entry points that will depend upon an invalid entry-point, when told to ignore missing dependencies',
|
||||
() => {
|
||||
spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({
|
||||
[_('/first/index.js')]: {resolved: [sixthIgnoreMissing.path], missing: []},
|
||||
[_('/sixth/index.js')]: {resolved: [], missing: ['/missing']},
|
||||
}));
|
||||
// Note that we will process `first` after `second`, which has the missing dependency.
|
||||
const result = resolver.sortEntryPointsByDependency([sixthIgnoreMissing, first]);
|
||||
expect(result.entryPoints).toEqual([sixthIgnoreMissing, first]);
|
||||
expect(result.invalidEntryPoints).toEqual([]);
|
||||
});
|
||||
|
||||
it('should not transitively ignore missing dependencies', () => {
|
||||
spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({
|
||||
[_('/first/index.js')]: {resolved: [], missing: ['/missing']},
|
||||
[_('/second/sub/index.js')]: {resolved: [first.path], missing: []},
|
||||
[_('/sixth/index.js')]: {resolved: [second.path], missing: []},
|
||||
}));
|
||||
const result = resolver.sortEntryPointsByDependency([first, second, sixthIgnoreMissing]);
|
||||
// sixth has no missing dependencies, but it has _invalid_ dependencies, so it's not
|
||||
// compiled.
|
||||
expect(result.entryPoints).toEqual([]);
|
||||
});
|
||||
|
||||
it('should cope with entry points having multiple indirect missing dependencies', () => {
|
||||
spyOn(host, 'findDependencies').and.callFake(createFakeComputeDependencies({
|
||||
[_('/first/index.js')]: {resolved: [], missing: ['/missing1']},
|
||||
|
|
|
@ -22,6 +22,7 @@ export function makeTestEntryPoint(
|
|||
path: absoluteFrom(`/node_modules/${entryPointName}`),
|
||||
typings: absoluteFrom(`/node_modules/${entryPointName}/index.d.ts`),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -143,6 +143,7 @@ runInEachFileSystem(() => {
|
|||
path: absoluteFrom('/node_modules/test'),
|
||||
typings: absoluteFrom('/node_modules/test/index.d.ts'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
};
|
||||
const esm5bundle = makeEntryPointBundle(fs, entryPoint, './index.js', false, 'esm5', true);
|
||||
|
||||
|
@ -189,6 +190,7 @@ runInEachFileSystem(() => {
|
|||
path: absoluteFrom('/node_modules/test'),
|
||||
typings: absoluteFrom('/node_modules/test/index.d.ts'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
};
|
||||
const esm5bundle = makeEntryPointBundle(
|
||||
fs, entryPoint, './index.js', false, 'esm5', /* transformDts */ true,
|
||||
|
@ -210,6 +212,7 @@ runInEachFileSystem(() => {
|
|||
path: absoluteFrom('/node_modules/test'),
|
||||
typings: absoluteFrom('/node_modules/test/index.d.ts'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
};
|
||||
const esm5bundle = makeEntryPointBundle(
|
||||
fs, entryPoint, './index.js', false, 'esm5', /* transformDts */ true,
|
||||
|
|
|
@ -50,6 +50,7 @@ runInEachFileSystem(() => {
|
|||
_(`/project/node_modules/some_package/valid_entry_point/valid_entry_point.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/valid_entry_point'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -109,6 +110,7 @@ runInEachFileSystem(() => {
|
|||
typings: _('/project/node_modules/some_package/valid_entry_point/some_other.d.ts'),
|
||||
packageJson: overriddenPackageJson,
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -155,6 +157,7 @@ runInEachFileSystem(() => {
|
|||
'/project/node_modules/some_package/missing_package_json/missing_package_json.d.ts'),
|
||||
packageJson: {name: 'some_package/missing_package_json', ...override},
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -211,6 +214,7 @@ runInEachFileSystem(() => {
|
|||
typings: _(`/project/node_modules/some_package/missing_typings/${typingsPath}.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/missing_typings'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -234,6 +238,7 @@ runInEachFileSystem(() => {
|
|||
typings: _(`/project/node_modules/some_package/missing_metadata/missing_metadata.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/missing_metadata'),
|
||||
compiledByAngular: false,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -260,6 +265,7 @@ runInEachFileSystem(() => {
|
|||
typings: _('/project/node_modules/some_package/missing_metadata/missing_metadata.d.ts'),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/missing_metadata'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -288,6 +294,7 @@ runInEachFileSystem(() => {
|
|||
packageJson:
|
||||
loadPackageJson(fs, '/project/node_modules/some_package/types_rather_than_typings'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -319,6 +326,7 @@ runInEachFileSystem(() => {
|
|||
typings: _(`/project/node_modules/some_package/material_style/material_style.d.ts`),
|
||||
packageJson: loadPackageJson(fs, '/project/node_modules/some_package/material_style'),
|
||||
compiledByAngular: true,
|
||||
ignoreMissingDependencies: false,
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue