feat(core): split nx config to project files (#5880)

This commit is contained in:
Craigory V Coppola 2021-06-22 19:30:38 -05:00 committed by GitHub
parent a7edd3cc70
commit f1911a71f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
170 changed files with 1874 additions and 288 deletions

View File

@ -128,6 +128,14 @@ Type: `boolean`
Skip creating spec files.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -150,6 +150,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -98,6 +98,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -66,6 +66,14 @@ Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -72,6 +72,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -108,6 +108,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style)
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -106,6 +106,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -138,6 +138,14 @@ Type: `boolean`
Do not update tsconfig.base.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -473,7 +473,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`: [_Tree_](../../angular/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../angular/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../angular/nx-devkit/index#nxjsonprojectconfiguration)): _void_
**addProjectConfiguration**(`host`: [_Tree_](../../angular/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../angular/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../angular/nx-devkit/index#nxjsonprojectconfiguration), `standalone?`: _boolean_): _void_
Adds project configuration to the Nx workspace.
@ -482,11 +482,12 @@ both files.
#### Parameters
| Name | Type | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../angular/nx-devkit/index#tree) | the file system tree |
| `projectName` | _string_ | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../angular/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../angular/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
| Name | Type | Default value | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../angular/nx-devkit/index#tree) | - | the file system tree |
| `projectName` | _string_ | - | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../angular/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../angular/nx-devkit/index#nxjsonprojectconfiguration) | - | project configuration |
| `standalone` | _boolean_ | false | - |
**Returns:** _void_

View File

@ -78,6 +78,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Alias(es): t

View File

@ -150,6 +150,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style).
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -158,6 +158,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -77,3 +77,11 @@ The tool to use for running lint checks.
Type: `string`
Project name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -60,6 +60,14 @@ Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### uiFramework
Type: `string`

View File

@ -53,3 +53,11 @@ The tool to use for running lint checks.
Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -76,6 +76,14 @@ Type: `boolean`
Skip formatting files
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Default: `css`

View File

@ -130,6 +130,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -128,6 +128,14 @@ Type: `boolean`
Skip creating spec files.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -150,6 +150,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -98,6 +98,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -66,6 +66,14 @@ Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -72,6 +72,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -108,6 +108,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style)
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -106,6 +106,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -138,6 +138,14 @@ Type: `boolean`
Do not update tsconfig.base.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -473,7 +473,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`: [_Tree_](../../node/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../node/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../node/nx-devkit/index#nxjsonprojectconfiguration)): _void_
**addProjectConfiguration**(`host`: [_Tree_](../../node/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../node/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../node/nx-devkit/index#nxjsonprojectconfiguration), `standalone?`: _boolean_): _void_
Adds project configuration to the Nx workspace.
@ -482,11 +482,12 @@ both files.
#### Parameters
| Name | Type | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../node/nx-devkit/index#tree) | the file system tree |
| `projectName` | _string_ | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../node/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../node/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
| Name | Type | Default value | Description |
| :--------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------ | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../node/nx-devkit/index#tree) | - | the file system tree |
| `projectName` | _string_ | - | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../node/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../node/nx-devkit/index#nxjsonprojectconfiguration) | - | project configuration |
| `standalone` | _boolean_ | false | - |
**Returns:** _void_

View File

@ -78,6 +78,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Alias(es): t

View File

@ -150,6 +150,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style).
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -158,6 +158,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -77,3 +77,11 @@ The tool to use for running lint checks.
Type: `string`
Project name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -60,6 +60,14 @@ Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### uiFramework
Type: `string`

View File

@ -53,3 +53,11 @@ The tool to use for running lint checks.
Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -76,6 +76,14 @@ Type: `boolean`
Skip formatting files
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Default: `css`

View File

@ -130,6 +130,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -128,6 +128,14 @@ Type: `boolean`
Skip creating spec files.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -150,6 +150,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -98,6 +98,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -66,6 +66,14 @@ Type: `boolean`
Whether or not to configure the ESLint "parserOptions.project" option. We do not do this by default for lint performance reasons.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -72,6 +72,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -108,6 +108,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style)
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Alias(es): s

View File

@ -106,6 +106,14 @@ Type: `boolean`
Do not add dependencies to package.json.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Type: `string`

View File

@ -138,6 +138,14 @@ Type: `boolean`
Do not update tsconfig.base.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -473,7 +473,7 @@ Callback to install dependencies only if necessary. undefined is returned if cha
### addProjectConfiguration
**addProjectConfiguration**(`host`: [_Tree_](../../react/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../react/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../react/nx-devkit/index#nxjsonprojectconfiguration)): _void_
**addProjectConfiguration**(`host`: [_Tree_](../../react/nx-devkit/index#tree), `projectName`: _string_, `projectConfiguration`: [_ProjectConfiguration_](../../react/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../react/nx-devkit/index#nxjsonprojectconfiguration), `standalone?`: _boolean_): _void_
Adds project configuration to the Nx workspace.
@ -482,11 +482,12 @@ both files.
#### Parameters
| Name | Type | Description |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../react/nx-devkit/index#tree) | the file system tree |
| `projectName` | _string_ | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../react/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../react/nx-devkit/index#nxjsonprojectconfiguration) | project configuration |
| Name | Type | Default value | Description |
| :--------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------ | :---------------------------------------------------------------------- |
| `host` | [_Tree_](../../react/nx-devkit/index#tree) | - | the file system tree |
| `projectName` | _string_ | - | unique name. Often directories are part of the name (e.g., mydir-mylib) |
| `projectConfiguration` | [_ProjectConfiguration_](../../react/nx-devkit/index#projectconfiguration) & [_NxJsonProjectConfiguration_](../../react/nx-devkit/index#nxjsonprojectconfiguration) | - | project configuration |
| `standalone` | _boolean_ | false | - |
**Returns:** _void_

View File

@ -78,6 +78,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### tags
Alias(es): t

View File

@ -150,6 +150,14 @@ Type: `boolean`
Skip updating workspace.json with default options based on values provided to this app (e.g. babel, style).
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -158,6 +158,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `true`

View File

@ -77,3 +77,11 @@ The tool to use for running lint checks.
Type: `string`
Project name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -60,6 +60,14 @@ Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### uiFramework
Type: `string`

View File

@ -53,3 +53,11 @@ The tool to use for running lint checks.
Type: `string`
Library or application name
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json

View File

@ -76,6 +76,14 @@ Type: `boolean`
Skip formatting files
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### style
Default: `css`

View File

@ -130,6 +130,14 @@ Type: `boolean`
Do not update tsconfig.json for development experience.
### standaloneConfig
Default: `false`
Type: `boolean`
Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json
### strict
Default: `false`

View File

@ -56,6 +56,24 @@ describe('Node Applications', () => {
expect(result).toContain('Hello World!');
}, 300000);
// TODO: This test fails in CI, but succeeds locally. It should be re-enabled once the reasoning is understood.
xit('should be able to generate an empty application with standalone configuration', async () => {
const nodeapp = uniq('nodeapp');
runCLI(
`generate @nrwl/node:app ${nodeapp} --linter=eslint --standaloneConfig`
);
updateFile(`apps/${nodeapp}/src/main.ts`, `console.log('Hello World!');`);
await runCLIAsync(`build ${nodeapp}`);
checkFilesExist(`dist/apps/${nodeapp}/main.js`);
const result = execSync(`node dist/apps/${nodeapp}/main.js`, {
cwd: tmpProjPath(),
}).toString();
expect(result).toContain('Hello World!');
}, 300000);
xit('should be able to generate an express application', async () => {
const nodeapp = uniq('nodeapp');
const port = 3334;

View File

@ -1,4 +1,5 @@
import { detectPackageManager } from '@nrwl/tao/src/shared/package-manager';
import { inlineProjectConfigurations } from '@nrwl/tao/src/shared/workspace';
import { ChildProcess, exec, execSync } from 'child_process';
import {
copySync,
@ -19,6 +20,7 @@ const kill = require('kill-port');
const isWindows = require('is-windows');
import { check as portCheck } from 'tcp-port-used';
import { parseJson } from '@nrwl/devkit';
import chalk = require('chalk');
import treeKill = require('tree-kill');
import { promisify } from 'util';
@ -36,7 +38,7 @@ interface RunCmdOpts {
}
export function currentCli() {
return process.env.SELECTED_CLI ?? 'nx';
return process.env.SELECTED_CLI || 'nx';
}
export function isNightlyRun() {
@ -443,7 +445,10 @@ function setMaxWorkers() {
const workspace = readJson(workspaceFile);
Object.keys(workspace.projects).forEach((appName) => {
const project = workspace.projects[appName];
let project = workspace.projects[appName];
if (typeof project === 'string') {
project = readJson(path.join(project, 'project.json'));
}
const { build } = project.targets ?? project.architect;
if (!build) {

View File

@ -38,5 +38,5 @@ describe('file-server', () => {
} catch {
expect('process running').toBeFalsy();
}
}, 300000);
}, 150000);
});

View File

@ -21,6 +21,8 @@ describe('Web Components Applications', () => {
const appName = uniq('app');
runCLI(`generate @nrwl/web:app ${appName} --no-interactive`);
checkFilesDoNotExist(`apps/${appName}/project.json`);
const lintResults = runCLI(`lint ${appName}`);
expect(lintResults).toContain('All files pass linting.');
@ -60,6 +62,18 @@ describe('Web Components Applications', () => {
}
}, 500000);
it('should be able to generate a web app with standaloneConfig', async () => {
const appName = uniq('app');
runCLI(
`generate @nrwl/web:app ${appName} --no-interactive --standalone-config`
);
checkFilesExist(`apps/${appName}/project.json`);
const lintResults = runCLI(`lint ${appName}`);
expect(lintResults).toContain('All files pass linting.');
}, 120000);
it('should remove previous output before building', async () => {
const appName = uniq('app');
const libName = uniq('lib');

View File

@ -9,6 +9,7 @@ import {
installPackagesTask,
} from '@nrwl/devkit';
import { wrapAngularDevkitSchematic } from '@nrwl/devkit/ngcli-adapter';
import { convertToNxProjectGenerator } from '@nrwl/workspace';
import { UnitTestRunner } from '../../utils/test-runners';
import init from '../init/init';
@ -99,6 +100,10 @@ export async function applicationGenerator(
setApplicationStrictDefault(host, false);
}
if (options.standaloneConfig) {
await convertToNxProjectGenerator(host, {project: options.name, all: false});
}
if (!options.skipFormat) {
await formatFiles(host);
}

View File

@ -19,4 +19,5 @@ export interface Schema {
e2eTestRunner: E2eTestRunner;
backendProject?: string;
strict?: boolean;
standaloneConfig?: boolean;
}

View File

@ -117,6 +117,11 @@
"type": "boolean",
"description": "Creates an application with stricter type checking and build optimization options.",
"default": true
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -11,6 +11,7 @@ export interface Schema {
buildable: boolean;
publishable: boolean;
importPath?: string;
standaloneConfig?: boolean;
spec?: boolean;
flat?: boolean;

View File

@ -103,6 +103,11 @@
"description": "Enable Ivy for library in tsconfig.lib.prod.json. Should not be used with publishable libraries.",
"type": "boolean",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -14,6 +14,7 @@ describe('schematic:cypress-project', () => {
let tree: Tree;
const defaultOptions: Omit<Schema, 'name' | 'project'> = {
linter: Linter.EsLint,
standaloneConfig: false,
};
beforeEach(() => {
@ -76,6 +77,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.TsLint,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const project = workspaceJson.projects['my-app-e2e'];
@ -114,6 +116,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.TsLint,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const project = workspaceJson.projects['my-app-e2e'];
@ -147,6 +150,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.EsLint,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const project = workspaceJson.projects['my-app-e2e'];
@ -164,6 +168,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.None,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const project = workspaceJson.projects['my-app-e2e'];
@ -176,6 +181,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.EsLint,
standaloneConfig: false,
});
const project = readProjectConfiguration(tree, 'my-app-e2e');
@ -224,6 +230,7 @@ describe('schematic:cypress-project', () => {
project: 'my-dir-my-app',
directory: 'my-dir',
linter: Linter.TsLint,
standaloneConfig: false,
});
const projectConfig = readJson(tree, 'workspace.json').projects[
'my-dir-my-app-e2e'
@ -319,6 +326,7 @@ describe('schematic:cypress-project', () => {
name: 'my-app-e2e',
project: 'my-app',
linter: Linter.EsLint,
standaloneConfig: false,
});
const packageJson = readJson(tree, 'package.json');
expect(

View File

@ -51,28 +51,39 @@ function addProject(tree: Tree, options: CypressProjectSchema) {
: devServerTarget;
}
addProjectConfiguration(tree, options.projectName, {
root: options.projectRoot,
sourceRoot: joinPathFragments(options.projectRoot, 'src'),
projectType: 'application',
targets: {
e2e: {
executor: '@nrwl/cypress:cypress',
options: {
cypressConfig: joinPathFragments(options.projectRoot, 'cypress.json'),
tsConfig: joinPathFragments(options.projectRoot, 'tsconfig.e2e.json'),
devServerTarget,
},
configurations: {
production: {
devServerTarget: `${options.project}:serve:production`,
addProjectConfiguration(
tree,
options.projectName,
{
root: options.projectRoot,
sourceRoot: joinPathFragments(options.projectRoot, 'src'),
projectType: 'application',
targets: {
e2e: {
executor: '@nrwl/cypress:cypress',
options: {
cypressConfig: joinPathFragments(
options.projectRoot,
'cypress.json'
),
tsConfig: joinPathFragments(
options.projectRoot,
'tsconfig.e2e.json'
),
devServerTarget,
},
configurations: {
production: {
devServerTarget: `${options.project}:serve:production`,
},
},
},
},
tags: [],
implicitDependencies: options.project ? [options.project] : undefined,
},
tags: [],
implicitDependencies: options.project ? [options.project] : undefined,
});
options.standaloneConfig
);
}
export async function addLinter(host: Tree, options: CypressProjectSchema) {

View File

@ -8,4 +8,5 @@ export interface Schema {
js?: boolean;
skipFormat?: boolean;
setParserOptionsProject?: boolean;
standaloneConfig?: booleann;
}

View File

@ -45,6 +45,11 @@
"type": "boolean",
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": ["name"]

View File

@ -0,0 +1,101 @@
import { Tree } from '@nrwl/tao/src/shared/tree';
import {
readProjectConfiguration,
addProjectConfiguration,
updateProjectConfiguration,
removeProjectConfiguration,
getProjects,
} from './project-configuration';
import { createTreeWithEmptyWorkspace } from '../tests/create-tree-with-empty-workspace';
import { ProjectConfiguration } from '@nrwl/tao/src/shared/workspace';
import { readJson } from '../utils/json';
const baseTestProjectConfig: ProjectConfiguration = {
root: 'libs/test',
sourceRoot: 'libs/test/src',
targets: {},
};
describe('project configuration', () => {
let tree: Tree;
beforeEach(() => {
tree = createTreeWithEmptyWorkspace();
});
it('should create project.json file when adding a project if standalone is true', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
expect(tree.exists('libs/test/project.json')).toBeTruthy();
});
it('should not create project.json file when adding a project if standalone is false', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, false);
expect(tree.exists('libs/test/project.json')).toBeFalsy();
});
it('should be able to read from standalone projects', () => {
tree.write(
'libs/test/project.json',
JSON.stringify(baseTestProjectConfig, null, 2)
);
tree.write(
'workspace.json',
JSON.stringify(
{
projects: {
test: 'libs/test',
},
},
null,
2
)
);
const projectConfig = readProjectConfiguration(tree, 'test');
expect(projectConfig).toEqual(baseTestProjectConfig);
});
it('should update project.json file when updating a project', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
const expectedProjectConfig = {
...baseTestProjectConfig,
targets: { build: { executor: '' } },
};
updateProjectConfiguration(tree, 'test', expectedProjectConfig);
expect(readJson(tree, 'libs/test/project.json')).toEqual(
expectedProjectConfig
);
});
it('should update workspace.json file when updating an inline project', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, false);
const expectedProjectConfig = {
...baseTestProjectConfig,
targets: { build: { executor: '' } },
};
updateProjectConfiguration(tree, 'test', expectedProjectConfig);
expect(readJson(tree, 'workspace.json').projects.test).toEqual(
expectedProjectConfig
);
});
it('should remove project.json file when removing projct configuration', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
removeProjectConfiguration(tree, 'test');
expect(tree.exists('test/project.json')).toBeFalsy();
});
it('should support workspaces with standalone and inline projects', () => {
addProjectConfiguration(tree, 'test', baseTestProjectConfig, true);
addProjectConfiguration(tree, 'test2', baseTestProjectConfig, false);
const configurations = getProjects(tree);
expect(configurations.get('test')).toEqual(baseTestProjectConfig);
expect(configurations.get('test2')).toEqual(baseTestProjectConfig);
});
});

View File

@ -1,15 +1,17 @@
import type { Tree } from '@nrwl/tao/src/shared/tree';
import type {
import {
ProjectConfiguration,
RawWorkspaceJsonConfiguration,
toNewFormat,
WorkspaceJsonConfiguration,
} from '@nrwl/tao/src/shared/workspace';
import { toNewFormat } from '@nrwl/tao/src/shared/workspace';
import { readJson, updateJson, writeJson } from '../utils/json';
import type {
NxJsonConfiguration,
NxJsonProjectConfiguration,
} from '@nrwl/tao/src/shared/nx';
import { getWorkspacePath } from '../utils/get-workspace-layout';
import { join } from 'path';
export type WorkspaceConfiguration = Omit<
WorkspaceJsonConfiguration,
@ -30,9 +32,16 @@ export type WorkspaceConfiguration = Omit<
export function addProjectConfiguration(
host: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration,
standalone: boolean = false
): void {
setProjectConfiguration(host, projectName, projectConfiguration, 'create');
setProjectConfiguration(
host,
projectName,
projectConfiguration,
'create',
standalone
);
}
/**
@ -78,10 +87,10 @@ export function getProjects(
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
return new Map(
Object.keys(workspace.projects).map((projectName) => {
Object.keys(workspace.projects || {}).map((projectName) => {
return [
projectName,
getProjectConfiguration(projectName, workspace, nxJson),
getProjectConfiguration(host, projectName, workspace, nxJson),
];
})
);
@ -156,31 +165,36 @@ export function readProjectConfiguration(
}
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
if (!nxJson.projects[projectName]) {
throw new Error(
`Cannot find configuration for '${projectName}' in nx.json`
);
}
return getProjectConfiguration(projectName, workspace, nxJson);
// TODO: Remove after confirming that nx.json should be optional.
// if (!nxJson.projects[projectName]) {
// throw new Error(
// `Cannot find configuration for '${projectName}' in nx.json`
// );
// }
return getProjectConfiguration(host, projectName, workspace, nxJson);
}
function getProjectConfiguration(
host: Tree,
projectName: string,
workspace: WorkspaceJsonConfiguration,
nxJson: NxJsonConfiguration
): ProjectConfiguration & NxJsonProjectConfiguration {
return {
...readWorkspaceSection(workspace, projectName),
...readWorkspaceSection(host, workspace, projectName),
...readNxJsonSection(nxJson, projectName),
};
}
function readWorkspaceSection(
host: Tree,
workspace: WorkspaceJsonConfiguration,
projectName: string
) {
return workspace.projects[projectName];
const config = workspace.projects[projectName];
return config;
}
function readNxJsonSection(nxJson: NxJsonConfiguration, projectName: string) {
@ -191,7 +205,8 @@ function setProjectConfiguration(
host: Tree,
projectName: string,
projectConfiguration: ProjectConfiguration & NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete'
mode: 'create' | 'update' | 'delete',
standalone: boolean = false
) {
if (mode === 'delete') {
addProjectToNxJson(host, projectName, undefined, mode);
@ -205,9 +220,14 @@ function setProjectConfiguration(
);
}
const { tags, implicitDependencies, ...workspaceConfiguration } =
projectConfiguration;
addProjectToWorkspaceJson(host, projectName, workspaceConfiguration, mode);
const { tags, implicitDependencies } = projectConfiguration;
addProjectToWorkspaceJson(
host,
projectName,
projectConfiguration,
mode,
standalone
);
addProjectToNxJson(
host,
projectName,
@ -222,11 +242,118 @@ function setProjectConfiguration(
function addProjectToWorkspaceJson(
host: Tree,
projectName: string,
project: ProjectConfiguration,
mode: 'create' | 'update' | 'delete'
project: ProjectConfiguration & NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete',
standalone: boolean = false
) {
const path = getWorkspacePath(host);
const workspaceJson = readJson<WorkspaceJsonConfiguration>(host, path);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(host, path);
validateWorkspaceJsonOperations(mode, workspaceJson, projectName);
const configFile =
mode === 'create' && standalone
? join(project.root, 'project.json')
: getProjectFileLocation(host, projectName);
if (configFile) {
if (mode === 'delete') {
host.delete(configFile);
} else {
writeJson(host, configFile, project);
}
if (mode === 'create') {
workspaceJson.projects[projectName] = project.root;
writeJson(host, path, workspaceJson);
}
} else {
let workspaceConfiguration: ProjectConfiguration;
if (project) {
const { tags, implicitDependencies, ...c } = project;
workspaceConfiguration = c;
}
workspaceJson.projects[projectName] = workspaceConfiguration;
writeJson(host, path, workspaceJson);
}
}
function addProjectToNxJson(
host: Tree,
projectName: string,
config: NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete'
) {
// distributed project files do not use nx.json,
// so only proceed if the project does not use them.
if (!getProjectFileLocation(host, projectName)) {
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
if (mode === 'delete') {
delete nxJson.projects[projectName];
} else {
nxJson.projects[projectName] = {
...{
tags: [],
},
...(config || {}),
};
}
writeJson(host, 'nx.json', nxJson);
}
}
function readWorkspace(host: Tree): WorkspaceJsonConfiguration {
const workspaceJson = inlineProjectConfigurationsWithTree(host);
const originalVersion = workspaceJson.version;
return {
...toNewFormat(workspaceJson),
version: originalVersion,
};
}
/**
* This has to be separate from the inline functionality inside tao,
* as the functionality in tao does not use a Tree. Changes made during
* a generator would not be present during runtime execution.
* @returns
*/
function inlineProjectConfigurationsWithTree(
host: Tree
): WorkspaceJsonConfiguration {
const path = getWorkspacePath(host);
const workspaceJson = readJson<RawWorkspaceJsonConfiguration>(host, path);
Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => {
if (typeof config === 'string') {
const configFileLocation = join(config, 'project.json');
workspaceJson.projects[project] = readJson<
ProjectConfiguration & NxJsonProjectConfiguration
>(host, configFileLocation);
}
});
return workspaceJson as WorkspaceJsonConfiguration;
}
/**
* @description Determine where a project's configuration is located.
* @returns file path if separate from root config, null otherwise.
*/
function getProjectFileLocation(host: Tree, project: string): string | null {
const rawWorkspace = readJson<RawWorkspaceJsonConfiguration>(
host,
getWorkspacePath(host)
);
const projectConfig = rawWorkspace.projects?.[project];
return typeof projectConfig === 'string'
? join(projectConfig, 'project.json')
: null;
}
function validateWorkspaceJsonOperations(
mode: 'create' | 'update' | 'delete',
workspaceJson: RawWorkspaceJsonConfiguration | WorkspaceJsonConfiguration,
projectName: string
) {
if (mode == 'create' && workspaceJson.projects[projectName]) {
throw new Error(
`Cannot create Project '${projectName}'. It already exists.`
@ -239,39 +366,7 @@ function addProjectToWorkspaceJson(
}
if (mode == 'delete' && !workspaceJson.projects[projectName]) {
throw new Error(
`Cannot update Project '${projectName}'. It does not exist.`
`Cannot delete Project '${projectName}'. It does not exist.`
);
}
workspaceJson.projects[projectName] = project;
writeJson(host, path, workspaceJson);
}
function addProjectToNxJson(
host: Tree,
projectName: string,
config: NxJsonProjectConfiguration,
mode: 'create' | 'update' | 'delete'
) {
const nxJson = readJson<NxJsonConfiguration>(host, 'nx.json');
if (mode === 'delete') {
delete nxJson.projects[projectName];
} else {
nxJson.projects[projectName] = {
...{
tags: [],
},
...(config || {}),
};
}
writeJson(host, 'nx.json', nxJson);
}
function readWorkspace(host: Tree): WorkspaceJsonConfiguration {
const path = getWorkspacePath(host);
const workspaceJson = readJson<WorkspaceJsonConfiguration>(host, path);
const originalVersion = workspaceJson.version;
return {
...toNewFormat(workspaceJson),
version: originalVersion,
};
}

View File

@ -4,10 +4,10 @@ import type { Tree } from '@nrwl/tao/src/shared/tree';
/**
* Creates a host for testing.
*/
export function createTreeWithEmptyWorkspace(): Tree {
export function createTreeWithEmptyWorkspace(version = 1): Tree {
const tree = new FsTree('/virtual', false);
tree.write('/workspace.json', JSON.stringify({ version: 1, projects: {} }));
tree.write('/workspace.json', JSON.stringify({ version, projects: {} }));
tree.write('./.prettierrc', JSON.stringify({ singleQuote: true }));
tree.write(
'/package.json',

View File

@ -13,4 +13,5 @@ export interface Schema {
babelJest?: boolean;
js: boolean;
pascalCaseFiles: boolean;
standaloneConfig?: boolean;
}

View File

@ -64,6 +64,11 @@
"type": "boolean",
"description": "Generate JavaScript files rather than TypeScript files.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -13,7 +13,11 @@ describe('app', () => {
});
it('should update workspace.json', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
expect(workspaceJson.projects['my-app'].root).toEqual('apps/my-app');
@ -28,6 +32,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson.projects).toEqual({
@ -42,7 +47,11 @@ describe('app', () => {
});
it('should generate files', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
expect(tree.exists('apps/my-app/tsconfig.app.json')).toBeTruthy();
expect(tree.exists('apps/my-app/src/pages/index.tsx')).toBeTruthy();
@ -55,6 +64,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'scss',
standaloneConfig: false,
});
expect(
tree.exists('apps/my-app/src/pages/index.module.scss')
@ -79,6 +89,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'less',
standaloneConfig: false,
});
expect(
tree.exists('apps/my-app/src/pages/index.module.less')
@ -103,6 +114,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styl',
standaloneConfig: false,
});
expect(
tree.exists('apps/my-app/src/pages/index.module.styl')
@ -127,6 +139,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styled-components',
standaloneConfig: false,
});
expect(
tree.exists('apps/my-app/src/pages/index.module.styled-components')
@ -152,6 +165,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: '@emotion/styled',
standaloneConfig: false,
});
expect(
tree.exists('apps/my-app/src/pages/index.module.styled-components')
@ -177,6 +191,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styled-jsx',
standaloneConfig: false,
});
const indexContent = tree
@ -206,6 +221,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
expect(tree.read('apps/my-app/jest.config.js', 'utf-8')).toContain(
@ -217,6 +233,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
expect(tree.read('apps/my-app/jest.config.js', 'utf-8')).toContain(
@ -228,6 +245,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const architectConfig = workspaceJson.projects['my-app'].architect;
@ -241,6 +259,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const architectConfig = workspaceJson.projects['my-app'].architect;
@ -259,6 +278,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
unitTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('jest.config.js')).toBeFalsy();
expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeFalsy();
@ -271,6 +291,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
e2eTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
const workspaceJson = readJson(tree, 'workspace.json');
@ -279,7 +300,11 @@ describe('app', () => {
});
it('should generate an index component', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const appContent = tree.read('apps/my-app/src/pages/index.tsx', 'utf-8');
@ -290,6 +315,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const packageJson = readJson(tree, '/package.json');
@ -349,6 +375,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
js: true,
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/src/pages/index.js')).toBeTruthy();

View File

@ -46,8 +46,13 @@ export function addProject(host: Tree, options: NormalizedSchema) {
targets,
};
addProjectConfiguration(host, options.projectName, {
...project,
...nxConfig,
});
addProjectConfiguration(
host,
options.projectName,
{
...project,
...nxConfig,
},
options.standaloneConfig
);
}

View File

@ -9,4 +9,5 @@ export interface Schema {
e2eTestRunner?: 'cypress' | 'none';
js?: boolean;
setParserOptionsProject?: boolean;
standaloneConfig?: boolean;
}

View File

@ -89,6 +89,11 @@
"type": "boolean",
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": ["name"]

View File

@ -12,7 +12,11 @@ describe('component', () => {
tree = createTreeWithEmptyWorkspace();
tree.write('.gitignore', '# empty');
tree.write('.prettierignore', '# empty');
await applicationGenerator(tree, { name: projectName, style: 'css' });
await applicationGenerator(tree, {
name: projectName,
style: 'css',
standaloneConfig: false,
});
});
it('should generate component in components directory', async () => {

View File

@ -12,7 +12,11 @@ describe('component', () => {
tree = createTreeWithEmptyWorkspace();
tree.write('.gitignore', '# empty');
tree.write('.prettierignore', '# empty');
await applicationGenerator(tree, { name: projectName, style: 'css' });
await applicationGenerator(tree, {
name: projectName,
style: 'css',
standaloneConfig: false,
});
});
it('should generate component in pages directory', async () => {

View File

@ -10,4 +10,5 @@ export interface Schema {
tags?: string;
linter: Linter;
frontendProject?: string;
standaloneConfig?: boolean;
}

View File

@ -46,6 +46,11 @@
"frontendProject": {
"type": "string",
"description": "Frontend project that needs to access this application. This sets up proxy configuration."
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -13,7 +13,11 @@ describe('app', () => {
describe('not nested', () => {
it('should update workspace.json', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
@ -29,6 +33,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson = readJson(tree, 'nx.json');
@ -45,7 +50,11 @@ describe('app', () => {
});
it('should generate files', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/tsconfig.json')).toBeTruthy();
expect(tree.exists('apps/my-app/pages/index.tsx')).toBeTruthy();
expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeTruthy();
@ -58,6 +67,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'scss',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/pages/index.module.scss')).toBeTruthy();
@ -75,6 +85,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'less',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/pages/index.module.less')).toBeTruthy();
@ -92,6 +103,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styl',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/pages/index.module.styl')).toBeTruthy();
@ -109,6 +121,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styled-components',
standaloneConfig: false,
});
expect(
@ -127,6 +140,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: '@emotion/styled',
standaloneConfig: false,
});
expect(
@ -145,6 +159,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'styled-jsx',
standaloneConfig: false,
});
const indexContent = tree.read('apps/my-app/pages/index.tsx', 'utf-8');
@ -163,7 +178,11 @@ describe('app', () => {
});
it('should setup jest with tsx support', async () => {
await applicationGenerator(tree, { name: 'my-app', style: 'css' });
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
expect(tree.read('apps/my-app/jest.config.js', 'utf-8')).toContain(
`moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],`
@ -171,7 +190,11 @@ describe('app', () => {
});
it('should setup jest with SVGR support', async () => {
await applicationGenerator(tree, { name: 'my-app', style: 'css' });
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
expect(tree.read('apps/my-app/jest.config.js', 'utf-8')).toContain(
`'^(?!.*\\\\.(js|jsx|ts|tsx|css|json)$)': '@nrwl/react/plugins/jest'`
@ -179,7 +202,11 @@ describe('app', () => {
});
it('should set up the nrwl next build builder', async () => {
await applicationGenerator(tree, { name: 'my-app', style: 'css' });
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const architectConfig = workspaceJson.projects['my-app'].architect;
@ -191,7 +218,11 @@ describe('app', () => {
});
it('should set up the nrwl next server builder', async () => {
await applicationGenerator(tree, { name: 'my-app', style: 'css' });
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const architectConfig = workspaceJson.projects['my-app'].architect;
@ -206,7 +237,11 @@ describe('app', () => {
});
it('should set up the nrwl next export builder', async () => {
await applicationGenerator(tree, { name: 'my-app', style: 'css' });
await applicationGenerator(tree, {
name: 'my-app',
style: 'css',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, 'workspace.json');
const architectConfig = workspaceJson.projects['my-app'].architect;
@ -222,6 +257,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
unitTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('jest.config.js')).toBeFalsy();
expect(tree.exists('apps/my-app/specs/index.spec.tsx')).toBeFalsy();
@ -234,6 +270,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
e2eTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('apps/my-app-e2e')).toBeFalsy();
const workspaceJson = readJson(tree, 'workspace.json');
@ -242,7 +279,11 @@ describe('app', () => {
});
it('should generate functional components by default', async () => {
await applicationGenerator(tree, { name: 'myApp', style: 'css' });
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const appContent = tree.read('apps/my-app/pages/index.tsx', 'utf-8');
@ -255,6 +296,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myApp',
style: 'css',
standaloneConfig: false,
});
const packageJson = readJson(tree, '/package.json');
@ -311,6 +353,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
linter: Linter.TsLint,
standaloneConfig: false,
});
const tslintJson = readJson(tree, 'apps/my-app/tslint.json');
@ -335,6 +378,7 @@ describe('app', () => {
name: 'myApp',
style: 'css',
js: true,
standaloneConfig: false,
});
expect(tree.exists('apps/my-app/pages/index.js')).toBeTruthy();

View File

@ -63,8 +63,13 @@ export function addProject(host: Tree, options: NormalizedSchema) {
targets,
};
addProjectConfiguration(host, options.projectName, {
...project,
...nxConfig,
});
addProjectConfiguration(
host,
options.projectName,
{
...project,
...nxConfig,
},
options.standaloneConfig
);
}

View File

@ -14,4 +14,5 @@ export interface Schema {
skipWorkspaceJson?: boolean;
js?: boolean;
setParserOptionsProject?: boolean;
standaloneConfig?: boolean;
}

View File

@ -109,6 +109,11 @@
"type": "boolean",
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -10,7 +10,11 @@ describe('component', () => {
beforeEach(async () => {
projectName = 'my-app';
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, { name: projectName, style: 'css' });
await applicationGenerator(tree, {
name: projectName,
style: 'css',
standaloneConfig: false,
});
});
it('should generate component in components directory', async () => {

View File

@ -10,7 +10,11 @@ describe('component', () => {
beforeEach(async () => {
projectName = 'my-app';
tree = createTreeWithEmptyWorkspace();
await applicationGenerator(tree, { name: projectName, style: 'css' });
await applicationGenerator(tree, {
name: projectName,
style: 'css',
standaloneConfig: false,
});
});
it('should generate component in pages directory', async () => {

View File

@ -31,7 +31,10 @@ describe('app', () => {
describe('not nested', () => {
it('should update workspace.json', async () => {
await applicationGenerator(tree, { name: 'myNodeApp' });
await applicationGenerator(tree, {
name: 'myNodeApp',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
const project = workspaceJson.projects['my-node-app'];
expect(project.root).toEqual('apps/my-node-app');
@ -79,7 +82,11 @@ describe('app', () => {
});
it('should update nx.json', async () => {
await applicationGenerator(tree, { name: 'myNodeApp', tags: 'one,two' });
await applicationGenerator(tree, {
name: 'myNodeApp',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson.projects).toEqual({
'my-node-app': {
@ -89,7 +96,10 @@ describe('app', () => {
});
it('should generate files', async () => {
await applicationGenerator(tree, { name: 'myNodeApp' });
await applicationGenerator(tree, {
name: 'myNodeApp',
standaloneConfig: false,
});
expect(tree.exists(`apps/my-node-app/jest.config.js`)).toBeTruthy();
expect(tree.exists('apps/my-node-app/src/main.ts')).toBeTruthy();
@ -158,6 +168,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myNodeApp',
directory: 'myDir',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
@ -183,6 +194,7 @@ describe('app', () => {
name: 'myNodeApp',
directory: 'myDir',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson.projects).toEqual({
@ -201,6 +213,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myNodeApp',
directory: 'myDir',
standaloneConfig: false,
});
// Make sure these exist
@ -237,6 +250,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myNodeApp',
unitTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('jest.config.js')).toBeFalsy();
expect(tree.exists('apps/my-node-app/src/test-setup.ts')).toBeFalsy();
@ -268,6 +282,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myNodeApp',
frontendProject: 'my-frontend',
standaloneConfig: false,
});
expect(tree.exists('apps/my-frontend/proxy.conf.json')).toBeTruthy();
@ -284,11 +299,13 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'cart',
frontendProject: 'my-frontend',
standaloneConfig: false,
});
await applicationGenerator(tree, {
name: 'billing',
frontendProject: 'my-frontend',
standaloneConfig: false,
});
expect(tree.exists('apps/my-frontend/proxy.conf.json')).toBeTruthy();
@ -305,6 +322,7 @@ describe('app', () => {
await applicationGenerator(tree, {
name: 'myNodeApp',
frontendProject: 'myFrontend',
standaloneConfig: false,
});
expect(tree.exists('apps/my-frontend/proxy.conf.json')).toBeTruthy();

View File

@ -93,7 +93,12 @@ function addProject(tree: Tree, options: NormalizedSchema) {
project.targets.build = getBuildConfig(project, options);
project.targets.serve = getServeConfig(options);
addProjectConfiguration(tree, options.name, project);
addProjectConfiguration(
tree,
options.name,
project,
options.standaloneConfig
);
const workspace = readWorkspaceConfiguration(tree);

View File

@ -13,4 +13,5 @@ export interface Schema {
js?: boolean;
pascalCaseFiles?: boolean;
setParserOptionsProject?: boolean;
standaloneConfig?: boolean;
}

View File

@ -68,6 +68,11 @@
"type": "boolean",
"description": "Whether or not to configure the ESLint \"parserOptions.project\" option. We do not do this by default for lint performance reasons.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": []

View File

@ -13,7 +13,7 @@ describe('lib', () => {
describe('not nested', () => {
it('should update workspace.json', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
const workspaceJson = readJson(tree, '/workspace.json');
expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib');
expect(workspaceJson.projects['my-lib'].architect.build).toBeUndefined();
@ -38,6 +38,7 @@ describe('lib', () => {
name: 'myLib',
rootDir: './src',
buildable: true,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
expect(
@ -47,7 +48,11 @@ describe('lib', () => {
});
it('should update nx.json', async () => {
await libraryGenerator(tree, { name: 'myLib', tags: 'one,two' });
await libraryGenerator(tree, {
name: 'myLib',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson.projects).toEqual({
'my-lib': {
@ -57,7 +62,7 @@ describe('lib', () => {
});
it('should update root tsconfig.base.json', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
expect(tsconfigJson.compilerOptions.paths['@proj/my-lib']).toEqual([
'libs/my-lib/src/index.ts',
@ -65,7 +70,7 @@ describe('lib', () => {
});
it('should create a local tsconfig.json', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.json');
expect(tsconfigJson).toMatchInlineSnapshot(`
Object {
@ -85,20 +90,20 @@ describe('lib', () => {
});
it('should extend the local tsconfig.json with tsconfig.spec.json', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.spec.json');
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
});
it('should extend the local tsconfig.json with tsconfig.lib.json', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
const tsconfigJson = readJson(tree, 'libs/my-lib/tsconfig.lib.json');
expect(tsconfigJson.compilerOptions.types).toContain('node');
expect(tsconfigJson.extends).toEqual('./tsconfig.json');
});
it('should generate files', async () => {
await libraryGenerator(tree, { name: 'myLib' });
await libraryGenerator(tree, { name: 'myLib', standaloneConfig: false });
expect(tree.exists(`libs/my-lib/jest.config.js`)).toBeTruthy();
expect(tree.exists('libs/my-lib/src/index.ts')).toBeTruthy();
@ -147,6 +152,7 @@ describe('lib', () => {
name: 'myLib',
directory: 'myDir',
tags: 'one',
standaloneConfig: false,
});
const nxJson = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson.projects).toEqual({
@ -159,6 +165,7 @@ describe('lib', () => {
name: 'myLib2',
directory: 'myDir',
tags: 'one,two',
standaloneConfig: false,
});
const nxJson2 = readJson<NxJsonConfiguration>(tree, '/nx.json');
expect(nxJson2.projects).toEqual({
@ -172,13 +179,21 @@ describe('lib', () => {
});
it('should generate files', async () => {
await libraryGenerator(tree, { name: 'myLib', directory: 'myDir' });
await libraryGenerator(tree, {
name: 'myLib',
directory: 'myDir',
standaloneConfig: false,
});
expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy();
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
});
it('should update workspace.json', async () => {
await libraryGenerator(tree, { name: 'myLib', directory: 'myDir' });
await libraryGenerator(tree, {
name: 'myLib',
directory: 'myDir',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
expect(workspaceJson.projects['my-dir-my-lib'].root).toEqual(
@ -193,7 +208,11 @@ describe('lib', () => {
});
it('should update tsconfig.json', async () => {
await libraryGenerator(tree, { name: 'myLib', directory: 'myDir' });
await libraryGenerator(tree, {
name: 'myLib',
directory: 'myDir',
standaloneConfig: false,
});
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
expect(tsconfigJson.compilerOptions.paths['@proj/my-dir/my-lib']).toEqual(
['libs/my-dir/my-lib/src/index.ts']
@ -211,6 +230,7 @@ describe('lib', () => {
name: 'myLib',
directory: 'myDir',
publishable: true,
standaloneConfig: false,
});
} catch (e) {
expect(e.message).toContain(
@ -220,7 +240,11 @@ describe('lib', () => {
});
it('should create a local tsconfig.json', async () => {
await libraryGenerator(tree, { name: 'myLib', directory: 'myDir' });
await libraryGenerator(tree, {
name: 'myLib',
directory: 'myDir',
standaloneConfig: false,
});
const tsconfigJson = readJson(tree, 'libs/my-dir/my-lib/tsconfig.json');
expect(tsconfigJson.extends).toEqual('../../../tsconfig.base.json');
@ -239,6 +263,7 @@ describe('lib', () => {
name: 'myLib',
directory: 'myDir',
simpleModuleName: true,
standaloneConfig: false,
});
expect(tree.exists(`libs/my-dir/my-lib/jest.config.js`)).toBeTruthy();
expect(tree.exists('libs/my-dir/my-lib/src/index.ts')).toBeTruthy();
@ -253,7 +278,11 @@ describe('lib', () => {
describe('--unit-test-runner none', () => {
it('should not generate test configuration', async () => {
await libraryGenerator(tree, { name: 'myLib', unitTestRunner: 'none' });
await libraryGenerator(tree, {
name: 'myLib',
unitTestRunner: 'none',
standaloneConfig: false,
});
expect(tree.exists('libs/my-lib/tsconfig.spec.json')).toBeFalsy();
expect(tree.exists('libs/my-lib/jest.config.js')).toBeFalsy();
expect(tree.exists('libs/my-lib/lib/my-lib.spec.ts')).toBeFalsy();
@ -282,7 +311,11 @@ describe('lib', () => {
describe('buildable package', () => {
it('should have a builder defined', async () => {
await libraryGenerator(tree, { name: 'myLib', buildable: true });
await libraryGenerator(tree, {
name: 'myLib',
buildable: true,
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
expect(workspaceJson.projects['my-lib'].root).toEqual('libs/my-lib');
@ -314,6 +347,7 @@ describe('lib', () => {
name: 'myLib',
publishable: true,
importPath: '@proj/mylib',
standaloneConfig: false,
});
const workspaceJson = readJson(tree, '/workspace.json');
@ -327,6 +361,7 @@ describe('lib', () => {
name: 'mylib',
publishable: true,
importPath: '@proj/mylib',
standaloneConfig: false,
});
let packageJsonContent = readJson(tree, 'libs/mylib/package.json');
@ -342,6 +377,7 @@ describe('lib', () => {
publishable: true,
directory: 'myDir',
importPath: '@myorg/lib',
standaloneConfig: false,
});
const packageJson = readJson(tree, 'libs/my-dir/my-lib/package.json');
const tsconfigJson = readJson(tree, '/tsconfig.base.json');
@ -357,6 +393,7 @@ describe('lib', () => {
name: 'myLib1',
publishable: true,
importPath: '@myorg/lib',
standaloneConfig: false,
});
try {
@ -364,6 +401,7 @@ describe('lib', () => {
name: 'myLib2',
publishable: true,
importPath: '@myorg/lib',
standaloneConfig: false,
});
} catch (e) {
expect(e.message).toContain(

View File

@ -18,4 +18,5 @@ export interface Schema {
js?: boolean;
pascalCaseFiles?: boolean;
strict?: boolean;
standaloneConfig?: boolean;
}

View File

@ -101,6 +101,11 @@
"type": "boolean",
"description": "Whether to enable tsconfig strict mode or not.",
"default": false
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": ["name"]

View File

@ -25,6 +25,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-plugin',
pluginOutputPath: `dist/libs/my-plugin`,
npmPackageName: '@proj/my-plugin',
standaloneConfig: false,
})
).resolves.not.toThrow();
@ -33,6 +34,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-nonexistentplugin',
pluginOutputPath: `dist/libs/my-nonexistentplugin`,
npmPackageName: '@proj/my-nonexistentplugin',
standaloneConfig: false,
})
).rejects.toThrow();
});
@ -42,6 +44,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-plugin',
pluginOutputPath: `dist/libs/my-plugin`,
npmPackageName: '@proj/my-plugin',
standaloneConfig: false,
});
expect(tree.exists('apps/my-plugin-e2e/tsconfig.json')).toBeTruthy();
@ -56,6 +59,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginOutputPath: `dist/libs/namespace/my-plugin`,
npmPackageName: '@proj/namespace-my-plugin',
projectDirectory: 'namespace/my-plugin',
standaloneConfig: false,
});
const project = readProjectConfiguration(tree, 'my-plugin-e2e');
@ -67,6 +71,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-plugin',
pluginOutputPath: `dist/libs/my-plugin`,
npmPackageName: '@proj/my-plugin',
standaloneConfig: false,
});
expect(readJson(tree, 'nx.json')).toMatchObject({
@ -84,6 +89,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-plugin',
pluginOutputPath: `dist/libs/my-plugin`,
npmPackageName: '@proj/my-plugin',
standaloneConfig: false,
});
const project = readProjectConfiguration(tree, 'my-plugin-e2e');
@ -106,6 +112,7 @@ describe('NxPlugin e2e-project Generator', () => {
pluginName: 'my-plugin',
pluginOutputPath: `dist/libs/my-plugin`,
npmPackageName: '@proj/my-plugin',
standaloneConfig: false,
});
const project = readProjectConfiguration(tree, 'my-plugin-e2e');

View File

@ -56,23 +56,28 @@ function addFiles(host: Tree, options: NormalizedSchema) {
}
function updateWorkspaceConfiguration(host: Tree, options: NormalizedSchema) {
addProjectConfiguration(host, options.projectName, {
root: options.projectRoot,
projectType: 'application',
sourceRoot: `${options.projectRoot}/src`,
targets: {
e2e: {
executor: '@nrwl/nx-plugin:e2e',
options: {
target: `${options.pluginName}:build`,
npmPackageName: options.npmPackageName,
pluginOutputPath: options.pluginOutputPath,
addProjectConfiguration(
host,
options.projectName,
{
root: options.projectRoot,
projectType: 'application',
sourceRoot: `${options.projectRoot}/src`,
targets: {
e2e: {
executor: '@nrwl/nx-plugin:e2e',
options: {
target: `${options.pluginName}:build`,
npmPackageName: options.npmPackageName,
pluginOutputPath: options.pluginOutputPath,
},
},
},
tags: [],
implicitDependencies: [options.pluginName],
},
tags: [],
implicitDependencies: [options.pluginName],
});
options.standaloneConfig
);
}
async function addJest(host: Tree, options: NormalizedSchema) {

View File

@ -4,4 +4,5 @@ export interface Schema {
projectDirectory?: string;
pluginOutputPath?: string;
jestConfig?: string;
standaloneConfig?: boolean;
}

View File

@ -29,6 +29,11 @@
"type": "string",
"description": "Spec tsconfig file",
"x-deprecated": true
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": ["pluginName", "npmPackageName"],

View File

@ -150,6 +150,7 @@ export async function pluginGenerator(host: Tree, schema: Schema) {
projectDirectory: options.projectDirectory,
pluginOutputPath: `dist/${options.libsDir}/${options.projectDirectory}`,
npmPackageName: options.npmPackageName,
standaloneConfig: options.standaloneConfig,
});
await formatFiles(host);

View File

@ -9,4 +9,5 @@ export interface Schema {
tags?: string;
unitTestRunner: 'jest' | 'none';
linter: Linter;
standaloneConfig?: boolean;
}

View File

@ -55,6 +55,11 @@
"type": "boolean",
"default": false,
"description": "Do not update tsconfig.json for development experience."
},
"standaloneConfig": {
"description": "Split the project configuration into <projectRoot>/project.json rather than including it inside workspace.json",
"type": "boolean",
"default": false
}
},
"required": ["name"],

View File

@ -20,6 +20,7 @@ describe('app', () => {
linter: Linter.EsLint,
style: 'css',
strict: false,
standaloneConfig: false,
};
beforeEach(() => {

View File

@ -22,10 +22,15 @@ export function addProject(host, options: NormalizedSchema) {
},
};
addProjectConfiguration(host, options.projectName, {
...project,
...nxConfig,
});
addProjectConfiguration(
host,
options.projectName,
{
...project,
...nxConfig,
},
options.standaloneConfig
);
}
function maybeJs(options: NormalizedSchema, path: string): string {

View File

@ -19,6 +19,7 @@ export interface Schema {
globalCss?: boolean;
strict?: boolean;
setParserOptionsProject?: boolean;
standaloneConfig?: boolean;
}
export interface NormalizedSchema extends Schema {

Some files were not shown because too many files have changed in this diff Show More