Skip to content

Commit

Permalink
feat(@schematics/angular): add migration to remove emitDecoratorMetadata
Browse files Browse the repository at this point in the history
Add migration to remove 'emitDecoratorMetadata' TypeScript compiler option. Decorator metadata is no longer needed by Angular.

Read more about this option here: https://www.typescriptlang.org/docs/handbook/decorators.html#metadata
  • Loading branch information
alan-agius4 committed Feb 18, 2021
1 parent c986832 commit 96a4467
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,11 @@
"version": "12.0.0-next.1",
"factory": "./update-12/update-zonejs",
"description": "Update 'zone.js' to version 0.11.x. Read more about this here: https://github.com/angular/angular/blob/master/packages/zone.js/CHANGELOG.md#breaking-changes-since-zonejs-v0111"
},
"remove-emit-decorator-metadata": {
"version": "12.0.0-next.2",
"factory": "./update-12/remove-emit-decorator-metadata",
"description": "Remove 'emitDecoratorMetadata' TypeScript compiler option. Decorator metadata is no longer needed by Angular. Read more about this here: https://www.typescriptlang.org/docs/handbook/decorators.html#metadata"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* 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 { join } from '@angular-devkit/core';
import { DirEntry, Rule } from '@angular-devkit/schematics';
import { JSONFile } from '../../utility/json-file';

function* visitJsonFiles(directory: DirEntry): IterableIterator<string> {
for (const path of directory.subfiles) {
if (!path.endsWith('.json')) {
continue;
}

yield join(directory.path, path);
}

for (const path of directory.subdirs) {
if (path === 'node_modules' || path.startsWith('.')) {
continue;
}

yield* visitJsonFiles(directory.dir(path));
}
}

export default function (): Rule {
return tree => {
for (const path of visitJsonFiles(tree.root)) {
const content = tree.read(path);
if (content?.toString().includes('"emitDecoratorMetadata"')) {
const json = new JSONFile(tree, path);
json.remove(['compilerOptions', 'emitDecoratorMetadata']);
}
}
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* 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 { EmptyTree } from '@angular-devkit/schematics';
import { SchematicTestRunner, UnitTestTree } from '@angular-devkit/schematics/testing';
import { parse as parseJson } from 'jsonc-parser';

describe('Migration to remove "emitDecoratorMetadata" compiler option', () => {
const schematicName = 'remove-emit-decorator-metadata';

const schematicRunner = new SchematicTestRunner(
'migrations',
require.resolve('../migration-collection.json'),
);

// tslint:disable-next-line: no-any
function readJsonFile(tree: UnitTestTree, filePath: string): any {
return parseJson(tree.readContent(filePath).toString());
}

let tree: UnitTestTree;
beforeEach(() => {
tree = new UnitTestTree(new EmptyTree());
});

it(`should rename 'emitDecoratorMetadata' when set to false`, async () => {
tree.create('/tsconfig.json', JSON.stringify({
compilerOptions: {
emitDecoratorMetadata: false,
strict: true,
},
}, undefined, 2));

const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
const { compilerOptions } = readJsonFile(newTree, '/tsconfig.json');
expect(compilerOptions['emitDecoratorMetadata']).toBeUndefined();
expect(compilerOptions['strict']).toBeTrue();
});

it(`should rename 'emitDecoratorMetadata' when set to true`, async () => {
tree.create('/tsconfig.json', JSON.stringify({
compilerOptions: {
emitDecoratorMetadata: true,
strict: true,
},
}, undefined, 2));

const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
const { compilerOptions } = readJsonFile(newTree, '/tsconfig.json');
expect(compilerOptions['emitDecoratorMetadata']).toBeUndefined();
expect(compilerOptions['strict']).toBeTrue();
});

it(`should not rename 'emitDecoratorMetadata' when it's not under 'compilerOptions'`, async () => {
tree.create('/foo.json', JSON.stringify({
options: {
emitDecoratorMetadata: true,
},
}, undefined, 2));

const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
const { options } = readJsonFile(newTree, '/foo.json');
expect(options['emitDecoratorMetadata']).toBeTrue();
});
});

0 comments on commit 96a4467

Please sign in to comment.