fix(bazel): Remove angular devkit and restore ngc postinstall (#32946)

This commit removes `@angular-devkit/build-angular` from package.json
for a project that opts into Bazel. This is because the package adds a
dependency on node-sass, which is rejected by Bazel due to its absense.

This commit also appends to `scripts.postinstall` if it already exists.
This is needed because `ng new` in CLI v9 now automatically adds a
postinstall step for `ngcc`.

PR Close #32946
This commit is contained in:
Keen Yee Liau
2019-10-16 16:28:09 -07:00
committed by Matias Niemelä
parent 86e1e6c082
commit f0366843ea
3 changed files with 82 additions and 5 deletions

54
packages/bazel/src/schematics/ng-add/index.ts Executable file → Normal file
View File

@ -76,6 +76,47 @@ function addDevDependenciesToPackageJson(options: Schema) {
};
}
/**
* Remove packages that are not needed under Bazel.
* @param options
*/
function removeObsoleteDependenciesFromPackageJson(options: Schema) {
return (host: Tree) => {
const packageJson = 'package.json';
if (!host.exists(packageJson)) {
throw new Error(`Could not find ${packageJson}`);
}
const buffer = host.read(packageJson);
if (!buffer) {
throw new Error('Failed to read package.json content');
}
const content = buffer.toString();
const jsonAst = parseJsonAst(content) as JsonAstObject;
const deps = findPropertyInAstObject(jsonAst, 'dependencies') as JsonAstObject;
const devDeps = findPropertyInAstObject(jsonAst, 'devDependencies') as JsonAstObject;
const depsToRemove = [
'@angular-devkit/build-angular',
];
const recorder = host.beginUpdate(packageJson);
for (const packageName of depsToRemove) {
const depNode = findPropertyInAstObject(deps, packageName);
if (depNode) {
removeKeyValueInAstObject(recorder, content, deps, packageName);
}
const devDepNode = findPropertyInAstObject(devDeps, packageName);
if (devDepNode) {
removeKeyValueInAstObject(recorder, content, devDeps, packageName);
}
}
host.commitUpdate(recorder);
return host;
};
}
/**
* Append additional Javascript / Typescript files needed to compile an Angular
* project under Bazel.
@ -292,13 +333,19 @@ function addPostinstallToGenerateNgSummaries() {
}
const scripts = findPropertyInAstObject(jsonAst, 'scripts') as JsonAstObject;
const recorder = host.beginUpdate(packageJson);
const ngcCommand = 'ngc -p ./angular-metadata.tsconfig.json';
if (scripts) {
insertPropertyInAstObjectInOrder(
recorder, scripts, 'postinstall', 'ngc -p ./angular-metadata.tsconfig.json', 4);
const postInstall = findPropertyInAstObject(scripts, 'postinstall');
if (postInstall) {
const command = `${postInstall.value}; ${ngcCommand}`;
replacePropertyInAstObject(recorder, scripts, 'postinstall', command);
} else {
insertPropertyInAstObjectInOrder(recorder, scripts, 'postinstall', ngcCommand, 4);
}
} else {
insertPropertyInAstObjectInOrder(
recorder, jsonAst, 'scripts', {
postinstall: 'ngc -p ./angular-metadata.tsconfig.json',
postinstall: ngcCommand,
},
2);
}
@ -329,6 +376,7 @@ export default function(options: Schema): Rule {
return chain([
addFilesRequiredByBazel(options),
addDevDependenciesToPackageJson(options),
removeObsoleteDependenciesFromPackageJson(options),
addPostinstallToGenerateNgSummaries(),
backupAngularJson(),
updateAngularJsonToUseBazelBuilder(options),

View File

@ -145,6 +145,29 @@ describe('ng-add schematic', () => {
expect(json.devDependencies['@angular/bazel']).toBe('1.2.3');
});
it('should remove unneeded dependencies', async() => {
const packageJson = JSON.parse(host.readContent('/package.json'));
packageJson.devDependencies['@angular-devkit/build-angular'] = '1.2.3';
host.overwrite('/package.json', JSON.stringify(packageJson));
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
const content = host.readContent('/package.json');
const json = JSON.parse(content);
expect(json.devDependencies['angular-devkit/build-angular']).toBeUndefined();
});
it('should append to scripts.postinstall if it already exists', async() => {
const packageJson = JSON.parse(host.readContent('/package.json'));
packageJson['scripts'] = {
postinstall: 'angular rocks',
};
host.overwrite('/package.json', JSON.stringify(packageJson));
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
const content = host.readContent('/package.json');
const json = JSON.parse(content);
expect(json.scripts['postinstall'])
.toBe('angular rocks; ngc -p ./angular-metadata.tsconfig.json');
});
it('should not create Bazel workspace file', async() => {
host = await schematicRunner.runSchematicAsync('ng-add', defaultOptions, host).toPromise();
const {files} = host;