mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-15 01:54:04 +08:00
fix(@schematics/angular): remove solution style tsconfig from new projects
Following the issues highlighted in https://docs.google.com/document/d/1eB6cGCG_2ircfS5GzpDC9dBgikeYYcMxghVH5sDESHw/edit?usp=sharing and discussions held with the TypeScript team. The best course of action is to rollback this feature. In future, it is not excluded that solution style tsconfigs are re-introduced.. Closes #18040 and closes #18170
This commit is contained in:
parent
fc5d2b3ff2
commit
8b96e52d83
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/app",
|
||||
"types": []
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/spec",
|
||||
"types": [
|
||||
|
@ -35,7 +35,6 @@ import { JSONFile } from '../utility/json-file';
|
||||
import { latestVersions } from '../utility/latest-versions';
|
||||
import { applyLintFix } from '../utility/lint-fix';
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { addTsConfigProjectReferences, verifyBaseTsConfigExists } from '../utility/tsconfig';
|
||||
import { validateProjectName } from '../utility/validation';
|
||||
import { getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { Builders, ProjectType } from '../utility/workspace-models';
|
||||
@ -280,7 +279,6 @@ export default function (options: ApplicationOptions): Rule {
|
||||
}
|
||||
|
||||
validateProjectName(options.name);
|
||||
verifyBaseTsConfigExists(host);
|
||||
|
||||
const appRootSelector = `${options.prefix}-root`;
|
||||
const componentOptions: Partial<ComponentOptions> = !options.minimal ?
|
||||
@ -363,10 +361,6 @@ export default function (options: ApplicationOptions): Rule {
|
||||
}),
|
||||
move(sourceDir),
|
||||
]), MergeStrategy.Overwrite),
|
||||
addTsConfigProjectReferences([
|
||||
join(appDir, 'tsconfig.app.json'),
|
||||
... options.minimal ? [] : [join(appDir, 'tsconfig.spec.json')],
|
||||
]),
|
||||
options.minimal ? noop() : schematic('e2e', e2eOptions),
|
||||
options.skipPackageJson ? noop() : addDependenciesToPackageJson(options),
|
||||
options.lintFix ? applyLintFix(appDir) : noop(),
|
||||
|
@ -80,28 +80,6 @@ describe('Application Schematic', () => {
|
||||
expect(workspace.defaultProject).toBe('foo');
|
||||
});
|
||||
|
||||
it('should add references in solution style tsconfig', async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('application', defaultOptions, workspaceTree)
|
||||
.toPromise();
|
||||
|
||||
const { references } = readJsonFile(tree, '/tsconfig.json');
|
||||
expect(references).toEqual([
|
||||
{ path: './projects/foo/tsconfig.app.json' },
|
||||
{ path: './projects/foo/tsconfig.spec.json' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('minimal=true should add correct reference in tsconfig', async () => {
|
||||
const options = { ...defaultOptions, minimal: true };
|
||||
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
|
||||
.toPromise();
|
||||
|
||||
const { references } = readJsonFile(tree, '/tsconfig.json');
|
||||
expect(references).toEqual([
|
||||
{ path: './projects/foo/tsconfig.app.json' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should set the prefix to app if none is set', async () => {
|
||||
const options = { ...defaultOptions };
|
||||
|
||||
@ -166,7 +144,7 @@ describe('Application Schematic', () => {
|
||||
.toPromise();
|
||||
const { files, extends: _extends } = readJsonFile(tree, '/projects/foo/tsconfig.app.json');
|
||||
expect(files).toEqual(['src/main.ts', 'src/polyfills.ts']);
|
||||
expect(_extends).toBe('../../tsconfig.base.json');
|
||||
expect(_extends).toBe('../../tsconfig.json');
|
||||
});
|
||||
|
||||
it('should set the right paths in the tsconfig.spec.json', async () => {
|
||||
@ -174,7 +152,7 @@ describe('Application Schematic', () => {
|
||||
.toPromise();
|
||||
const { files, extends: _extends } = readJsonFile(tree, '/projects/foo/tsconfig.spec.json');
|
||||
expect(files).toEqual(['src/test.ts', 'src/polyfills.ts']);
|
||||
expect(_extends).toBe('../../tsconfig.base.json');
|
||||
expect(_extends).toBe('../../tsconfig.json');
|
||||
});
|
||||
|
||||
it('should set the right path and prefix in the tslint file', async () => {
|
||||
@ -401,9 +379,9 @@ describe('Application Schematic', () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('application', options, workspaceTree)
|
||||
.toPromise();
|
||||
const appTsConfig = readJsonFile(tree, '/tsconfig.app.json');
|
||||
expect(appTsConfig.extends).toEqual('./tsconfig.base.json');
|
||||
expect(appTsConfig.extends).toEqual('./tsconfig.json');
|
||||
const specTsConfig = readJsonFile(tree, '/tsconfig.spec.json');
|
||||
expect(specTsConfig.extends).toEqual('./tsconfig.base.json');
|
||||
expect(specTsConfig.extends).toEqual('./tsconfig.json');
|
||||
expect(specTsConfig.files).toEqual(['src/test.ts', 'src/polyfills.ts']);
|
||||
});
|
||||
|
||||
@ -447,9 +425,9 @@ describe('Application Schematic', () => {
|
||||
expect(buildOpt.tsConfig).toEqual('foo/tsconfig.app.json');
|
||||
|
||||
const appTsConfig = readJsonFile(tree, '/foo/tsconfig.app.json');
|
||||
expect(appTsConfig.extends).toEqual('../tsconfig.base.json');
|
||||
expect(appTsConfig.extends).toEqual('../tsconfig.json');
|
||||
const specTsConfig = readJsonFile(tree, '/foo/tsconfig.spec.json');
|
||||
expect(specTsConfig.extends).toEqual('../tsconfig.base.json');
|
||||
expect(specTsConfig.extends).toEqual('../tsconfig.json');
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/e2e",
|
||||
"module": "commonjs",
|
||||
|
@ -18,7 +18,6 @@ import {
|
||||
url,
|
||||
} from '@angular-devkit/schematics';
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { verifyBaseTsConfigExists } from '../utility/tsconfig';
|
||||
import { getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { Builders } from '../utility/workspace-models';
|
||||
import { Schema as E2eOptions } from './schema';
|
||||
@ -32,8 +31,6 @@ export default function (options: E2eOptions): Rule {
|
||||
throw new SchematicsException(`Project name "${appProject}" doesn't not exist.`);
|
||||
}
|
||||
|
||||
verifyBaseTsConfigExists(host);
|
||||
|
||||
const root = join(normalize(project.root), 'e2e');
|
||||
|
||||
project.targets.add({
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/lib",
|
||||
"target": "es2015",
|
||||
|
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/spec",
|
||||
"types": [
|
||||
|
@ -25,7 +25,6 @@ import { NodeDependencyType, addPackageJsonDependency } from '../utility/depende
|
||||
import { latestVersions } from '../utility/latest-versions';
|
||||
import { applyLintFix } from '../utility/lint-fix';
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { addTsConfigProjectReferences, verifyBaseTsConfigExists } from '../utility/tsconfig';
|
||||
import { validateProjectName } from '../utility/validation';
|
||||
import { getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { Builders, ProjectType } from '../utility/workspace-models';
|
||||
@ -59,9 +58,9 @@ function updateJsonFile<T>(host: Tree, path: string, callback: UpdateJsonFn<T>):
|
||||
function updateTsConfig(packageName: string, ...paths: string[]) {
|
||||
|
||||
return (host: Tree) => {
|
||||
if (!host.exists('tsconfig.base.json')) { return host; }
|
||||
if (!host.exists('tsconfig.json')) { return host; }
|
||||
|
||||
return updateJsonFile(host, 'tsconfig.base.json', (tsconfig: TsConfigPartialType) => {
|
||||
return updateJsonFile(host, 'tsconfig.json', (tsconfig: TsConfigPartialType) => {
|
||||
if (!tsconfig.compilerOptions.paths) {
|
||||
tsconfig.compilerOptions.paths = {};
|
||||
}
|
||||
@ -174,7 +173,6 @@ export default function (options: LibraryOptions): Rule {
|
||||
const prefix = options.prefix;
|
||||
|
||||
validateProjectName(options.name);
|
||||
verifyBaseTsConfigExists(host);
|
||||
|
||||
// If scoped project (i.e. "@foo/bar"), convert projectDir to "foo/bar".
|
||||
const projectName = options.name;
|
||||
@ -240,10 +238,6 @@ export default function (options: LibraryOptions): Rule {
|
||||
path: sourceDir,
|
||||
project: options.name,
|
||||
}),
|
||||
addTsConfigProjectReferences([
|
||||
`${projectRoot}/tsconfig.lib.json`,
|
||||
`${projectRoot}/tsconfig.spec.json`,
|
||||
]),
|
||||
options.lintFix ? applyLintFix(sourceDir) : noop(),
|
||||
(_tree: Tree, context: SchematicContext) => {
|
||||
if (!options.skipPackageJson && !options.skipInstall) {
|
||||
|
@ -202,11 +202,11 @@ describe('Library Schematic', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe(`update tsconfig.base.json`, () => {
|
||||
describe(`update tsconfig.json`, () => {
|
||||
it(`should add paths mapping to empty tsconfig`, async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree).toPromise();
|
||||
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.base.json');
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json');
|
||||
expect(tsConfigJson.compilerOptions.paths.foo).toBeTruthy();
|
||||
expect(tsConfigJson.compilerOptions.paths.foo.length).toEqual(2);
|
||||
expect(tsConfigJson.compilerOptions.paths.foo[0]).toEqual('dist/foo/foo');
|
||||
@ -214,7 +214,7 @@ describe('Library Schematic', () => {
|
||||
});
|
||||
|
||||
it(`should append to existing paths mappings`, async () => {
|
||||
workspaceTree.overwrite('tsconfig.base.json', JSON.stringify({
|
||||
workspaceTree.overwrite('tsconfig.json', JSON.stringify({
|
||||
compilerOptions: {
|
||||
paths: {
|
||||
'unrelated': ['./something/else.ts'],
|
||||
@ -224,7 +224,7 @@ describe('Library Schematic', () => {
|
||||
}));
|
||||
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree).toPromise();
|
||||
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.base.json');
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json');
|
||||
expect(tsConfigJson.compilerOptions.paths.foo).toBeTruthy();
|
||||
expect(tsConfigJson.compilerOptions.paths.foo.length).toEqual(3);
|
||||
expect(tsConfigJson.compilerOptions.paths.foo[1]).toEqual('dist/foo/foo');
|
||||
@ -237,7 +237,7 @@ describe('Library Schematic', () => {
|
||||
skipTsConfig: true,
|
||||
}, workspaceTree).toPromise();
|
||||
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.base.json');
|
||||
const tsConfigJson = getJsonFileContent(tree, 'tsconfig.json');
|
||||
expect(tsConfigJson.compilerOptions.paths).toBeUndefined();
|
||||
});
|
||||
});
|
||||
@ -266,12 +266,12 @@ describe('Library Schematic', () => {
|
||||
expect(pkgJson.name).toEqual(scopedName);
|
||||
|
||||
const tsConfigJson = getJsonFileContent(tree, '/projects/myscope/mylib/tsconfig.spec.json');
|
||||
expect(tsConfigJson.extends).toEqual('../../../tsconfig.base.json');
|
||||
expect(tsConfigJson.extends).toEqual('../../../tsconfig.json');
|
||||
|
||||
const cfg = JSON.parse(tree.readContent('/angular.json'));
|
||||
expect(cfg.projects['@myscope/mylib']).toBeDefined();
|
||||
|
||||
const rootTsCfg = getJsonFileContent(tree, '/tsconfig.base.json');
|
||||
const rootTsCfg = getJsonFileContent(tree, '/tsconfig.json');
|
||||
expect(rootTsCfg.compilerOptions.paths['@myscope/mylib']).toEqual(['dist/myscope/mylib/myscope-mylib', 'dist/myscope/mylib']);
|
||||
|
||||
const karmaConf = getFileContent(tree, '/projects/myscope/mylib/karma.conf.js');
|
||||
@ -316,9 +316,9 @@ describe('Library Schematic', () => {
|
||||
expect(buildOpt.tsConfig).toEqual('foo/tsconfig.lib.json');
|
||||
|
||||
const appTsConfig = getJsonFileContent(tree, '/foo/tsconfig.lib.json');
|
||||
expect(appTsConfig.extends).toEqual('../tsconfig.base.json');
|
||||
expect(appTsConfig.extends).toEqual('../tsconfig.json');
|
||||
const specTsConfig = getJsonFileContent(tree, '/foo/tsconfig.spec.json');
|
||||
expect(specTsConfig.extends).toEqual('../tsconfig.base.json');
|
||||
expect(specTsConfig.extends).toEqual('../tsconfig.json');
|
||||
});
|
||||
|
||||
it(`should add 'production' configuration`, async () => {
|
||||
@ -328,16 +328,4 @@ describe('Library Schematic', () => {
|
||||
const workspace = JSON.parse(tree.readContent('/angular.json'));
|
||||
expect(workspace.projects.foo.architect.build.configurations.production).toBeDefined();
|
||||
});
|
||||
|
||||
it('should add reference in solution style tsconfig', async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('library', defaultOptions, workspaceTree)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const { references } = getJsonFileContent(tree, '/tsconfig.json');
|
||||
expect(references).toEqual([
|
||||
{ path: './projects/foo/tsconfig.lib.json' },
|
||||
{ path: './projects/foo/tsconfig.spec.json' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -41,7 +41,7 @@
|
||||
"skipTsConfig": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "When true, does not update \"tsconfig.base.json\" to add a path mapping for the new library. The path mapping is needed to use the library in an app, but can be disabled here to simplify development."
|
||||
"description": "When true, does not update \"tsconfig.json\" to add a path mapping for the new library. The path mapping is needed to use the library in an app, but can be disabled here to simplify development."
|
||||
},
|
||||
"lintFix": {
|
||||
"type": "boolean",
|
||||
|
@ -73,9 +73,9 @@ function updateTsconfigExtendsRule(): Rule {
|
||||
}
|
||||
|
||||
// Rename workspace tsconfig to base tsconfig.
|
||||
host.rename('tsconfig.json', 'tsconfig.base.json');
|
||||
host.rename('tsconfig.json', 'tsconfig.json');
|
||||
|
||||
// Iterate over all tsconfig files and change the extends from 'tsconfig.json' 'tsconfig.base.json'
|
||||
// Iterate over all tsconfig files and change the extends from 'tsconfig.json' 'tsconfig.json'
|
||||
for (const [tsconfigPath, extendsAst] of visitExtendedJsonFiles(host.root, context.logger)) {
|
||||
const tsConfigDir = dirname(normalize(tsconfigPath));
|
||||
if ('/tsconfig.json' !== resolve(tsConfigDir, normalize(extendsAst.value))) {
|
||||
@ -127,7 +127,7 @@ export default function (): Rule {
|
||||
return (host, context) => {
|
||||
const logger = context.logger;
|
||||
|
||||
if (host.exists('tsconfig.base.json')) {
|
||||
if (host.exists('tsconfig.json')) {
|
||||
logger.info('Migration has already been executed.');
|
||||
|
||||
return;
|
||||
|
@ -79,16 +79,16 @@ describe('Migration to create "Solution Style" tsconfig', () => {
|
||||
createJsonFile(tree, 'src/tsconfig.worker.json', { extends: './../tsconfig.json', compilerOptions });
|
||||
});
|
||||
|
||||
it(`should rename 'tsconfig.json' to 'tsconfig.base.json'`, async () => {
|
||||
it(`should rename 'tsconfig.json' to 'tsconfig.json'`, async () => {
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
expect(newTree.exists('tsconfig.base.json')).toBeTrue();
|
||||
expect(newTree.exists('tsconfig.json')).toBeTrue();
|
||||
});
|
||||
|
||||
it(`should update extends from 'tsconfig.json' to 'tsconfig.base.json'`, async () => {
|
||||
it(`should update extends from 'tsconfig.json' to 'tsconfig.json'`, async () => {
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.json').extends).toEqual('./../tsconfig.base.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.spec.json').extends).toEqual('./../tsconfig.base.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.worker.json').extends).toEqual('./../tsconfig.base.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.json').extends).toEqual('./../tsconfig.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.spec.json').extends).toEqual('./../tsconfig.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.worker.json').extends).toEqual('./../tsconfig.json');
|
||||
});
|
||||
|
||||
it('should not update extends if not extended the root tsconfig', async () => {
|
||||
@ -118,7 +118,7 @@ describe('Migration to create "Solution Style" tsconfig', () => {
|
||||
it('should not error out when a JSON file is a blank', async () => {
|
||||
tree.create('blank.json', '');
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.json').extends).toEqual('./../tsconfig.base.json');
|
||||
expect(readJsonFile(newTree, 'src/tsconfig.json').extends).toEqual('./../tsconfig.json');
|
||||
});
|
||||
|
||||
it('should show warning with full path when parsing invalid JSON', async () => {
|
||||
|
@ -23,13 +23,13 @@ export default function (): Rule {
|
||||
return async (host, { logger }) => {
|
||||
// Workspace level tsconfig
|
||||
try {
|
||||
updateModuleAndTarget(host, 'tsconfig.base.json', {
|
||||
updateModuleAndTarget(host, 'tsconfig.json', {
|
||||
oldModule: 'esnext',
|
||||
newModule: 'es2020',
|
||||
});
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
`Unable to update 'tsconfig.base.json' module option from 'esnext' to 'es2020': ${
|
||||
`Unable to update 'tsconfig.json' module option from 'esnext' to 'es2020': ${
|
||||
error.message || error
|
||||
}`,
|
||||
);
|
||||
|
@ -91,7 +91,7 @@ describe('Migration to update target and module compiler options', () => {
|
||||
const compilerOptions = { target: 'es2015', module: 'esnext' };
|
||||
|
||||
// Workspace
|
||||
createJsonFile(tree, 'tsconfig.base.json', { compilerOptions });
|
||||
createJsonFile(tree, 'tsconfig.json', { compilerOptions });
|
||||
|
||||
// Application
|
||||
createJsonFile(tree, 'src/tsconfig.app.json', { compilerOptions });
|
||||
@ -106,19 +106,19 @@ describe('Migration to update target and module compiler options', () => {
|
||||
createJsonFile(tree, 'src/tsconfig.server.json', { compilerOptions: { module: 'commonjs' } });
|
||||
});
|
||||
|
||||
it(`should update module and target in workspace 'tsconfig.base.json'`, async () => {
|
||||
it(`should update module and target in workspace 'tsconfig.json'`, async () => {
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
const { module } = readJsonFile(newTree, 'tsconfig.base.json').compilerOptions;
|
||||
const { module } = readJsonFile(newTree, 'tsconfig.json').compilerOptions;
|
||||
expect(module).toBe('es2020');
|
||||
});
|
||||
|
||||
it(`should update module and target in 'tsconfig.base.json' which is referenced in option`, async () => {
|
||||
it(`should update module and target in 'tsconfig.json' which is referenced in option`, async () => {
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
const { module } = readJsonFile(newTree, 'src/tsconfig.spec.json').compilerOptions;
|
||||
expect(module).toBe('es2020');
|
||||
});
|
||||
|
||||
it(`should update module and target in 'tsconfig.base.json' which is referenced in a configuration`, async () => {
|
||||
it(`should update module and target in 'tsconfig.json' which is referenced in a configuration`, async () => {
|
||||
const newTree = await schematicRunner.runSchematicAsync(schematicName, {}, tree).toPromise();
|
||||
const { module } = readJsonFile(newTree, 'src/tsconfig.app.prod.json').compilerOptions;
|
||||
expect(module).toBe('es2020');
|
||||
|
@ -62,7 +62,7 @@ describe('Migration to version 9', () => {
|
||||
.toPromise();
|
||||
|
||||
// Pre version 9 - tsconfig.json was the base tsconfig file.
|
||||
tree.overwrite('tsconfig.json', tree.readContent('tsconfig.base.json'));
|
||||
tree.overwrite('tsconfig.json', tree.readContent('tsconfig.json'));
|
||||
});
|
||||
|
||||
it('should update apps tsConfig with stricter files inclusions', async () => {
|
||||
|
@ -82,7 +82,7 @@ describe('Migration to version 9', () => {
|
||||
.toPromise();
|
||||
|
||||
// Pre version 9 - tsconfig.json was the base tsconfig file.
|
||||
tree.overwrite('tsconfig.json', tree.readContent('tsconfig.base.json'));
|
||||
tree.overwrite('tsconfig.json', tree.readContent('tsconfig.json'));
|
||||
|
||||
const tsConfig = JSON.stringify(
|
||||
{
|
||||
|
@ -34,7 +34,6 @@ import { addPackageJsonDependency, getPackageJsonDependency } from '../utility/d
|
||||
import { findBootstrapModuleCall, findBootstrapModulePath } from '../utility/ng-ast-utils';
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { targetBuildNotFoundError } from '../utility/project-targets';
|
||||
import { addTsConfigProjectReferences, verifyBaseTsConfigExists } from '../utility/tsconfig';
|
||||
import { getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { BrowserBuilderOptions, Builders, OutputHashing } from '../utility/workspace-models';
|
||||
import { Schema as UniversalOptions } from './schema';
|
||||
@ -240,8 +239,6 @@ export default function (options: UniversalOptions): Rule {
|
||||
throw targetBuildNotFoundError();
|
||||
}
|
||||
|
||||
verifyBaseTsConfigExists(host);
|
||||
|
||||
const clientBuildOptions =
|
||||
(clientBuildTarget.options || {}) as unknown as BrowserBuilderOptions;
|
||||
|
||||
@ -285,9 +282,6 @@ export default function (options: UniversalOptions): Rule {
|
||||
updateConfigFile(options, tsConfigDirectory),
|
||||
wrapBootstrapCall(clientBuildOptions.main),
|
||||
addServerTransition(options, clientBuildOptions.main, clientProject.root),
|
||||
addTsConfigProjectReferences([
|
||||
join(tsConfigDirectory, 'tsconfig.server.json'),
|
||||
]),
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
@ -263,19 +263,4 @@ describe('Universal Schematic', () => {
|
||||
const contents = tree.readContent(filePath);
|
||||
expect(contents).toContain('@angular/localize/init');
|
||||
});
|
||||
|
||||
it('should add reference in solution style tsconfig', async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('universal', workspaceUniversalOptions, appTree)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const { references } = parseJson(tree.readContent('/tsconfig.json').toString(), JsonParseMode.Loose) as any;
|
||||
expect(references).toEqual([
|
||||
{ path: './tsconfig.app.json' },
|
||||
{ path: './tsconfig.spec.json' },
|
||||
{ path: './projects/bar/tsconfig.app.json' },
|
||||
{ path: './projects/bar/tsconfig.spec.json' },
|
||||
{ path: './tsconfig.server.json' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -1,70 +0,0 @@
|
||||
/**
|
||||
* @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 { JsonParseMode, parseJsonAst } from '@angular-devkit/core';
|
||||
import { Rule, SchematicsException, Tree } from '@angular-devkit/schematics';
|
||||
import { appendValueInAstArray, findPropertyInAstObject } from './json-utils';
|
||||
|
||||
const SOLUTION_TSCONFIG_PATH = 'tsconfig.json';
|
||||
|
||||
/**
|
||||
* Add project references in "Solution Style" tsconfig.
|
||||
*/
|
||||
export function addTsConfigProjectReferences(paths: string[]): Rule {
|
||||
return (host, context) => {
|
||||
const logger = context.logger;
|
||||
|
||||
// We need to read after each write to avoid missing `,` when appending multiple items.
|
||||
for (const path of paths) {
|
||||
const source = host.read(SOLUTION_TSCONFIG_PATH);
|
||||
if (!source) {
|
||||
// Solution tsconfig doesn't exist.
|
||||
logger.warn(`Cannot add reference '${path}' in '${SOLUTION_TSCONFIG_PATH}'. File doesn't exists.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const jsonAst = parseJsonAst(source.toString(), JsonParseMode.Loose);
|
||||
if (jsonAst?.kind !== 'object') {
|
||||
// Invalid JSON
|
||||
throw new SchematicsException(`Invalid JSON AST Object '${SOLUTION_TSCONFIG_PATH}'.`);
|
||||
}
|
||||
|
||||
// Solutions style tsconfig can contain 2 properties:
|
||||
// - 'files' with a value of empty array
|
||||
// - 'references'
|
||||
const filesAst = findPropertyInAstObject(jsonAst, 'files');
|
||||
const referencesAst = findPropertyInAstObject(jsonAst, 'references');
|
||||
if (
|
||||
filesAst?.kind !== 'array' ||
|
||||
filesAst.elements.length !== 0 ||
|
||||
referencesAst?.kind !== 'array'
|
||||
) {
|
||||
logger.warn(`Cannot add reference '${path}' in '${SOLUTION_TSCONFIG_PATH}'. It appears to be an invalid solution style tsconfig.`);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Append new paths
|
||||
const recorder = host.beginUpdate(SOLUTION_TSCONFIG_PATH);
|
||||
appendValueInAstArray(recorder, referencesAst, { 'path': `./${path}` }, 4);
|
||||
host.commitUpdate(recorder);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an exception when the base tsconfig doesn't exists.
|
||||
*/
|
||||
export function verifyBaseTsConfigExists(host: Tree): void {
|
||||
if (host.exists('tsconfig.base.json')) {
|
||||
return;
|
||||
}
|
||||
|
||||
throw new SchematicsException(`Cannot find base TypeScript configuration file 'tsconfig.base.json'.`);
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/**
|
||||
* @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, SchematicContext, Tree, callRule } from '@angular-devkit/schematics';
|
||||
import { addTsConfigProjectReferences } from './tsconfig';
|
||||
|
||||
const SOLUTION_TSCONFIG_PATH = 'tsconfig.json';
|
||||
|
||||
describe('addTsConfigProjectReference', () => {
|
||||
const context = {
|
||||
// tslint:disable-next-line:no-any
|
||||
logger: {} as any,
|
||||
} as SchematicContext;
|
||||
|
||||
const createTsConfig = (content: object) =>
|
||||
tree.create(SOLUTION_TSCONFIG_PATH, JSON.stringify(content, undefined, 2));
|
||||
|
||||
const parseTsConfig = (tree: Tree) =>
|
||||
// tslint:disable-next-line:no-non-null-assertion
|
||||
JSON.parse(tree.read(SOLUTION_TSCONFIG_PATH)!.toString());
|
||||
|
||||
let tree: Tree;
|
||||
beforeEach(() => {
|
||||
tree = new EmptyTree();
|
||||
});
|
||||
|
||||
it('works when references is an empty array', async () => {
|
||||
createTsConfig({
|
||||
files: [],
|
||||
references: [],
|
||||
});
|
||||
|
||||
const result = await callRule(
|
||||
addTsConfigProjectReferences(['foo/tsconfig.app.json']),
|
||||
tree,
|
||||
context,
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-non-null-assertion
|
||||
const { references } = parseTsConfig(result);
|
||||
expect(references).toEqual([
|
||||
{ path: './foo/tsconfig.app.json' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('works when references contains an element', async () => {
|
||||
createTsConfig({
|
||||
files: [],
|
||||
references: [
|
||||
{ path: './foo/tsconfig.spec.json' },
|
||||
],
|
||||
});
|
||||
|
||||
const result = await callRule(
|
||||
addTsConfigProjectReferences(['foo/tsconfig.app.json']),
|
||||
tree,
|
||||
context,
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-non-null-assertion
|
||||
const { references } = parseTsConfig(result);
|
||||
expect(references).toEqual([
|
||||
{ path: './foo/tsconfig.spec.json' },
|
||||
{ path: './foo/tsconfig.app.json' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('works when adding multiple references and contains an element', async () => {
|
||||
createTsConfig({
|
||||
files: [],
|
||||
references: [
|
||||
{ path: './foo/tsconfig.spec.json' },
|
||||
],
|
||||
});
|
||||
|
||||
const result = await callRule(
|
||||
addTsConfigProjectReferences([
|
||||
'foo/tsconfig.app.json',
|
||||
'foo/tsconfig.server.json',
|
||||
]),
|
||||
tree,
|
||||
context,
|
||||
)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-non-null-assertion
|
||||
const { references } = parseTsConfig(result);
|
||||
expect(references).toEqual([
|
||||
{ path: './foo/tsconfig.spec.json' },
|
||||
{ path: './foo/tsconfig.app.json' },
|
||||
{ path: './foo/tsconfig.server.json' },
|
||||
]);
|
||||
});
|
||||
});
|
@ -1,6 +1,6 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.base.json",
|
||||
"extends": "<%= relativePathToWorkspaceRoot %>/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "<%= relativePathToWorkspaceRoot %>/out-tsc/worker",
|
||||
"lib": [
|
||||
|
@ -19,7 +19,6 @@ import {
|
||||
import { JSONFile } from '../utility/json-file';
|
||||
import { parseName } from '../utility/parse-name';
|
||||
import { relativePathToWorkspaceRoot } from '../utility/paths';
|
||||
import { addTsConfigProjectReferences, verifyBaseTsConfigExists } from '../utility/tsconfig';
|
||||
import { buildDefaultPath, getWorkspace, updateWorkspace } from '../utility/workspace';
|
||||
import { BrowserBuilderOptions, LintBuilderOptions } from '../utility/workspace-models';
|
||||
import { Schema as WebWorkerOptions } from './schema';
|
||||
@ -118,8 +117,6 @@ export default function (options: WebWorkerOptions): Rule {
|
||||
throw new SchematicsException(`Web Worker requires a project type of "application".`);
|
||||
}
|
||||
|
||||
verifyBaseTsConfigExists(host);
|
||||
|
||||
const projectTarget = project.targets.get(options.target);
|
||||
if (!projectTarget) {
|
||||
throw new Error(`Target is not defined for this project.`);
|
||||
@ -160,9 +157,6 @@ export default function (options: WebWorkerOptions): Rule {
|
||||
options.snippet ? addSnippet(options) : noop(),
|
||||
// Add the worker.
|
||||
mergeWith(templateSource),
|
||||
addTsConfigProjectReferences([
|
||||
`${root}/tsconfig.worker.json`,
|
||||
]),
|
||||
]);
|
||||
};
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ describe('Web Worker Schematic', () => {
|
||||
appTree.overwrite('/angular.json', JSON.stringify(workspace));
|
||||
|
||||
const oldTsConfig = {
|
||||
extends: '../../../tsconfig.base.json',
|
||||
extends: '../../../tsconfig.json',
|
||||
include: [
|
||||
'**/*.ts',
|
||||
],
|
||||
@ -152,17 +152,4 @@ describe('Web Worker Schematic', () => {
|
||||
const { exclude } = JSON.parse(tree.readContent(tsConfigPath));
|
||||
expect(exclude).toContain('**/*.worker.ts');
|
||||
});
|
||||
|
||||
it('should add reference in solution style tsconfig', async () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('web-worker', defaultOptions, appTree)
|
||||
.toPromise();
|
||||
|
||||
// tslint:disable-next-line:no-any
|
||||
const { references } = parseJson(tree.readContent('/tsconfig.json').toString(), JsonParseMode.Loose) as any;
|
||||
expect(references).toEqual([
|
||||
{ path: './projects/bar/tsconfig.app.json' },
|
||||
{ path: './projects/bar/tsconfig.spec.json' },
|
||||
{ path: './projects/bar/tsconfig.worker.json' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
@ -1,28 +0,0 @@
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",<% if (strict) { %>
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,<% } %>
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
}<% if (strict) { %>,
|
||||
"angularCompilerOptions": {
|
||||
"strictInjectionParameters": true,
|
||||
"strictTemplates": true
|
||||
}<% } %>
|
||||
}
|
@ -1,10 +1,28 @@
|
||||
/*
|
||||
This is a "Solution Style" tsconfig.json file, and is used by editors and TypeScript’s language server to improve development experience.
|
||||
It is not intended to be used to perform a compilation.
|
||||
|
||||
To learn more about this file see: https://angular.io/config/solution-tsconfig.
|
||||
*/
|
||||
/* To learn more about this file see: https://angular.io/config/tsconfig. */
|
||||
{
|
||||
"files": [],
|
||||
"references": []
|
||||
"compileOnSave": false,
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"outDir": "./dist/out-tsc",<% if (strict) { %>
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,<% } %>
|
||||
"sourceMap": true,
|
||||
"declaration": false,
|
||||
"downlevelIteration": true,
|
||||
"experimentalDecorators": true,
|
||||
"moduleResolution": "node",
|
||||
"importHelpers": true,
|
||||
"target": "es2015",
|
||||
"module": "es2020",
|
||||
"lib": [
|
||||
"es2018",
|
||||
"dom"
|
||||
]
|
||||
}<% if (strict) { %>,
|
||||
"angularCompilerOptions": {
|
||||
"strictInjectionParameters": true,
|
||||
"strictTemplates": true
|
||||
}<% } %>
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ describe('Workspace Schematic', () => {
|
||||
'/package.json',
|
||||
'/README.md',
|
||||
'/tsconfig.json',
|
||||
'/tsconfig.base.json',
|
||||
'/tslint.json',
|
||||
]));
|
||||
});
|
||||
@ -68,7 +67,6 @@ describe('Workspace Schematic', () => {
|
||||
'/package.json',
|
||||
'/README.md',
|
||||
'/tsconfig.json',
|
||||
'/tsconfig.base.json',
|
||||
]));
|
||||
|
||||
expect(files).not.toContain('/tslint.json');
|
||||
@ -79,7 +77,7 @@ describe('Workspace Schematic', () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('workspace', { ...defaultOptions, strict: false }).toPromise();
|
||||
const { compilerOptions, angularCompilerOptions } =
|
||||
// tslint:disable-next-line: no-any
|
||||
parseJson(tree.readContent('tsconfig.base.json').toString(), JsonParseMode.Loose) as any;
|
||||
parseJson(tree.readContent('tsconfig.json').toString(), JsonParseMode.Loose) as any;
|
||||
expect(compilerOptions.strict).toBeUndefined();
|
||||
expect(angularCompilerOptions).toBeUndefined();
|
||||
});
|
||||
@ -88,7 +86,7 @@ describe('Workspace Schematic', () => {
|
||||
const tree = await schematicRunner.runSchematicAsync('workspace', { ...defaultOptions, strict: true }).toPromise();
|
||||
const { compilerOptions, angularCompilerOptions } =
|
||||
// tslint:disable-next-line: no-any
|
||||
parseJson(tree.readContent('tsconfig.base.json').toString(), JsonParseMode.Loose) as any;
|
||||
parseJson(tree.readContent('tsconfig.json').toString(), JsonParseMode.Loose) as any;
|
||||
expect(compilerOptions.strict).toBe(true);
|
||||
expect(angularCompilerOptions.strictTemplates).toBe(true);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user