refactor(elements): ng-add schematics (#33723)
This PR brings a couple of changes; - Removes undeed dependencies in bazel targets such as `//packages/common` & `//packages/core` - Removes RxJs usage - Adds `document-register-element` to architect test targets - Use @schematics/angular helpers - Uses the standard `$source": "projectName"` to get the projectName, which is defined in the `schema.json` - Use workspace writer to update the workspace config PR Close #33723
This commit is contained in:

committed by
Matias Niemelä

parent
85a4a1ac60
commit
21ec7d92dd
@ -5,72 +5,74 @@
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import {Rule, SchematicContext, Tree, chain, noop} from '@angular-devkit/schematics';
|
||||
import {Rule, SchematicContext, SchematicsException, Tree, chain, noop} from '@angular-devkit/schematics';
|
||||
import {NodePackageInstallTask} from '@angular-devkit/schematics/tasks';
|
||||
import {NodeDependencyType, addPackageJsonDependency} from '@schematics/angular/utility/dependencies';
|
||||
import {getWorkspace} from '@schematics/angular/utility/workspace';
|
||||
|
||||
import {Schema} from './schema';
|
||||
|
||||
export default function(options: Schema): Rule {
|
||||
return chain([
|
||||
options && options.skipPackageJson ? noop() : addPackageJsonDependency(), addScript(options)
|
||||
options && options.skipPackageJson ? noop() : addPolyfillDependency(),
|
||||
addPolyfill(options),
|
||||
]);
|
||||
}
|
||||
|
||||
/** Adds a package.json dependency for document-register-element */
|
||||
function addPackageJsonDependency() {
|
||||
function addPolyfillDependency(): Rule {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
addPackageJsonDependency(host, {
|
||||
type: NodeDependencyType.Default,
|
||||
name: 'document-register-element',
|
||||
version: '^1.7.2',
|
||||
});
|
||||
context.logger.info('Added "document-register-element" as a dependency.');
|
||||
|
||||
if (host.exists('package.json')) {
|
||||
const jsonStr = host.read('package.json') !.toString('utf-8');
|
||||
const json = JSON.parse(jsonStr);
|
||||
|
||||
// If there are no dependencies, create an entry for dependencies.
|
||||
const type = 'dependencies';
|
||||
if (!json[type]) {
|
||||
json[type] = {};
|
||||
}
|
||||
|
||||
// If not already present, add the dependency.
|
||||
const pkg = 'document-register-element';
|
||||
const version = '^1.7.2';
|
||||
if (!json[type][pkg]) {
|
||||
json[type][pkg] = version;
|
||||
}
|
||||
|
||||
// Write the JSON back to package.json
|
||||
host.overwrite('package.json', JSON.stringify(json, null, 2));
|
||||
context.logger.log('info', 'Added `document-register-element` as a dependency.');
|
||||
|
||||
// Install the dependency
|
||||
context.addTask(new NodePackageInstallTask());
|
||||
}
|
||||
|
||||
return host;
|
||||
// Install the dependency
|
||||
context.addTask(new NodePackageInstallTask());
|
||||
};
|
||||
}
|
||||
|
||||
/** Adds the document-register-element.js script to the angular CLI json. */
|
||||
function addScript(options: Schema) {
|
||||
return (host: Tree, context: SchematicContext) => {
|
||||
const script = 'node_modules/document-register-element/build/document-register-element.js';
|
||||
/** Adds the document-register-element.js to the polyfills file. */
|
||||
function addPolyfill(options: Schema): Rule {
|
||||
return async(host: Tree, context: SchematicContext) => {
|
||||
const projectName = options.project;
|
||||
|
||||
|
||||
try {
|
||||
// Handle the new json - angular.json
|
||||
const angularJsonFile = host.read('angular.json');
|
||||
if (angularJsonFile) {
|
||||
const json = JSON.parse(angularJsonFile.toString('utf-8'));
|
||||
const project = Object.keys(json['projects'])[0] || options.project;
|
||||
const scripts = json['projects'][project]['architect']['build']['options']['scripts'];
|
||||
scripts.push({input: script});
|
||||
host.overwrite('angular.json', JSON.stringify(json, null, 2));
|
||||
}
|
||||
} catch {
|
||||
context.logger.log(
|
||||
'warn', 'Failed to add the polyfill document-register-element.js to scripts');
|
||||
if (!projectName) {
|
||||
throw new SchematicsException('Option "project" is required.');
|
||||
}
|
||||
|
||||
context.logger.log('info', 'Added document-register-element.js polyfill to scripts');
|
||||
const workspace = await getWorkspace(host);
|
||||
const project = workspace.projects.get(projectName);
|
||||
|
||||
return host;
|
||||
if (!project) {
|
||||
throw new SchematicsException(`Project ${projectName} is not defined in this workspace.`);
|
||||
}
|
||||
|
||||
if (project.extensions['projectType'] !== 'application') {
|
||||
throw new SchematicsException(
|
||||
`@angular/elements requires a project type of "application" but ${projectName} isn't.`);
|
||||
}
|
||||
|
||||
const buildTarget = project.targets.get('build');
|
||||
if (!buildTarget || !buildTarget.options) {
|
||||
throw new SchematicsException(`Cannot find 'options' for ${projectName} build target.`);
|
||||
}
|
||||
|
||||
const {polyfills} = buildTarget.options;
|
||||
if (typeof polyfills !== 'string') {
|
||||
throw new SchematicsException(`polyfills for ${projectName} build target is not a string.`);
|
||||
}
|
||||
|
||||
const content = host.read(polyfills).toString();
|
||||
if (!content.includes('document-register-element')) {
|
||||
// Add string at the end of the file.
|
||||
const recorder = host.beginUpdate(polyfills);
|
||||
recorder.insertRight(content.length, `import 'document-register-element';\n`);
|
||||
host.commitUpdate(recorder);
|
||||
}
|
||||
|
||||
context.logger.info('Added "document-register-element" to polyfills.');
|
||||
};
|
||||
}
|
||||
|
Reference in New Issue
Block a user