diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000000000..9eb1bd5a2a315
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,18 @@
+# EditorConfig is awesome: https://EditorConfig.org
+
+# top-most EditorConfig file
+root = true
+
+# Unix-style newlines with a newline ending every file
+[*]
+end_of_line = lf
+insert_final_newline = true
+
+# 4 space indentation
+[*.{js,ts,jsx,tsx}]
+indent_style = space
+indent_size = 2
+
+[package.json]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/packages/angular/src/generators/application/angular-v14/files/tsconfig.json b/packages/angular/src/generators/application/angular-v14/files/tsconfig.json
deleted file mode 100644
index 595598eddbf3e..0000000000000
--- a/packages/angular/src/generators/application/angular-v14/files/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.app.json"
- }
- ]
-}
diff --git a/packages/angular/src/generators/application/angular-v14/lib/create-files.ts b/packages/angular/src/generators/application/angular-v14/lib/create-files.ts
index 1588633a0c487..d2ec7f3b8cdcb 100644
--- a/packages/angular/src/generators/application/angular-v14/lib/create-files.ts
+++ b/packages/angular/src/generators/application/angular-v14/lib/create-files.ts
@@ -10,10 +10,6 @@ export function createFiles(tree: Tree, options: NormalizedSchema) {
options.appProjectRoot,
{
...options,
- rootTsConfigPath: getRelativePathToRootTsConfig(
- tree,
- options.appProjectRoot
- ),
tpl: '',
}
);
diff --git a/packages/angular/src/generators/application/angular-v14/lib/update-config-files.ts b/packages/angular/src/generators/application/angular-v14/lib/update-config-files.ts
index f7946113e2f05..3476327b3faf2 100644
--- a/packages/angular/src/generators/application/angular-v14/lib/update-config-files.ts
+++ b/packages/angular/src/generators/application/angular-v14/lib/update-config-files.ts
@@ -11,8 +11,16 @@ import {
import { replaceAppNameWithPath } from '@nrwl/workspace/src/utils/cli-config-utils';
import { E2eTestRunner, UnitTestRunner } from '../../../../utils/test-runners';
import type { NormalizedSchema } from './normalized-schema';
+import {
+ createTsConfig,
+ extractTsConfigBase,
+} from '../../../utils/create-ts-config';
+import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
export function updateConfigFiles(host: Tree, options: NormalizedSchema) {
+ if (!options.rootProject) {
+ extractTsConfigBase(host);
+ }
updateTsConfigOptions(host, options);
updateAppAndE2EProjectConfigurations(host, options);
}
@@ -36,14 +44,13 @@ function updateTsConfigOptions(host: Tree, options: NormalizedSchema) {
],
}));
- // tsconfig.json
- updateJson(host, `${options.appProjectRoot}/tsconfig.json`, (json) => ({
- ...json,
- compilerOptions: {
- ...json.compilerOptions,
- target: 'es2020',
- },
- }));
+ createTsConfig(
+ host,
+ options.appProjectRoot,
+ 'app',
+ options,
+ getRelativePathToRootTsConfig(host, options.appProjectRoot)
+ );
}
function updateAppAndE2EProjectConfigurations(
diff --git a/packages/angular/src/generators/application/application.spec.ts b/packages/angular/src/generators/application/application.spec.ts
index 2ce99a96cc095..83a36f95be8a9 100644
--- a/packages/angular/src/generators/application/application.spec.ts
+++ b/packages/angular/src/generators/application/application.spec.ts
@@ -1073,9 +1073,7 @@ describe('app', () => {
expect(appTree.exists('src/app/app.module.ts')).toBe(true);
expect(appTree.exists('src/app/app.component.ts')).toBe(true);
expect(appTree.exists('e2e/cypress.config.ts')).toBe(true);
- expect(readJson(appTree, 'tsconfig.json').extends).toEqual(
- './tsconfig.base.json'
- );
+ expect(readJson(appTree, 'tsconfig.json').extends).toBeUndefined();
const project = readProjectConfiguration(appTree, 'my-app');
expect(project.targets.build.options['outputPath']).toBe('dist/my-app');
});
diff --git a/packages/angular/src/generators/application/application.v14.spec.ts b/packages/angular/src/generators/application/application.v14.spec.ts
index c3336a8564280..7c2194bbb1241 100644
--- a/packages/angular/src/generators/application/application.v14.spec.ts
+++ b/packages/angular/src/generators/application/application.v14.spec.ts
@@ -214,18 +214,6 @@ describe('app', () => {
expect(appTsConfig.extends).toBe('../../tsconfig.base.json');
});
- it('should support a root tsconfig.json instead of tsconfig.base.json', async () => {
- // ARRANGE
- appTree.rename('tsconfig.base.json', 'tsconfig.json');
-
- // ACT
- await generateApp(appTree, 'app');
-
- // ASSERT
- const appTsConfig = readJson(appTree, 'apps/app/tsconfig.json');
- expect(appTsConfig.extends).toBe('../../tsconfig.json');
- });
-
it('should set default project', async () => {
// ACT
await generateApp(appTree);
@@ -339,18 +327,6 @@ describe('app', () => {
const appTsConfig = readJson(appTree, 'apps/my-dir/app/tsconfig.json');
expect(appTsConfig.extends).toBe('../../../tsconfig.base.json');
});
-
- it('should support a root tsconfig.json instead of tsconfig.base.json', async () => {
- // ARRANGE
- appTree.rename('tsconfig.base.json', 'tsconfig.json');
-
- // ACT
- await generateApp(appTree, 'app', { directory: 'myDir' });
-
- // ASSERT
- const appTsConfig = readJson(appTree, 'apps/my-dir/app/tsconfig.json');
- expect(appTsConfig.extends).toBe('../../../tsconfig.json');
- });
});
describe('at the root', () => {
diff --git a/packages/angular/src/generators/application/files/tsconfig.json b/packages/angular/src/generators/application/files/tsconfig.json
deleted file mode 100644
index 595598eddbf3e..0000000000000
--- a/packages/angular/src/generators/application/files/tsconfig.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.app.json"
- }
- ]
-}
diff --git a/packages/angular/src/generators/application/lib/update-config-files.ts b/packages/angular/src/generators/application/lib/update-config-files.ts
index 703db4d0cd5ab..bdcb3261fcc13 100644
--- a/packages/angular/src/generators/application/lib/update-config-files.ts
+++ b/packages/angular/src/generators/application/lib/update-config-files.ts
@@ -11,6 +11,8 @@ import {
import { replaceAppNameWithPath } from '@nrwl/workspace/src/utils/cli-config-utils';
import { E2eTestRunner, UnitTestRunner } from '../../../utils/test-runners';
import type { NormalizedSchema } from './normalized-schema';
+import { createTsConfig } from '../../utils/create-ts-config';
+import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
export function updateConfigFiles(host: Tree, options: NormalizedSchema) {
updateTsConfigOptions(host, options);
@@ -37,14 +39,13 @@ function updateTsConfigOptions(host: Tree, options: NormalizedSchema) {
}));
// tsconfig.json
- updateJson(host, `${options.appProjectRoot}/tsconfig.json`, (json) => ({
- ...json,
- compilerOptions: {
- ...json.compilerOptions,
- target: 'es2022',
- useDefineForClassFields: false, // This will eventually need updated when Angular switch to using TC39 Compliant code
- },
- }));
+ createTsConfig(
+ host,
+ options.appProjectRoot,
+ 'app',
+ options,
+ getRelativePathToRootTsConfig(host, options.appProjectRoot)
+ );
}
function updateAppAndE2EProjectConfigurations(
diff --git a/packages/angular/src/generators/library/files/lib/tsconfig.json__tpl__ b/packages/angular/src/generators/library/files/lib/tsconfig.json__tpl__
deleted file mode 100644
index 6feda9591dc03..0000000000000
--- a/packages/angular/src/generators/library/files/lib/tsconfig.json__tpl__
+++ /dev/null
@@ -1,14 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- }<% if (publishable) { %>,
- {
- "path": "./tsconfig.lib.prod.json"
- }
- <% } %>
- ]
-}
diff --git a/packages/angular/src/generators/library/lib/update-tsconfig.ts b/packages/angular/src/generators/library/lib/update-tsconfig.ts
index ac039886800a7..f9b907cdb61ac 100644
--- a/packages/angular/src/generators/library/lib/update-tsconfig.ts
+++ b/packages/angular/src/generators/library/lib/update-tsconfig.ts
@@ -1,7 +1,14 @@
import type { Tree } from '@nrwl/devkit';
import { joinPathFragments, updateJson } from '@nrwl/devkit';
-import { getRootTsConfigPathInTree } from '@nrwl/workspace/src/utilities/typescript';
+import {
+ getRelativePathToRootTsConfig,
+ getRootTsConfigPathInTree,
+} from '@nrwl/workspace/src/utilities/typescript';
import { NormalizedSchema } from './normalized-schema';
+import {
+ createTsConfig,
+ extractTsConfigBase,
+} from '../../utils/create-ts-config';
function updateRootConfig(
host: Tree,
@@ -44,14 +51,13 @@ function updateProjectConfig(
});
// tsconfig.json
- updateJson(host, `${options.projectRoot}/tsconfig.json`, (json) => ({
- ...json,
- compilerOptions: {
- ...json.compilerOptions,
- target: 'es2022',
- useDefineForClassFields: false,
- },
- }));
+ createTsConfig(
+ host,
+ options.projectRoot,
+ 'lib',
+ options,
+ getRelativePathToRootTsConfig(host, options.projectRoot)
+ );
}
function updateProjectIvyConfig(
@@ -75,6 +81,7 @@ export function updateTsConfig(
host: Tree,
options: NormalizedSchema['libraryOptions']
) {
+ extractTsConfigBase(host);
updateRootConfig(host, options);
updateProjectConfig(host, options);
updateProjectIvyConfig(host, options);
diff --git a/packages/angular/src/generators/library/library.spec.ts b/packages/angular/src/generators/library/library.spec.ts
index 6f2b5f0a68b5a..b0a39ad74634f 100644
--- a/packages/angular/src/generators/library/library.spec.ts
+++ b/packages/angular/src/generators/library/library.spec.ts
@@ -313,16 +313,13 @@ describe('lib', () => {
});
});
- it('should support a root tsconfig.json instead of tsconfig.base.json', async () => {
- // ARRANGE
+ it('should create tsconfig.base.json when it is missing', async () => {
tree.rename('tsconfig.base.json', 'tsconfig.json');
- // ACT
await runLibraryGeneratorWithOpts();
- // ASSERT
const appTsConfig = readJson(tree, 'libs/my-lib/tsconfig.json');
- expect(appTsConfig.extends).toBe('../../tsconfig.json');
+ expect(appTsConfig.extends).toBe('../../tsconfig.base.json');
});
it('should check for existence of spec files before deleting them', async () => {
@@ -663,56 +660,6 @@ describe('lib', () => {
tsconfigJson.compilerOptions.paths['my-dir-my-lib/*']
).toBeUndefined();
});
-
- it('should create a local tsconfig.json', async () => {
- // ACT
- await runLibraryGeneratorWithOpts({ directory: 'myDir' });
-
- // ASSERT
- const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json');
-
- expect(tsconfigJson).toEqual({
- extends: '../../../tsconfig.base.json',
- angularCompilerOptions: {
- enableI18nLegacyMessageIdFormat: false,
- strictInjectionParameters: true,
- strictInputAccessModifiers: true,
- strictTemplates: true,
- },
- compilerOptions: {
- forceConsistentCasingInFileNames: true,
- noFallthroughCasesInSwitch: true,
- noPropertyAccessFromIndexSignature: true,
- noImplicitOverride: true,
- noImplicitReturns: true,
- strict: true,
- target: 'es2022',
- useDefineForClassFields: false,
- },
- files: [],
- include: [],
- references: [
- {
- path: './tsconfig.lib.json',
- },
- {
- path: './tsconfig.spec.json',
- },
- ],
- });
- });
-
- it('should support a root tsconfig.json instead of tsconfig.base.json', async () => {
- // ARRANGE
- tree.rename('tsconfig.base.json', 'tsconfig.json');
-
- // ACT
- await runLibraryGeneratorWithOpts({ directory: 'myDir' });
-
- // ASSERT
- const appTsConfig = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json');
- expect(appTsConfig.extends).toBe('../../../tsconfig.json');
- });
});
describe('at the root', () => {
diff --git a/packages/angular/src/generators/utils/create-ts-config.ts b/packages/angular/src/generators/utils/create-ts-config.ts
new file mode 100644
index 0000000000000..1fc2d88cbb9d6
--- /dev/null
+++ b/packages/angular/src/generators/utils/create-ts-config.ts
@@ -0,0 +1,42 @@
+import { Tree } from 'nx/src/generators/tree';
+import { tsConfigBaseOptions } from '@nrwl/workspace/src/utils/create-ts-config';
+import { writeJson } from 'nx/src/generators/utils/json';
+export { extractTsConfigBase } from '@nrwl/workspace/src/utils/create-ts-config';
+
+export function createTsConfig(
+ host: Tree,
+ projectRoot: string,
+ type: 'app' | 'lib',
+ options: {
+ strict?: boolean;
+ style?: string;
+ bundler?: string;
+ rootProject?: boolean;
+ },
+ relativePathToRootTsConfig: string
+) {
+ const json = {
+ compilerOptions: {
+ target: 'es2022',
+ useDefineForClassFields: false,
+ },
+ files: [],
+ include: [],
+ references: [
+ {
+ path: type === 'app' ? './tsconfig.app.json' : './tsconfig.lib.json',
+ },
+ ],
+ } as any;
+
+ // inline tsconfig.base.json into the project
+ if (options.rootProject) {
+ json.compileOnSave = false;
+ json.compilerOptions = { ...tsConfigBaseOptions, ...json.compilerOptions };
+ json.exclude = ['node_modules', 'tmp'];
+ } else {
+ json.extends = relativePathToRootTsConfig;
+ }
+
+ writeJson(host, `${projectRoot}/tsconfig.json`, json);
+}
diff --git a/packages/react/src/generators/application/application.spec.ts b/packages/react/src/generators/application/application.spec.ts
index 34a8f68f8a47e..6709445f40310 100644
--- a/packages/react/src/generators/application/application.spec.ts
+++ b/packages/react/src/generators/application/application.spec.ts
@@ -104,17 +104,7 @@ describe('app', () => {
path: './tsconfig.spec.json',
},
]);
- expect(tsconfig.compilerOptions.forceConsistentCasingInFileNames).toEqual(
- true
- );
expect(tsconfig.compilerOptions.strict).toEqual(true);
- expect(tsconfig.compilerOptions.noImplicitOverride).toEqual(true);
- expect(
- tsconfig.compilerOptions.noPropertyAccessFromIndexSignature
- ).toEqual(true);
- expect(tsconfig.compilerOptions.noImplicitReturns).toEqual(true);
- expect(tsconfig.compilerOptions.noFallthroughCasesInSwitch).toEqual(true);
-
const tsconfigApp = readJson(appTree, 'apps/my-app/tsconfig.app.json');
expect(tsconfigApp.compilerOptions.outDir).toEqual('../../dist/out-tsc');
expect(tsconfigApp.extends).toEqual('./tsconfig.json');
@@ -165,15 +155,6 @@ describe('app', () => {
const tsConfig = readJson(appTree, 'apps/my-app/tsconfig.json');
expect(tsConfig.extends).toEqual('../../tsconfig.base.json');
});
-
- it('should extend from root tsconfig.json when no tsconfig.base.json', async () => {
- appTree.rename('tsconfig.base.json', 'tsconfig.json');
-
- await applicationGenerator(appTree, schema);
-
- const tsConfig = readJson(appTree, 'apps/my-app/tsconfig.json');
- expect(tsConfig.extends).toEqual('../../tsconfig.json');
- });
});
describe('nested', () => {
@@ -902,15 +883,7 @@ describe('app', () => {
expect(
tsconfigJson.compilerOptions.forceConsistentCasingInFileNames
).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.strict).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.noImplicitOverride).not.toBeDefined();
- expect(
- tsconfigJson.compilerOptions.noPropertyAccessFromIndexSignature
- ).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.noImplicitReturns).not.toBeDefined();
- expect(
- tsconfigJson.compilerOptions.noFallthroughCasesInSwitch
- ).not.toBeDefined();
+ expect(tsconfigJson.compilerOptions.strict).toEqual(false);
});
});
@@ -931,24 +904,6 @@ describe('app', () => {
describe('--root-project', () => {
it('should create files at the root', async () => {
- await applicationGenerator(appTree, {
- ...schema,
- rootProject: true,
- bundler: 'webpack',
- });
- expect(appTree.read('/src/main.tsx')).toBeDefined();
- expect(appTree.read('/e2e/cypress.config.ts')).toBeDefined();
- expect(readJson(appTree, '/tsconfig.json').extends).toEqual(
- './tsconfig.base.json'
- );
- expect(
- readJson(appTree, '/workspace.json').projects['my-app'].architect[
- 'build'
- ].options['outputPath']
- ).toEqual('dist/my-app');
- });
-
- it('should create files at the root if bundler is vite', async () => {
await applicationGenerator(appTree, {
...schema,
name: 'my-app2',
@@ -957,9 +912,11 @@ describe('app', () => {
});
expect(appTree.read('/src/main.tsx')).toBeDefined();
expect(appTree.read('/e2e/cypress.config.ts')).toBeDefined();
- expect(readJson(appTree, '/tsconfig.json').extends).toEqual(
- './tsconfig.base.json'
- );
+
+ const rootTsConfig = readJson(appTree, '/tsconfig.json');
+ expect(rootTsConfig.extends).toBeUndefined();
+ expect(rootTsConfig.compilerOptions.sourceMap).toBe(true);
+
expect(
readJson(appTree, '/workspace.json').projects['my-app2'].architect[
'build'
diff --git a/packages/react/src/generators/application/application.ts b/packages/react/src/generators/application/application.ts
index b3ca1a78c5874..2001e69cf72a5 100644
--- a/packages/react/src/generators/application/application.ts
+++ b/packages/react/src/generators/application/application.ts
@@ -32,6 +32,7 @@ import {
swcLoaderVersion,
} from '../../utils/versions';
import { installCommonDependencies } from './lib/install-common-dependencies';
+import { extractTsConfigBase } from '../../utils/create-ts-config';
async function addLinting(host: Tree, options: NormalizedSchema) {
const tasks: GeneratorCallback[] = [];
@@ -90,6 +91,10 @@ export async function applicationGenerator(host: Tree, schema: Schema) {
tasks.push(initTask);
+ if (!options.rootProject) {
+ extractTsConfigBase(host);
+ }
+
createApplicationFiles(host, options);
addProject(host, options);
diff --git a/packages/react/src/generators/application/files/common-vite/tsconfig.json__tmpl__ b/packages/react/src/generators/application/files/common-vite/tsconfig.json__tmpl__
deleted file mode 100644
index e1b7347c34ec3..0000000000000
--- a/packages/react/src/generators/application/files/common-vite/tsconfig.json__tmpl__
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "compilerOptions": {
- "jsx": "react-jsx",
- <% if (style === '@emotion/styled') { %>"jsxImportSource": "@emotion/react",<% } %>
- "allowJs": false,
- "esModuleInterop": false,
- "allowSyntheticDefaultImports": true,
- "forceConsistentCasingInFileNames": true,
- "isolatedModules": true,
- "lib": ["DOM", "DOM.Iterable", "ESNext"],
- "module": "ESNext",
- "moduleResolution": "Node",
- "noEmit": true,
- "resolveJsonModule": true,
- "skipLibCheck": true,
- "strict": true,
- "target": "ESNext",
- "types": ["vite/client"],
- "useDefineForClassFields": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.app.json"
- }
- ]
-}
diff --git a/packages/react/src/generators/application/files/common/tsconfig.json__tmpl__ b/packages/react/src/generators/application/files/common/tsconfig.json__tmpl__
deleted file mode 100644
index fc23421ea4caf..0000000000000
--- a/packages/react/src/generators/application/files/common/tsconfig.json__tmpl__
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "compilerOptions": {
- "jsx": "react-jsx",
- <% if (style === '@emotion/styled') { %>"jsxImportSource": "@emotion/react",<% } %>
- "allowJs": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.app.json"
- }
- ]
-}
diff --git a/packages/react/src/generators/application/lib/create-application-files.ts b/packages/react/src/generators/application/lib/create-application-files.ts
index c8312b5c59e2a..187ecc047ec07 100644
--- a/packages/react/src/generators/application/lib/create-application-files.ts
+++ b/packages/react/src/generators/application/lib/create-application-files.ts
@@ -10,28 +10,7 @@ import {
} from '@nrwl/devkit';
import { join } from 'path';
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
-
-function updateTsConfig(host: Tree, options: NormalizedSchema) {
- updateJson(
- host,
- joinPathFragments(options.appProjectRoot, 'tsconfig.json'),
- (json) => {
- if (options.strict) {
- json.compilerOptions = {
- ...json.compilerOptions,
- forceConsistentCasingInFileNames: true,
- strict: true,
- noImplicitOverride: true,
- noPropertyAccessFromIndexSignature: true,
- noImplicitReturns: true,
- noFallthroughCasesInSwitch: true,
- };
- }
-
- return json;
- }
- );
-}
+import { createTsConfig } from '../../../utils/create-ts-config';
export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
let styleSolutionSpecificAppFiles: string;
@@ -47,15 +26,15 @@ export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
styleSolutionSpecificAppFiles = '../files/css-module';
}
+ const relativePathToRootTsConfig = getRelativePathToRootTsConfig(
+ host,
+ options.appProjectRoot
+ );
const templateVariables = {
...names(options.name),
...options,
tmpl: '',
offsetFromRoot: offsetFromRoot(options.appProjectRoot),
- rootTsConfigPath: getRelativePathToRootTsConfig(
- host,
- options.appProjectRoot
- ),
};
generateFiles(
@@ -99,5 +78,11 @@ export function createApplicationFiles(host: Tree, options: NormalizedSchema) {
toJS(host);
}
- updateTsConfig(host, options);
+ createTsConfig(
+ host,
+ options.appProjectRoot,
+ 'app',
+ options,
+ relativePathToRootTsConfig
+ );
}
diff --git a/packages/react/src/generators/library/files/common/tsconfig.json__tmpl__ b/packages/react/src/generators/library/files/common/tsconfig.json__tmpl__
deleted file mode 100644
index c5c5460225c53..0000000000000
--- a/packages/react/src/generators/library/files/common/tsconfig.json__tmpl__
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "extends": "<%= rootTsConfigPath %>",
- "compilerOptions": {
- "jsx": "react-jsx",
- <% if (style === '@emotion/styled') { %>"jsxImportSource": "@emotion/react",<% } %>
- "allowJs": true,
- "esModuleInterop": true,
- "allowSyntheticDefaultImports": true
- },
- "files": [],
- "include": [],
- "references": [
- {
- "path": "./tsconfig.lib.json"
- }
- ]
-}
diff --git a/packages/react/src/generators/library/lib/create-files.ts b/packages/react/src/generators/library/lib/create-files.ts
index b9f4830d201c8..8dc320d435052 100644
--- a/packages/react/src/generators/library/lib/create-files.ts
+++ b/packages/react/src/generators/library/lib/create-files.ts
@@ -10,14 +10,18 @@ import {
import { getRelativePathToRootTsConfig } from '@nrwl/workspace/src/utilities/typescript';
import { NormalizedSchema } from '../schema';
+import { createTsConfig } from '../../../utils/create-ts-config';
export function createFiles(host: Tree, options: NormalizedSchema) {
+ const relativePathToRootTsConfig = getRelativePathToRootTsConfig(
+ host,
+ options.projectRoot
+ );
const substitutions = {
...options,
...names(options.name),
tmpl: '',
offsetFromRoot: offsetFromRoot(options.projectRoot),
- rootTsConfigPath: getRelativePathToRootTsConfig(host, options.projectRoot),
};
generateFiles(
@@ -48,27 +52,11 @@ export function createFiles(host: Tree, options: NormalizedSchema) {
toJS(host);
}
- updateTsConfig(host, options);
-}
-
-function updateTsConfig(tree: Tree, options: NormalizedSchema) {
- updateJson(
- tree,
- joinPathFragments(options.projectRoot, 'tsconfig.json'),
- (json) => {
- if (options.strict) {
- json.compilerOptions = {
- ...json.compilerOptions,
- forceConsistentCasingInFileNames: true,
- strict: true,
- noImplicitOverride: true,
- noPropertyAccessFromIndexSignature: true,
- noImplicitReturns: true,
- noFallthroughCasesInSwitch: true,
- };
- }
-
- return json;
- }
+ createTsConfig(
+ host,
+ options.projectRoot,
+ 'lib',
+ options,
+ relativePathToRootTsConfig
);
}
diff --git a/packages/react/src/generators/library/library.spec.ts b/packages/react/src/generators/library/library.spec.ts
index 9e50cc710f01d..2bda3d4ad4948 100644
--- a/packages/react/src/generators/library/library.spec.ts
+++ b/packages/react/src/generators/library/library.spec.ts
@@ -96,12 +96,12 @@ describe('lib', () => {
]);
});
- it('should update root tsconfig.json when no tsconfig.base.json', async () => {
+ it('should create tsconfig.base.json out of tsconfig.json', async () => {
tree.rename('tsconfig.base.json', 'tsconfig.json');
await libraryGenerator(tree, defaultSchema);
- const tsconfigJson = readJson(tree, '/tsconfig.json');
+ const tsconfigJson = readJson(tree, '/tsconfig.base.json');
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
'libs/my-lib/src/index.ts',
]);
@@ -133,27 +133,7 @@ describe('lib', () => {
path: './tsconfig.spec.json',
},
]);
- expect(
- tsconfigJson.compilerOptions.forceConsistentCasingInFileNames
- ).toEqual(true);
expect(tsconfigJson.compilerOptions.strict).toEqual(true);
- expect(tsconfigJson.compilerOptions.noImplicitOverride).toEqual(true);
- expect(
- tsconfigJson.compilerOptions.noPropertyAccessFromIndexSignature
- ).toEqual(true);
- expect(tsconfigJson.compilerOptions.noImplicitReturns).toEqual(true);
- expect(tsconfigJson.compilerOptions.noFallthroughCasesInSwitch).toEqual(
- true
- );
- });
-
- it('should extend from root tsconfig.json when no tsconfig.base.json', async () => {
- tree.rename('tsconfig.base.json', 'tsconfig.json');
-
- await libraryGenerator(tree, defaultSchema);
-
- const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json');
- expect(tsconfigJson.extends).toBe('../../tsconfig.json');
});
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
@@ -325,20 +305,6 @@ describe('lib', () => {
).toBeUndefined();
});
- it('should update root tsconfig.json when no tsconfig.base.json', async () => {
- tree.rename('tsconfig.base.json', 'tsconfig.json');
-
- await libraryGenerator(tree, { ...defaultSchema, directory: 'myDir' });
-
- const tsconfigJson = readJson(tree, '/tsconfig.json');
- expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
- ['libs/my-dir/my-lib/src/index.ts']
- );
- expect(
- tsconfigJson.compilerOptions.paths['my-dir-my-lib/*']
- ).toBeUndefined();
- });
-
it('should create a local tsconfig.json', async () => {
await libraryGenerator(tree, { ...defaultSchema, directory: 'myDir' });
@@ -353,15 +319,6 @@ describe('lib', () => {
},
]);
});
-
- it('should extend from root tsconfig.json when no tsconfig.base.json', async () => {
- tree.rename('tsconfig.base.json', 'tsconfig.json');
-
- await libraryGenerator(tree, { ...defaultSchema, directory: 'myDir' });
-
- const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json');
- expect(tsconfigJson.extends).toBe('../../../tsconfig.json');
- });
});
describe('--style scss', () => {
@@ -704,18 +661,7 @@ describe('lib', () => {
});
const tsconfigJson = readJson(tree, '/libs/my-lib/tsconfig.json');
- expect(
- tsconfigJson.compilerOptions.forceConsistentCasingInFileNames
- ).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.strict).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.noImplicitOverride).not.toBeDefined();
- expect(
- tsconfigJson.compilerOptions.noPropertyAccessFromIndexSignature
- ).not.toBeDefined();
- expect(tsconfigJson.compilerOptions.noImplicitReturns).not.toBeDefined();
- expect(
- tsconfigJson.compilerOptions.noFallthroughCasesInSwitch
- ).not.toBeDefined();
+ expect(tsconfigJson.compilerOptions.strict).toEqual(false);
});
});
diff --git a/packages/react/src/generators/library/library.ts b/packages/react/src/generators/library/library.ts
index 2cd8444342539..7fbc2c39ee1a2 100644
--- a/packages/react/src/generators/library/library.ts
+++ b/packages/react/src/generators/library/library.ts
@@ -21,6 +21,7 @@ import { addLinting } from './lib/add-linting';
import { updateAppRoutes } from './lib/update-app-routes';
import { createFiles } from './lib/create-files';
import { updateBaseTsConfig } from './lib/update-base-tsconfig';
+import { extractTsConfigBase } from '../../utils/create-ts-config';
import { installCommonDependencies } from './lib/install-common-dependencies';
export async function libraryGenerator(host: Tree, schema: Schema) {
@@ -36,6 +37,8 @@ export async function libraryGenerator(host: Tree, schema: Schema) {
options.style = 'none';
}
+ extractTsConfigBase(host);
+
const initTask = await initGenerator(host, {
...options,
e2eTestRunner: 'none',
diff --git a/packages/react/src/utils/create-ts-config.ts b/packages/react/src/utils/create-ts-config.ts
new file mode 100644
index 0000000000000..363ddaa85ced8
--- /dev/null
+++ b/packages/react/src/utils/create-ts-config.ts
@@ -0,0 +1,67 @@
+import { Tree } from 'nx/src/generators/tree';
+import * as shared from '@nrwl/workspace/src/utils/create-ts-config';
+import { writeJson } from 'nx/src/generators/utils/json';
+
+export function createTsConfig(
+ host: Tree,
+ projectRoot: string,
+ type: 'app' | 'lib',
+ options: {
+ strict?: boolean;
+ style?: string;
+ bundler?: string;
+ rootProject?: boolean;
+ },
+ relativePathToRootTsConfig: string
+) {
+ const json = {
+ compilerOptions: {
+ jsx: 'react-jsx',
+ allowJs: false,
+ esModuleInterop: false,
+ allowSyntheticDefaultImports: true,
+ strict: options.strict,
+ },
+ files: [],
+ include: [],
+ references: [
+ {
+ path: type === 'app' ? './tsconfig.app.json' : './tsconfig.lib.json',
+ },
+ ],
+ } as any;
+
+ if (options.style === '@emotion/styled') {
+ json.compilerOptions.jsxImportSource = '@emotion/react';
+ }
+
+ if (options.bundler === 'vite') {
+ json.compilerOptions.types = ['vite/client'];
+ }
+
+ // inline tsconfig.base.json into the project
+ if (options.rootProject) {
+ json.compileOnSave = false;
+ json.compilerOptions = {
+ ...shared.tsConfigBaseOptions,
+ ...json.compilerOptions,
+ };
+ json.exclude = ['node_modules', 'tmp'];
+ } else {
+ json.extends = relativePathToRootTsConfig;
+ }
+
+ writeJson(host, `${projectRoot}/tsconfig.json`, json);
+}
+
+export function extractTsConfigBase(host: Tree) {
+ shared.extractTsConfigBase(host);
+
+ if (host.exists('vite.config.ts')) {
+ const vite = host.read('vite.config.ts').toString();
+ host.write(
+ 'vite.config.ts',
+ vite.replace(`projects: []`, `projects: ['tsconfig.base.json']`)
+ );
+ }
+}
diff --git a/packages/vite/src/utils/generator-utils.ts b/packages/vite/src/utils/generator-utils.ts
index 0596c4ba6c70d..4b116446cacdb 100644
--- a/packages/vite/src/utils/generator-utils.ts
+++ b/packages/vite/src/utils/generator-utils.ts
@@ -412,6 +412,9 @@ export function writeViteConfig(tree: Tree, options: Schema) {
host: 'localhost',
},`;
+ const projectsTsConfig = tree.exists('tsconfig.base.json')
+ ? "'tsconfig.base.json'"
+ : '';
switch (options.uiFramework) {
case 'react':
viteConfigContent = `
@@ -432,7 +435,7 @@ ${options.includeVitest ? '/// ' : ''}
react(),
tsconfigPaths({
root: '${offsetFromRoot(projectConfig.root)}',
- projects: ['tsconfig.base.json'],
+ projects: [${projectsTsConfig}],
}),
],
${buildOption}
@@ -457,7 +460,7 @@ ${options.includeVitest ? '/// ' : ''}
${options.includeLib ? dtsPlugin : ''}
tsconfigPaths({
root: '${offsetFromRoot(projectConfig.root)}',
- projects: ['tsconfig.base.json'],
+ projects: [${projectsTsConfig}],
}),
],
${buildOption}
diff --git a/packages/workspace/src/generators/new/files-root-app/tsconfig.base.json b/packages/workspace/src/generators/new/files-root-app/tsconfig.base.json
deleted file mode 100644
index 11253ac5c2b7b..0000000000000
--- a/packages/workspace/src/generators/new/files-root-app/tsconfig.base.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
- "compileOnSave": false,
- "compilerOptions": {
- "rootDir": ".",
- "sourceMap": true,
- "declaration": false,
- "moduleResolution": "node",
- "emitDecoratorMetadata": true,
- "experimentalDecorators": true,
- "importHelpers": true,
- "target": "es2015",
- "module": "esnext",
- "lib": ["es2017", "dom"],
- "skipLibCheck": true,
- "skipDefaultLibCheck": true,
- "baseUrl": ".",
- "paths": {}
- },
- "exclude": ["node_modules", "tmp"]
-}
diff --git a/packages/workspace/src/utils/create-ts-config.ts b/packages/workspace/src/utils/create-ts-config.ts
new file mode 100644
index 0000000000000..6bb11be4781b8
--- /dev/null
+++ b/packages/workspace/src/utils/create-ts-config.ts
@@ -0,0 +1,48 @@
+import { Tree } from 'nx/src/generators/tree';
+import { readJson, updateJson, writeJson } from 'nx/src/generators/utils/json';
+
+export const tsConfigBaseOptions = {
+ rootDir: '.',
+ sourceMap: true,
+ declaration: false,
+ moduleResolution: 'node',
+ emitDecoratorMetadata: true,
+ experimentalDecorators: true,
+ importHelpers: true,
+ target: 'es2015',
+ module: 'esnext',
+ lib: ['es2017', 'dom'],
+ skipLibCheck: true,
+ skipDefaultLibCheck: true,
+ baseUrl: '.',
+};
+
+export function extractTsConfigBase(host: Tree) {
+ if (host.exists('tsconfig.base.json')) return;
+
+ const tsconfig = readJson(host, 'tsconfig.json');
+ const baseCompilerOptions = {} as any;
+ for (let compilerOption of Object.keys(tsConfigBaseOptions)) {
+ baseCompilerOptions[compilerOption] =
+ tsconfig.compilerOptions[compilerOption];
+ delete tsconfig.compilerOptions[compilerOption];
+ }
+ writeJson(host, 'tsconfig.base.json', {
+ compileOnSave: false,
+ compilerOptions: baseCompilerOptions,
+ exclude: tsconfig.exclude,
+ });
+ tsconfig.extends = './tsconfig.base.json';
+ delete tsconfig.compileOnSave;
+ delete tsconfig.exclude;
+
+ writeJson(host, 'tsconfig.json', tsconfig);
+
+ // special case for updating e2e tests.
+ if (host.exists('e2e/tsconfig.json')) {
+ updateJson(host, 'e2e/tsconfig.json', (json) => {
+ json.extends = '../tsconfig.base.json';
+ return json;
+ });
+ }
+}