feat(misc): add useProjectJson flag to project generators (#30319)
Add a `useProjectJson` option to project generators to allow users to opt in/out of generating the Nx configuration in a `project.json` file. ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes #
This commit is contained in:
parent
432a645d21
commit
cbf80c18d1
@ -58,6 +58,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["e2eDirectory", "appProject", "framework"],
|
||||
|
||||
@ -86,6 +86,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -89,6 +89,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -73,6 +73,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -78,6 +78,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Adds strictNullChecks, noImplicitAny, strictBindCallApply, forceConsistentCasingInFileNames and noFallthroughCasesInSwitch to tsconfig.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -133,6 +133,10 @@
|
||||
"description": "Don't include the directory in the name of the module of the library.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -138,6 +138,10 @@
|
||||
"default": false,
|
||||
"hidden": true,
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -152,6 +152,10 @@
|
||||
"default": false,
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -123,6 +123,10 @@
|
||||
"docker": {
|
||||
"type": "boolean",
|
||||
"description": "Add a docker build target"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -123,6 +123,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Whether or not to configure the ESLint `parserOptions.project`. We do not do this by default for lint performance reasons.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "application",
|
||||
"factory": "./src/generators/application/application",
|
||||
"factory": "./src/generators/application/application#applicationGeneratorInternal",
|
||||
"schema": {
|
||||
"$schema": "https://json-schema.org/schema",
|
||||
"cli": "nx",
|
||||
@ -100,6 +100,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
@ -108,7 +112,7 @@
|
||||
},
|
||||
"aliases": ["app"],
|
||||
"description": "Create a Nuxt application.",
|
||||
"implementation": "/packages/nuxt/src/generators/application/application.ts",
|
||||
"implementation": "/packages/nuxt/src/generators/application/application#applicationGeneratorInternal.ts",
|
||||
"hidden": false,
|
||||
"path": "/packages/nuxt/src/generators/application/schema.json",
|
||||
"type": "generator"
|
||||
|
||||
@ -95,6 +95,10 @@
|
||||
"x-prompt": "Which bundler do you want to use to build the application?",
|
||||
"default": "vite",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -93,6 +93,10 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -181,6 +181,10 @@
|
||||
"description": "Generate a React app with a minimal setup, no separate test files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -184,6 +184,10 @@
|
||||
"description": "Don't include the directory in the name of the module of the library.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -57,6 +57,10 @@
|
||||
"type": "boolean",
|
||||
"x-priority": "internal",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -81,6 +81,10 @@
|
||||
"default": false,
|
||||
"description": "Generate a buildable library that uses rollup to bundle.",
|
||||
"x-deprecated": "Use the `bundler` option for greater control (none, vite, rollup)."
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -133,6 +133,10 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"hidden": true
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -125,6 +125,10 @@
|
||||
"description": "Create a Vue library with a minimal setup, no separate test files.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -101,6 +101,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Creates an application with strict mode and strict type checking.",
|
||||
"default": true
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -531,6 +531,7 @@ describe('detox application generator', () => {
|
||||
linter: Linter.None,
|
||||
framework: 'react-native',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(tree.read('tsconfig.json', 'utf-8')).toMatchInlineSnapshot(`
|
||||
@ -592,6 +593,7 @@ describe('detox application generator', () => {
|
||||
framework: 'react-native',
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(tree.exists('apps/my-app-e2e/test-setup.ts')).toBeTruthy();
|
||||
@ -672,6 +674,7 @@ describe('detox application generator', () => {
|
||||
framework: 'react-native',
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'apps/my-app-e2e/package.json');
|
||||
@ -687,5 +690,38 @@ describe('detox application generator', () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
writeJson(tree, 'apps/my-app/package.json', { name: 'my-app' });
|
||||
|
||||
await detoxApplicationGenerator(tree, {
|
||||
e2eDirectory: 'apps/my-app-e2e',
|
||||
appProject: 'my-app',
|
||||
e2eName: 'my-app-e2e',
|
||||
linter: Linter.None,
|
||||
framework: 'react-native',
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
useProjectJson: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('apps/my-app-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, 'my-app-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"my-app",
|
||||
],
|
||||
"name": "my-app-e2e",
|
||||
"projectType": "application",
|
||||
"root": "apps/my-app-e2e",
|
||||
"sourceRoot": "apps/my-app-e2e/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'apps/my-app-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,6 +18,7 @@ import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields
|
||||
export async function detoxApplicationGenerator(host: Tree, schema: Schema) {
|
||||
return await detoxApplicationGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
@ -41,6 +41,7 @@ describe('Add Project', () => {
|
||||
appRoot: 'apps/my-app',
|
||||
linter: Linter.EsLint,
|
||||
framework: 'react-native',
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -91,6 +92,7 @@ describe('Add Project', () => {
|
||||
appRoot: 'apps/my-dir/my-app',
|
||||
linter: Linter.EsLint,
|
||||
framework: 'react-native',
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ import {
|
||||
reactNativeTestTarget,
|
||||
} from './get-targets';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
const nxJson = readNxJson(host);
|
||||
@ -23,20 +23,21 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
: p.plugin === '@nx/detox/plugin'
|
||||
);
|
||||
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
writeJson(host, joinPathFragments(options.e2eProjectRoot, 'package.json'), {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
name:
|
||||
options.e2eProjectName !== options.importPath
|
||||
? options.e2eProjectName
|
||||
: undefined,
|
||||
targets: hasPlugin ? undefined : getTargets(options),
|
||||
implicitDependencies: [options.appProject],
|
||||
},
|
||||
});
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
root: options.e2eProjectRoot,
|
||||
@ -47,6 +48,14 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
implicitDependencies: [options.appProject],
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getTargets(options: NormalizedSchema) {
|
||||
|
||||
@ -40,6 +40,7 @@ describe('Normalize Options', () => {
|
||||
isUsingTsSolutionConfig: false,
|
||||
linter: Linter.EsLint,
|
||||
js: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -70,6 +71,7 @@ describe('Normalize Options', () => {
|
||||
framework: 'react-native',
|
||||
isUsingTsSolutionConfig: false,
|
||||
js: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -101,6 +103,7 @@ describe('Normalize Options', () => {
|
||||
framework: 'react-native',
|
||||
isUsingTsSolutionConfig: false,
|
||||
js: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -41,6 +41,8 @@ export async function normalizeOptions(
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host);
|
||||
const e2eProjectName =
|
||||
!isUsingTsSolutionConfig || options.e2eName ? projectName : importPath;
|
||||
// We default to generate a project.json file if the new setup is not being used
|
||||
const useProjectJson = options.useProjectJson ?? !isUsingTsSolutionConfig;
|
||||
|
||||
return {
|
||||
...options,
|
||||
@ -54,5 +56,6 @@ export async function normalizeOptions(
|
||||
importPath,
|
||||
isUsingTsSolutionConfig,
|
||||
js: options.js ?? false,
|
||||
useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
@ -12,4 +12,5 @@ export interface Schema {
|
||||
setParserOptionsProject?: boolean;
|
||||
framework: 'react-native' | 'expo';
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -60,6 +60,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["e2eDirectory", "appProject", "framework"]
|
||||
|
||||
@ -482,7 +482,7 @@ describe('app', () => {
|
||||
`);
|
||||
});
|
||||
|
||||
it('should respect provided name', async () => {
|
||||
it('should respect the provided name', async () => {
|
||||
await expoApplicationGenerator(tree, {
|
||||
directory: 'my-app',
|
||||
name: 'my-app',
|
||||
@ -493,6 +493,7 @@ describe('app', () => {
|
||||
js: false,
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'my-app/package.json');
|
||||
@ -508,5 +509,50 @@ describe('app', () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await expoApplicationGenerator(tree, {
|
||||
directory: 'my-app',
|
||||
linter: Linter.EsLint,
|
||||
e2eTestRunner: 'cypress',
|
||||
useProjectJson: true,
|
||||
unitTestRunner: 'none',
|
||||
js: false,
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('my-app/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/my-app'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/my-app",
|
||||
"projectType": "application",
|
||||
"root": "my-app",
|
||||
"sourceRoot": "my-app/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'my-app/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('my-app-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/my-app-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/my-app",
|
||||
],
|
||||
"name": "@proj/my-app-e2e",
|
||||
"projectType": "application",
|
||||
"root": "my-app-e2e",
|
||||
"sourceRoot": "my-app-e2e/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'my-app-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -32,6 +32,7 @@ export async function expoApplicationGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await expoApplicationGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
@ -7,15 +7,14 @@ import {
|
||||
Tree,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { webStaticServeGenerator } from '@nx/web';
|
||||
|
||||
import { nxVersion } from '../../../utils/versions';
|
||||
import { hasExpoPlugin } from '../../../utils/has-expo-plugin';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
import { getE2EWebServerInfo } from '@nx/devkit/src/generators/e2e-web-server-info-utils';
|
||||
import { addE2eCiTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import { findPluginForConfigFile } from '@nx/devkit/src/utils/find-plugin-for-config-file';
|
||||
import { getE2EWebServerInfo } from '@nx/devkit/src/generators/e2e-web-server-info-utils';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { webStaticServeGenerator } from '@nx/web';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
import { hasExpoPlugin } from '../../../utils/has-expo-plugin';
|
||||
import { nxVersion } from '../../../utils/versions';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
|
||||
export async function addE2e(
|
||||
tree: Tree,
|
||||
@ -42,19 +41,16 @@ export async function addE2e(
|
||||
typeof import('@nx/cypress')
|
||||
>('@nx/cypress', nxVersion);
|
||||
|
||||
if (isUsingTsSolutionSetup(tree)) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(tree, options.e2eProjectName, {
|
||||
projectType: 'application',
|
||||
@ -66,6 +62,14 @@ export async function addE2e(
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(tree, {
|
||||
...options,
|
||||
project: options.e2eProjectName,
|
||||
@ -123,19 +127,16 @@ export async function addE2e(
|
||||
const { configurationGenerator } = ensurePackage<
|
||||
typeof import('@nx/playwright')
|
||||
>('@nx/playwright', nxVersion);
|
||||
if (isUsingTsSolutionSetup(tree)) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(tree, options.e2eProjectName, {
|
||||
projectType: 'application',
|
||||
@ -143,9 +144,18 @@ export async function addE2e(
|
||||
sourceRoot: joinPathFragments(options.e2eProjectRoot, 'src'),
|
||||
targets: {},
|
||||
implicitDependencies: [options.projectName],
|
||||
tags: [],
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(tree, {
|
||||
project: options.e2eProjectName,
|
||||
skipFormat: true,
|
||||
|
||||
@ -6,12 +6,10 @@ import {
|
||||
Tree,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
|
||||
import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
import { hasExpoPlugin } from '../../../utils/has-expo-plugin';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
import { addBuildTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
const hasPlugin = hasExpoPlugin(host);
|
||||
@ -28,13 +26,13 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
tags: options.parsedTags,
|
||||
};
|
||||
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
if (options.importPath !== options.projectName) {
|
||||
packageJson.nx = { name: options.projectName };
|
||||
}
|
||||
@ -46,12 +44,6 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(
|
||||
host,
|
||||
@ -60,6 +52,14 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
options.standaloneConfig
|
||||
);
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function getTargets(options: NormalizedSchema) {
|
||||
|
||||
@ -41,6 +41,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
} as NormalizedSchema);
|
||||
});
|
||||
|
||||
@ -74,6 +75,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'myApp-e2e',
|
||||
e2eProjectRoot: 'myApp-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
} as NormalizedSchema);
|
||||
});
|
||||
|
||||
@ -109,6 +111,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'directory-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
} as NormalizedSchema);
|
||||
});
|
||||
|
||||
@ -142,6 +145,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'directory/my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
} as NormalizedSchema);
|
||||
});
|
||||
|
||||
@ -176,6 +180,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
} as NormalizedSchema);
|
||||
});
|
||||
});
|
||||
|
||||
@ -51,6 +51,7 @@ export async function normalizeOptions(
|
||||
const isTsSolutionSetup = isUsingTsSolutionSetup(host);
|
||||
const appProjectName =
|
||||
!isTsSolutionSetup || options.name ? projectName : importPath;
|
||||
const useProjectJson = options.useProjectJson ?? !isTsSolutionSetup;
|
||||
|
||||
const e2eProjectName = rootProject ? 'e2e' : `${appProjectName}-e2e`;
|
||||
const e2eProjectRoot = rootProject ? 'e2e' : `${appProjectRoot}-e2e`;
|
||||
@ -71,5 +72,6 @@ export async function normalizeOptions(
|
||||
e2eProjectName,
|
||||
e2eProjectRoot,
|
||||
isTsSolutionSetup,
|
||||
useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
@ -20,4 +20,5 @@ export interface Schema {
|
||||
nxCloudToken?: string;
|
||||
useTsSolution?: boolean;
|
||||
formatter?: 'prettier' | 'none';
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -86,6 +86,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# <%= name %>
|
||||
# <%= projectName %>
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Running unit tests
|
||||
|
||||
Run `nx test <%= name %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
Run `nx test <%= projectName %>` to execute the unit tests via [Jest](https://jestjs.io).
|
||||
|
||||
@ -6,8 +6,7 @@ import {
|
||||
import { Schema } from '../schema';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
|
||||
export interface NormalizedSchema extends Schema {
|
||||
name: string;
|
||||
export interface NormalizedSchema extends Omit<Schema, 'name'> {
|
||||
fileName: string;
|
||||
projectName: string;
|
||||
projectRoot: string;
|
||||
@ -44,17 +43,19 @@ export async function normalizeOptions(
|
||||
: [];
|
||||
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host);
|
||||
const useProjectJson = options.useProjectJson ?? !isUsingTsSolutionConfig;
|
||||
|
||||
const normalized: NormalizedSchema = {
|
||||
...options,
|
||||
fileName: projectName,
|
||||
routePath: `/${projectNames.projectSimpleName}`,
|
||||
name: projectName,
|
||||
projectName:
|
||||
isUsingTsSolutionConfig && !options.name ? importPath : projectName,
|
||||
projectRoot,
|
||||
parsedTags,
|
||||
importPath,
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
|
||||
@ -480,6 +480,7 @@ describe('lib', () => {
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
strict: false,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'tsconfig.json').references)
|
||||
@ -622,6 +623,7 @@ describe('lib', () => {
|
||||
...defaultSchema,
|
||||
buildable: true,
|
||||
strict: false,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'my-lib/package.json')).toMatchInlineSnapshot(`
|
||||
@ -652,6 +654,7 @@ describe('lib', () => {
|
||||
...defaultSchema,
|
||||
directory: 'my-lib',
|
||||
name: 'my-lib', // import path contains the npm scope, so it would be different
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -665,6 +668,7 @@ describe('lib', () => {
|
||||
...defaultSchema,
|
||||
directory: 'my-lib',
|
||||
name: '@proj/my-lib',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -674,10 +678,34 @@ describe('lib', () => {
|
||||
it('should not set "nx.name" in package.json when the user does not provide a name', async () => {
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema, // defaultSchema has no name
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'my-lib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await expoLibraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
strict: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
|
||||
expect(appTree.exists('my-lib/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(appTree, '@proj/my-lib'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/my-lib",
|
||||
"projectType": "library",
|
||||
"root": "my-lib",
|
||||
"sourceRoot": "my-lib/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(appTree, 'my-lib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -5,7 +5,6 @@ import {
|
||||
GeneratorCallback,
|
||||
installPackagesTask,
|
||||
joinPathFragments,
|
||||
names,
|
||||
offsetFromRoot,
|
||||
ProjectConfiguration,
|
||||
runTasksInSerial,
|
||||
@ -46,6 +45,7 @@ export async function expoLibraryGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await expoLibraryGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
@ -157,7 +157,7 @@ export async function expoLibraryGeneratorInternal(
|
||||
}
|
||||
|
||||
tasks.push(() => {
|
||||
logShowProjectCommand(options.name);
|
||||
logShowProjectCommand(options.projectName);
|
||||
});
|
||||
|
||||
return runTasksInSerial(...tasks);
|
||||
@ -175,18 +175,24 @@ async function addProject(
|
||||
targets: {},
|
||||
};
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.projectName,
|
||||
let packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
...determineEntryFields(options),
|
||||
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
|
||||
peerDependencies: {
|
||||
react: reactVersion,
|
||||
'react-native': reactNativeVersion,
|
||||
},
|
||||
};
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
packageJson = {
|
||||
...packageJson,
|
||||
...determineEntryFields(options),
|
||||
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
if (options.projectName !== options.importPath) {
|
||||
packageJson.nx = { name: options.projectName };
|
||||
}
|
||||
@ -194,14 +200,21 @@ async function addProject(
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
} else {
|
||||
addProjectConfiguration(host, options.projectName, project);
|
||||
}
|
||||
|
||||
if (
|
||||
!options.useProjectJson ||
|
||||
options.isUsingTsSolutionConfig ||
|
||||
options.publishable ||
|
||||
options.buildable
|
||||
) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.projectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(host, options.name, project);
|
||||
}
|
||||
|
||||
if (options.publishable || options.buildable) {
|
||||
@ -263,7 +276,6 @@ function createFiles(host: Tree, options: NormalizedSchema) {
|
||||
options.projectRoot,
|
||||
{
|
||||
...options,
|
||||
...names(options.name),
|
||||
tmpl: '',
|
||||
offsetFromRoot: offsetFromRoot(options.projectRoot),
|
||||
rootTsConfigPath: getRelativePathToRootTsConfig(
|
||||
|
||||
@ -19,4 +19,5 @@ export interface Schema {
|
||||
setParserOptionsProject?: boolean;
|
||||
skipPackageJson?: boolean; // default is false
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -89,6 +89,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nx/devkit": "file:../devkit",
|
||||
"@nx/js": "file:../js",
|
||||
"@nx/node": "file:../node",
|
||||
"tslib": "^2.3.0"
|
||||
},
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { readJson, Tree, updateJson, writeJson } from '@nx/devkit';
|
||||
import {
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
updateJson,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import { applicationGenerator } from './application';
|
||||
import { Schema } from './schema';
|
||||
@ -158,6 +164,7 @@ describe('app', () => {
|
||||
it('should add project references when using TS solution', async () => {
|
||||
await applicationGenerator(appTree, {
|
||||
directory: 'myapp',
|
||||
useProjectJson: false,
|
||||
} as Schema);
|
||||
|
||||
expect(readJson(appTree, 'tsconfig.json').references)
|
||||
@ -171,9 +178,11 @@ describe('app', () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
const packageJson = readJson(appTree, 'myapp/package.json');
|
||||
expect(packageJson.name).toBe('@proj/myapp');
|
||||
expect(packageJson.nx.name).toBeUndefined();
|
||||
// Make sure keys are in idiomatic order
|
||||
expect(Object.keys(readJson(appTree, 'myapp/package.json')))
|
||||
.toMatchInlineSnapshot(`
|
||||
expect(Object.keys(packageJson)).toMatchInlineSnapshot(`
|
||||
[
|
||||
"name",
|
||||
"version",
|
||||
@ -313,5 +322,100 @@ describe('app', () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should respect the provided name', async () => {
|
||||
await applicationGenerator(appTree, {
|
||||
directory: 'myapp',
|
||||
name: 'myapp',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
const packageJson = readJson(appTree, 'myapp/package.json');
|
||||
expect(packageJson.name).toBe('@proj/myapp');
|
||||
expect(packageJson.nx.name).toBe('myapp');
|
||||
// Make sure keys are in idiomatic order
|
||||
expect(Object.keys(packageJson)).toMatchInlineSnapshot(`
|
||||
[
|
||||
"name",
|
||||
"version",
|
||||
"private",
|
||||
"nx",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await applicationGenerator(appTree, {
|
||||
directory: 'myapp',
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
expect(appTree.exists('myapp/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(appTree, '@proj/myapp'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/myapp",
|
||||
"projectType": "application",
|
||||
"root": "myapp",
|
||||
"sourceRoot": "myapp/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"configurations": {
|
||||
"development": {},
|
||||
"production": {},
|
||||
},
|
||||
"defaultConfiguration": "production",
|
||||
"executor": "@nx/webpack:webpack",
|
||||
"options": {
|
||||
"assets": [
|
||||
"myapp/src/assets",
|
||||
],
|
||||
"compiler": "tsc",
|
||||
"main": "myapp/src/main.ts",
|
||||
"outputPath": "myapp/dist",
|
||||
"target": "node",
|
||||
"tsConfig": "myapp/tsconfig.app.json",
|
||||
"webpackConfig": "myapp/webpack.config.js",
|
||||
},
|
||||
"outputs": [
|
||||
"{options.outputPath}",
|
||||
],
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
},
|
||||
"serve": {
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "@proj/myapp:build:development",
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "@proj/myapp:build:production",
|
||||
},
|
||||
},
|
||||
"defaultConfiguration": "development",
|
||||
"dependsOn": [
|
||||
"build",
|
||||
],
|
||||
"executor": "@nx/js:node",
|
||||
"options": {
|
||||
"buildTarget": "@proj/myapp:build",
|
||||
"runBuildTargetDependencies": false,
|
||||
},
|
||||
},
|
||||
"test": {
|
||||
"options": {
|
||||
"passWithNoTests": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(appTree, 'myapp/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
determineProjectNameAndRootOptions,
|
||||
ensureRootProjectName,
|
||||
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { applicationGenerator as nodeApplicationGenerator } from '@nx/node';
|
||||
import { tslibVersion } from '@nx/node/src/utils/versions';
|
||||
import { join } from 'path';
|
||||
@ -69,6 +70,7 @@ server.on('error', console.error);
|
||||
export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
@ -119,10 +121,14 @@ async function normalizeOptions(
|
||||
nxJson.useInferencePlugins !== false;
|
||||
options.addPlugin ??= addPlugin;
|
||||
|
||||
const useProjectJson =
|
||||
options.useProjectJson ?? !isUsingTsSolutionSetup(host);
|
||||
|
||||
return {
|
||||
...options,
|
||||
appProjectName,
|
||||
appProjectRoot,
|
||||
useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -17,4 +17,5 @@ export interface Schema {
|
||||
standaloneConfig?: boolean;
|
||||
setParserOptionsProject?: boolean;
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -73,6 +73,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -1,4 +1,10 @@
|
||||
import { readJson, updateJson, writeJson, type Tree } from '@nx/devkit';
|
||||
import {
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
updateJson,
|
||||
writeJson,
|
||||
type Tree,
|
||||
} from '@nx/devkit';
|
||||
import * as devkit from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import { applicationGenerator } from './application';
|
||||
@ -193,6 +199,7 @@ describe('application generator', () => {
|
||||
directory: 'myapp',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -330,5 +337,124 @@ describe('application generator', () => {
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it('should respect the provided name', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'myapp',
|
||||
name: 'myapp',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'myapp/package.json');
|
||||
expect(packageJson.name).toBe('@proj/myapp');
|
||||
expect(packageJson.nx.name).toBe('myapp');
|
||||
// Make sure keys are in idiomatic order
|
||||
expect(Object.keys(packageJson)).toMatchInlineSnapshot(`
|
||||
[
|
||||
"name",
|
||||
"version",
|
||||
"private",
|
||||
"nx",
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'myapp',
|
||||
e2eTestRunner: 'jest',
|
||||
useProjectJson: true,
|
||||
addPlugin: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('myapp/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/myapp",
|
||||
"projectType": "application",
|
||||
"root": "myapp",
|
||||
"sourceRoot": "myapp/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"configurations": {
|
||||
"development": {
|
||||
"args": [
|
||||
"node-env=development",
|
||||
],
|
||||
},
|
||||
},
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"args": [
|
||||
"node-env=production",
|
||||
],
|
||||
"command": "webpack-cli build",
|
||||
},
|
||||
},
|
||||
"serve": {
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "@proj/myapp:build:development",
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "@proj/myapp:build:production",
|
||||
},
|
||||
},
|
||||
"defaultConfiguration": "development",
|
||||
"dependsOn": [
|
||||
"build",
|
||||
],
|
||||
"executor": "@nx/js:node",
|
||||
"options": {
|
||||
"buildTarget": "@proj/myapp:build",
|
||||
"runBuildTargetDependencies": false,
|
||||
},
|
||||
},
|
||||
"test": {
|
||||
"options": {
|
||||
"passWithNoTests": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('myapp-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/myapp",
|
||||
],
|
||||
"name": "@proj/myapp-e2e",
|
||||
"projectType": "application",
|
||||
"root": "myapp-e2e",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
"dependsOn": [
|
||||
"@proj/myapp:build",
|
||||
],
|
||||
"executor": "@nx/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "myapp-e2e/jest.config.ts",
|
||||
"passWithNoTests": true,
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage/{e2eProjectRoot}",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -18,6 +18,7 @@ export async function applicationGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...rawOptions,
|
||||
});
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import {
|
||||
ensureRootProjectName,
|
||||
} from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import { Linter } from '@nx/eslint';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import type { Schema as NodeApplicationGeneratorOptions } from '@nx/node/src/generators/application/schema';
|
||||
import type { ApplicationGeneratorOptions, NormalizedOptions } from '../schema';
|
||||
|
||||
@ -35,6 +36,7 @@ export async function normalizeOptions(
|
||||
linter: options.linter ?? Linter.EsLint,
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
e2eTestRunner: options.e2eTestRunner ?? 'jest',
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionSetup(tree),
|
||||
};
|
||||
}
|
||||
|
||||
@ -57,5 +59,6 @@ export function toNodeApplicationGeneratorOptions(
|
||||
bundler: 'webpack', // Some features require webpack plugins such as TS transformers
|
||||
isNest: true,
|
||||
addPlugin: options.addPlugin,
|
||||
useProjectJson: options.useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ export interface ApplicationGeneratorOptions {
|
||||
strict?: boolean;
|
||||
addPlugin?: boolean;
|
||||
useTsSolution?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
interface NormalizedOptions extends ApplicationGeneratorOptions {
|
||||
|
||||
@ -78,6 +78,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Adds strictNullChecks, noImplicitAny, strictBindCallApply, forceConsistentCasingInFileNames and noFallthroughCasesInSwitch to tsconfig.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -58,6 +58,7 @@ export async function normalizeOptions(
|
||||
testEnvironment: options.testEnvironment ?? 'node',
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
isUsingTsSolutionsConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionsConfig,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
@ -82,6 +83,6 @@ export function toJsLibraryGeneratorOptions(
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
setParserOptionsProject: options.setParserOptionsProject,
|
||||
addPlugin: options.addPlugin,
|
||||
useProjectJson: !options.isUsingTsSolutionsConfig,
|
||||
useProjectJson: options.useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
@ -370,6 +370,7 @@ describe('lib', () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -503,6 +504,7 @@ describe('lib', () => {
|
||||
name: 'my-lib', // import path contains the npm scope, so it would be different
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -517,6 +519,7 @@ describe('lib', () => {
|
||||
name: '@proj/my-lib',
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -528,10 +531,48 @@ describe('lib', () => {
|
||||
directory: 'mylib',
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('mylib/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/mylib'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/mylib",
|
||||
"projectType": "library",
|
||||
"root": "mylib",
|
||||
"sourceRoot": "mylib/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
},
|
||||
"test": {
|
||||
"executor": "@nx/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "mylib/jest.config.ts",
|
||||
},
|
||||
"outputs": [
|
||||
"{projectRoot}/test-output/jest/coverage",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -27,6 +27,7 @@ export async function libraryGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await libraryGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...rawOptions,
|
||||
});
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ export interface LibraryGeneratorOptions {
|
||||
simpleName?: boolean;
|
||||
addPlugin?: boolean;
|
||||
isUsingTsSolutionsConfig?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
export interface NormalizedOptions extends LibraryGeneratorOptions {
|
||||
|
||||
@ -133,6 +133,10 @@
|
||||
"description": "Don't include the directory in the name of the module of the library.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
|
||||
@ -872,48 +872,10 @@ describe('app', () => {
|
||||
expect(tsConfigApp.exclude).not.toContain('**/*.spec.js');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('app (legacy)', () => {
|
||||
let tree: Tree;
|
||||
let originalEnv;
|
||||
|
||||
const schema: Schema = {
|
||||
directory: 'app',
|
||||
appDir: true,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
e2eTestRunner: 'cypress',
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
originalEnv = process.env['NX_ADD_PLUGINS'];
|
||||
process.env['NX_ADD_PLUGINS'] = 'false';
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (originalEnv) {
|
||||
process.env['NX_ADD_PLUGINS'] = originalEnv;
|
||||
} else {
|
||||
delete process.env['NX_ADD_PLUGINS'];
|
||||
}
|
||||
});
|
||||
|
||||
it('should generate build and serve targets', async () => {
|
||||
const name = uniq();
|
||||
|
||||
await applicationGenerator(tree, {
|
||||
...schema,
|
||||
name,
|
||||
});
|
||||
|
||||
const projectConfiguration = readProjectConfiguration(tree, name);
|
||||
expect(projectConfiguration.targets.build).toBeDefined();
|
||||
expect(projectConfiguration.targets.serve).toBeDefined();
|
||||
});
|
||||
|
||||
describe('TS solution setup', () => {
|
||||
let tree: Tree;
|
||||
|
||||
beforeEach(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
updateJson(tree, 'package.json', (json) => {
|
||||
@ -935,9 +897,13 @@ describe('app (legacy)', () => {
|
||||
|
||||
it('should add project references when using TS solution', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
...schema,
|
||||
addPlugin: true,
|
||||
directory: 'myapp',
|
||||
appDir: true,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
e2eTestRunner: 'cypress',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -1089,10 +1055,14 @@ describe('app (legacy)', () => {
|
||||
|
||||
it('should respect the provided name', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
...schema,
|
||||
addPlugin: true,
|
||||
directory: 'myapp',
|
||||
name: 'myapp',
|
||||
appDir: true,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
e2eTestRunner: 'cypress',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'myapp/package.json');
|
||||
@ -1109,6 +1079,91 @@ describe('app (legacy)', () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'myapp',
|
||||
appDir: true,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
e2eTestRunner: 'cypress',
|
||||
addPlugin: true,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('myapp/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/myapp",
|
||||
"projectType": "application",
|
||||
"root": "myapp",
|
||||
"sourceRoot": "myapp",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('myapp-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/myapp",
|
||||
],
|
||||
"name": "@proj/myapp-e2e",
|
||||
"projectType": "application",
|
||||
"root": "myapp-e2e",
|
||||
"sourceRoot": "myapp-e2e/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('app (legacy)', () => {
|
||||
let tree: Tree;
|
||||
let originalEnv;
|
||||
|
||||
const schema: Schema = {
|
||||
directory: 'app',
|
||||
appDir: true,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
e2eTestRunner: 'cypress',
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
tree = createTreeWithEmptyWorkspace();
|
||||
originalEnv = process.env['NX_ADD_PLUGINS'];
|
||||
process.env['NX_ADD_PLUGINS'] = 'false';
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
if (originalEnv) {
|
||||
process.env['NX_ADD_PLUGINS'] = originalEnv;
|
||||
} else {
|
||||
delete process.env['NX_ADD_PLUGINS'];
|
||||
}
|
||||
});
|
||||
|
||||
it('should generate build and serve targets', async () => {
|
||||
const name = uniq();
|
||||
|
||||
await applicationGenerator(tree, {
|
||||
...schema,
|
||||
name,
|
||||
});
|
||||
|
||||
const projectConfiguration = readProjectConfiguration(tree, name);
|
||||
expect(projectConfiguration.targets.build).toBeDefined();
|
||||
expect(projectConfiguration.targets.serve).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@ -40,6 +40,7 @@ import { configureForSwc } from '../../utils/add-swc-to-custom-server';
|
||||
export async function applicationGenerator(host: Tree, schema: Schema) {
|
||||
return await applicationGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
@ -6,15 +6,14 @@ import {
|
||||
Tree,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { getE2EWebServerInfo } from '@nx/devkit/src/generators/e2e-web-server-info-utils';
|
||||
import { addE2eCiTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import { findPluginForConfigFile } from '@nx/devkit/src/utils/find-plugin-for-config-file';
|
||||
import { Linter } from '@nx/eslint';
|
||||
|
||||
import { webStaticServeGenerator } from '@nx/web';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
import { nxVersion } from '../../../utils/versions';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
import { webStaticServeGenerator } from '@nx/web';
|
||||
import { findPluginForConfigFile } from '@nx/devkit/src/utils/find-plugin-for-config-file';
|
||||
import { addE2eCiTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import { getE2EWebServerInfo } from '@nx/devkit/src/generators/e2e-web-server-info-utils';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
|
||||
export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
const nxJson = readNxJson(host);
|
||||
@ -45,19 +44,16 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
});
|
||||
}
|
||||
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
root: options.e2eProjectRoot,
|
||||
@ -69,6 +65,14 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(host, {
|
||||
...options,
|
||||
linter: Linter.EsLint,
|
||||
@ -124,19 +128,17 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
const { configurationGenerator } = ensurePackage<
|
||||
typeof import('@nx/playwright')
|
||||
>('@nx/playwright', nxVersion);
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
root: options.e2eProjectRoot,
|
||||
@ -148,6 +150,14 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(host, {
|
||||
rootProject: options.rootProject,
|
||||
project: options.e2eProjectName,
|
||||
|
||||
@ -72,7 +72,6 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
tags: options.parsedTags,
|
||||
};
|
||||
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
@ -84,6 +83,7 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
},
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
if (options.projectName !== options.importPath) {
|
||||
packageJson.nx = { name: options.projectName };
|
||||
}
|
||||
@ -91,15 +91,17 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(host, options.projectName, {
|
||||
...project,
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,5 +97,6 @@ export async function normalizeOptions(
|
||||
unitTestRunner: options.unitTestRunner || 'jest',
|
||||
importPath,
|
||||
isTsSolutionSetup,
|
||||
useProjectJson: options.useProjectJson ?? !isTsSolutionSetup,
|
||||
};
|
||||
}
|
||||
|
||||
@ -22,4 +22,5 @@ export interface Schema {
|
||||
addPlugin?: boolean;
|
||||
useTsSolution?: boolean;
|
||||
formatter?: 'prettier' | 'none';
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -144,6 +144,10 @@
|
||||
"default": false,
|
||||
"hidden": true,
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -32,11 +32,13 @@ export async function normalizeOptions(
|
||||
process.env.NX_ADD_PLUGINS !== 'false' &&
|
||||
nxJson.useInferencePlugins !== false;
|
||||
options.addPlugin ??= addPlugin;
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host);
|
||||
|
||||
return {
|
||||
...options,
|
||||
importPath,
|
||||
projectRoot,
|
||||
isUsingTsSolutionConfig: isUsingTsSolutionSetup(host),
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
||||
};
|
||||
}
|
||||
|
||||
@ -1,5 +1,11 @@
|
||||
import { installedCypressVersion } from '@nx/cypress/src/utils/cypress-version';
|
||||
import { readJson, Tree, updateJson, writeJson } from '@nx/devkit';
|
||||
import {
|
||||
readJson,
|
||||
readProjectConfiguration,
|
||||
Tree,
|
||||
updateJson,
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing';
|
||||
import { Linter } from '@nx/eslint';
|
||||
import libraryGenerator from './library';
|
||||
@ -145,6 +151,7 @@ describe('next library', () => {
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
component: false,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -264,6 +271,7 @@ describe('next library', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
style: 'css',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -279,6 +287,7 @@ describe('next library', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
style: 'css',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -291,10 +300,38 @@ describe('next library', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
style: 'css',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
linter: Linter.EsLint,
|
||||
unitTestRunner: 'jest',
|
||||
style: 'css',
|
||||
addPlugin: true,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('mylib/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/mylib'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/mylib",
|
||||
"projectType": "library",
|
||||
"root": "mylib",
|
||||
"sourceRoot": "mylib/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -28,6 +28,7 @@ import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields
|
||||
export async function libraryGenerator(host: Tree, rawOptions: Schema) {
|
||||
return await libraryGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...rawOptions,
|
||||
});
|
||||
}
|
||||
|
||||
@ -24,4 +24,5 @@ export interface Schema {
|
||||
setParserOptionsProject?: boolean;
|
||||
skipPackageJson?: boolean;
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -158,6 +158,10 @@
|
||||
"default": false,
|
||||
"description": "Do not add dependencies to `package.json`.",
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -587,6 +587,7 @@ describe('app', () => {
|
||||
bundler: 'webpack',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -723,6 +724,7 @@ describe('app', () => {
|
||||
bundler: 'webpack',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'myapp/package.json');
|
||||
@ -743,6 +745,7 @@ describe('app', () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'apps/my-app',
|
||||
swcJest: true,
|
||||
useProjectJson: false,
|
||||
} as Schema);
|
||||
|
||||
expect(tree.read('apps/my-app/jest.config.ts', 'utf-8'))
|
||||
@ -803,6 +806,7 @@ describe('app', () => {
|
||||
directory: 'apps/my-app',
|
||||
bundler: 'webpack',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -837,6 +841,7 @@ describe('app', () => {
|
||||
directory: 'apps/my-app',
|
||||
bundler: 'webpack',
|
||||
addPlugin: false,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -851,6 +856,7 @@ describe('app', () => {
|
||||
directory: 'apps/my-app',
|
||||
bundler: 'esbuild',
|
||||
addPlugin: false,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -859,5 +865,85 @@ describe('app', () => {
|
||||
.outputPath
|
||||
).toBe('apps/my-app/dist');
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'myapp',
|
||||
bundler: 'webpack',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('myapp/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/myapp",
|
||||
"projectType": "application",
|
||||
"root": "myapp",
|
||||
"sourceRoot": "myapp/src",
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"serve": {
|
||||
"configurations": {
|
||||
"development": {
|
||||
"buildTarget": "@proj/myapp:build:development",
|
||||
},
|
||||
"production": {
|
||||
"buildTarget": "@proj/myapp:build:production",
|
||||
},
|
||||
},
|
||||
"defaultConfiguration": "development",
|
||||
"dependsOn": [
|
||||
"build",
|
||||
],
|
||||
"executor": "@nx/js:node",
|
||||
"options": {
|
||||
"buildTarget": "@proj/myapp:build",
|
||||
"runBuildTargetDependencies": false,
|
||||
},
|
||||
},
|
||||
"test": {
|
||||
"options": {
|
||||
"passWithNoTests": true,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('myapp-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/myapp",
|
||||
],
|
||||
"name": "@proj/myapp-e2e",
|
||||
"projectType": "application",
|
||||
"root": "myapp-e2e",
|
||||
"targets": {
|
||||
"e2e": {
|
||||
"dependsOn": [
|
||||
"@proj/myapp:build",
|
||||
],
|
||||
"executor": "@nx/jest:jest",
|
||||
"options": {
|
||||
"jestConfig": "myapp-e2e/jest.config.ts",
|
||||
"passWithNoTests": true,
|
||||
},
|
||||
"outputs": [
|
||||
"{workspaceRoot}/coverage/{e2eProjectRoot}",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -60,6 +60,7 @@ import {
|
||||
updateTsconfigFiles,
|
||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export interface NormalizedSchema extends Omit<Schema, 'useTsSolution'> {
|
||||
appProjectRoot: string;
|
||||
@ -206,17 +207,18 @@ function addProject(tree: Tree, options: NormalizedSchema) {
|
||||
}
|
||||
project.targets.serve = getServeConfig(options);
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
writeJson(tree, joinPathFragments(options.appProjectRoot, 'package.json'), {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
name: options.name !== options.importPath ? options.name : undefined,
|
||||
targets: project.targets,
|
||||
tags: project.tags?.length ? project.tags : undefined,
|
||||
},
|
||||
});
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(
|
||||
tree,
|
||||
@ -225,6 +227,14 @@ function addProject(tree: Tree, options: NormalizedSchema) {
|
||||
options.standaloneConfig
|
||||
);
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function addAppFiles(tree: Tree, options: NormalizedSchema) {
|
||||
@ -435,6 +445,7 @@ function updateTsConfigOptions(tree: Tree, options: NormalizedSchema) {
|
||||
export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
@ -646,6 +657,7 @@ async function normalizeOptions(
|
||||
|
||||
const appProjectName =
|
||||
!isUsingTsSolutionConfig || options.name ? projectName : importPath;
|
||||
const useProjectJson = options.useProjectJson ?? !isUsingTsSolutionConfig;
|
||||
|
||||
return {
|
||||
addPlugin,
|
||||
@ -669,6 +681,7 @@ async function normalizeOptions(
|
||||
),
|
||||
isUsingTsSolutionConfig,
|
||||
swcJest,
|
||||
useProjectJson,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -25,6 +25,7 @@ export interface Schema {
|
||||
isNest?: boolean;
|
||||
addPlugin?: boolean;
|
||||
useTsSolution?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
export type NodeJsFrameWorks = 'express' | 'koa' | 'fastify' | 'nest' | 'none';
|
||||
|
||||
@ -123,6 +123,10 @@
|
||||
"docker": {
|
||||
"type": "boolean",
|
||||
"description": "Add a docker build target"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -173,6 +173,7 @@ describe('e2eProjectGenerator', () => {
|
||||
framework: 'none',
|
||||
e2eTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
await e2eProjectGenerator(tree, {
|
||||
projectType: 'server',
|
||||
@ -214,6 +215,7 @@ describe('e2eProjectGenerator', () => {
|
||||
framework: 'none',
|
||||
e2eTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
await e2eProjectGenerator(tree, {
|
||||
projectType: 'server',
|
||||
@ -282,11 +284,13 @@ describe('e2eProjectGenerator', () => {
|
||||
framework: 'none',
|
||||
e2eTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
await e2eProjectGenerator(tree, {
|
||||
projectType: 'cli',
|
||||
project: '@proj/cli',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(tree.read('cli-e2e/jest.config.ts', 'utf-8'))
|
||||
|
||||
@ -36,10 +36,12 @@ import {
|
||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { relative } from 'node:path/posix';
|
||||
import { addSwcTestConfig } from '@nx/js/src/utils/swc/add-swc-config';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export async function e2eProjectGenerator(host: Tree, options: Schema) {
|
||||
return await e2eProjectGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
@ -51,15 +53,16 @@ export async function e2eProjectGeneratorInternal(
|
||||
const tasks: GeneratorCallback[] = [];
|
||||
const options = await normalizeOptions(host, _options);
|
||||
const appProject = readProjectConfiguration(host, options.project);
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(host);
|
||||
|
||||
// TODO(@ndcunningham): This is broken.. the outputs are wrong.. and this isn't using the jest generator
|
||||
if (isUsingTsSolutionConfig) {
|
||||
writeJson(host, joinPathFragments(options.e2eProjectRoot, 'package.json'), {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
name:
|
||||
options.e2eProjectName !== options.importPath
|
||||
? options.e2eProjectName
|
||||
@ -76,8 +79,7 @@ export async function e2eProjectGeneratorInternal(
|
||||
dependsOn: [`${options.project}:build`],
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
root: options.e2eProjectRoot,
|
||||
@ -96,6 +98,15 @@ export async function e2eProjectGeneratorInternal(
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
// TODO(@nicholas): Find a better way to get build target
|
||||
|
||||
// We remove the 'test' target from the e2e project because it is not needed
|
||||
@ -125,11 +136,11 @@ export async function e2eProjectGeneratorInternal(
|
||||
}
|
||||
|
||||
const jestPreset = findRootJestPreset(host) ?? 'jest.preset.js';
|
||||
const tsConfigFile = isUsingTsSolutionConfig
|
||||
const tsConfigFile = options.isUsingTsSolutionConfig
|
||||
? 'tsconfig.json'
|
||||
: 'tsconfig.spec.json';
|
||||
const rootOffset = offsetFromRoot(options.e2eProjectRoot);
|
||||
const coverageDirectory = isUsingTsSolutionConfig
|
||||
const coverageDirectory = options.isUsingTsSolutionConfig
|
||||
? 'test-output/jest/coverage'
|
||||
: joinPathFragments(rootOffset, 'coverage', options.e2eProjectName);
|
||||
const projectSimpleName = options.project.split('/').pop();
|
||||
@ -145,7 +156,6 @@ export async function e2eProjectGeneratorInternal(
|
||||
offsetFromRoot: rootOffset,
|
||||
jestPreset,
|
||||
coverageDirectory,
|
||||
isUsingTsSolutionConfig,
|
||||
tmpl: '',
|
||||
}
|
||||
);
|
||||
@ -178,13 +188,12 @@ export async function e2eProjectGeneratorInternal(
|
||||
offsetFromRoot: rootOffset,
|
||||
jestPreset,
|
||||
coverageDirectory,
|
||||
isUsingTsSolutionConfig,
|
||||
tmpl: '',
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if (isUsingTsSolutionConfig) {
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
addSwcTestConfig(host, options.e2eProjectRoot, 'es6');
|
||||
generateFiles(
|
||||
host,
|
||||
@ -245,7 +254,7 @@ export async function e2eProjectGeneratorInternal(
|
||||
}
|
||||
}
|
||||
|
||||
if (isUsingTsSolutionConfig) {
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
updateJson(host, 'tsconfig.json', (json) => {
|
||||
json.references ??= [];
|
||||
const e2eRef = `./${options.e2eProjectRoot}`;
|
||||
@ -258,7 +267,7 @@ export async function e2eProjectGeneratorInternal(
|
||||
|
||||
// If we are using the new TS solution
|
||||
// We need to update the workspace file (package.json or pnpm-workspaces.yaml) to include the new project
|
||||
if (isUsingTsSolutionConfig) {
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
await addProjectToTsSolutionWorkspace(host, options.e2eProjectRoot);
|
||||
}
|
||||
|
||||
@ -281,6 +290,7 @@ async function normalizeOptions(
|
||||
e2eProjectRoot: string;
|
||||
e2eProjectName: string;
|
||||
importPath: string;
|
||||
isUsingTsSolutionConfig: boolean;
|
||||
}
|
||||
> {
|
||||
let directory = options.rootProject ? 'e2e' : options.directory;
|
||||
@ -303,6 +313,8 @@ async function normalizeOptions(
|
||||
process.env.NX_ADD_PLUGINS !== 'false' &&
|
||||
nxJson.useInferencePlugins !== false;
|
||||
|
||||
const isUsingTsSolutionConfig = isUsingTsSolutionSetup(tree);
|
||||
|
||||
return {
|
||||
addPlugin,
|
||||
...options,
|
||||
@ -311,6 +323,8 @@ async function normalizeOptions(
|
||||
importPath,
|
||||
port: options.port ?? 3000,
|
||||
rootProject: !!options.rootProject,
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -9,4 +9,5 @@ export interface Schema {
|
||||
isNest?: boolean;
|
||||
skipFormat?: boolean;
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -59,6 +59,10 @@
|
||||
"default": false,
|
||||
"hidden": true,
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["project"]
|
||||
|
||||
@ -545,6 +545,7 @@ describe('lib', () => {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
} as Schema);
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -660,6 +661,7 @@ describe('lib', () => {
|
||||
compiler: 'swc',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
} as Schema);
|
||||
|
||||
expect(readJson(tree, 'mylib/package.json')).toMatchInlineSnapshot(`
|
||||
@ -709,6 +711,7 @@ describe('lib', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
@ -724,6 +727,7 @@ describe('lib', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
@ -736,10 +740,36 @@ describe('lib', () => {
|
||||
linter: 'none',
|
||||
unitTestRunner: 'none',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await libraryGenerator(tree, {
|
||||
directory: 'mylib',
|
||||
unitTestRunner: 'jest',
|
||||
addPlugin: true,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
} as Schema);
|
||||
|
||||
expect(tree.exists('mylib/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/mylib'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/mylib",
|
||||
"projectType": "library",
|
||||
"root": "mylib",
|
||||
"sourceRoot": "mylib/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'mylib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -47,6 +47,7 @@ export interface NormalizedSchema extends Schema {
|
||||
export async function libraryGenerator(tree: Tree, schema: Schema) {
|
||||
return await libraryGeneratorInternal(tree, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
@ -70,6 +71,7 @@ export async function libraryGeneratorInternal(tree: Tree, schema: Schema) {
|
||||
|
||||
// Create `package.json` first because @nx/js:lib generator will update it.
|
||||
if (
|
||||
!options.useProjectJson ||
|
||||
options.isUsingTsSolutionConfig ||
|
||||
options.publishable ||
|
||||
options.buildable
|
||||
@ -78,7 +80,6 @@ export async function libraryGeneratorInternal(tree: Tree, schema: Schema) {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
|
||||
});
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ export async function libraryGeneratorInternal(tree: Tree, schema: Schema) {
|
||||
testEnvironment: 'node',
|
||||
skipFormat: true,
|
||||
setParserOptionsProject: schema.setParserOptionsProject,
|
||||
useProjectJson: !options.isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson,
|
||||
})
|
||||
);
|
||||
|
||||
@ -173,6 +174,7 @@ async function normalizeOptions(
|
||||
parsedTags,
|
||||
importPath,
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -21,4 +21,5 @@ export interface Schema {
|
||||
setParserOptionsProject?: boolean;
|
||||
compiler: 'tsc' | 'swc';
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -123,6 +123,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Whether or not to configure the ESLint `parserOptions.project`. We do not do this by default for lint performance reasons.",
|
||||
"default": false
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
"hidden": true
|
||||
},
|
||||
"application": {
|
||||
"factory": "./src/generators/application/application",
|
||||
"factory": "./src/generators/application/application#applicationGeneratorInternal",
|
||||
"schema": "./src/generators/application/schema.json",
|
||||
"aliases": ["app"],
|
||||
"description": "Create a Nuxt application."
|
||||
|
||||
@ -240,6 +240,7 @@ describe('app', () => {
|
||||
e2eTestRunner: 'playwright',
|
||||
unitTestRunner: 'vitest',
|
||||
linter: 'eslint',
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(tree.read('myapp/vite.config.ts', 'utf-8')).toMatchInlineSnapshot(
|
||||
@ -395,6 +396,7 @@ describe('app', () => {
|
||||
e2eTestRunner: 'playwright',
|
||||
unitTestRunner: 'vitest',
|
||||
linter: 'eslint',
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'myapp/package.json');
|
||||
@ -410,5 +412,46 @@ describe('app', () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await applicationGenerator(tree, {
|
||||
directory: 'myapp',
|
||||
e2eTestRunner: 'playwright',
|
||||
unitTestRunner: 'vitest',
|
||||
linter: 'eslint',
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('myapp/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/myapp",
|
||||
"projectType": "application",
|
||||
"root": "myapp",
|
||||
"sourceRoot": "myapp/src",
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('myapp-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/myapp-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/myapp",
|
||||
],
|
||||
"name": "@proj/myapp-e2e",
|
||||
"projectType": "application",
|
||||
"root": "myapp-e2e",
|
||||
"sourceRoot": "myapp-e2e/src",
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'myapp-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -40,6 +40,13 @@ import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
export async function applicationGeneratorInternal(tree: Tree, schema: Schema) {
|
||||
const tasks: GeneratorCallback[] = [];
|
||||
|
||||
const jsInitTask = await jsInitGenerator(tree, {
|
||||
@ -66,13 +73,13 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
|
||||
tasks.push(ensureDependencies(tree, options));
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
if (options.projectName !== options.importPath) {
|
||||
packageJson.nx = { name: options.projectName };
|
||||
}
|
||||
@ -80,12 +87,6 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(tree, options.projectName, {
|
||||
root: options.appProjectRoot,
|
||||
@ -96,6 +97,14 @@ export async function applicationGenerator(tree: Tree, schema: Schema) {
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
tree,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
generateFiles(
|
||||
tree,
|
||||
joinPathFragments(__dirname, './files/base'),
|
||||
|
||||
@ -11,6 +11,7 @@ import { nxVersion } from '../../../utils/versions';
|
||||
import { NormalizedSchema } from '../schema';
|
||||
import { findPluginForConfigFile } from '@nx/devkit/src/utils/find-plugin-for-config-file';
|
||||
import { addE2eCiTargetDefaults } from '@nx/devkit/src/generators/target-defaults-utils';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
const e2eWebServerInfo = await getNuxtE2EWebServerInfo(
|
||||
@ -25,19 +26,17 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
const { configurationGenerator } = ensurePackage<
|
||||
typeof import('@nx/cypress')
|
||||
>('@nx/cypress', nxVersion);
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
projectType: 'application',
|
||||
@ -48,6 +47,15 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
implicitDependencies: [options.projectName],
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(host, {
|
||||
...options,
|
||||
project: options.e2eProjectName,
|
||||
@ -95,19 +103,17 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
const { configurationGenerator } = ensurePackage<
|
||||
typeof import('@nx/playwright')
|
||||
>('@nx/playwright', nxVersion);
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
{
|
||||
|
||||
const packageJson: PackageJson = {
|
||||
name: options.e2eProjectName,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
nx: {
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson.nx = {
|
||||
implicitDependencies: [options.projectName],
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
} else {
|
||||
addProjectConfiguration(host, options.e2eProjectName, {
|
||||
projectType: 'application',
|
||||
@ -117,6 +123,15 @@ export async function addE2e(host: Tree, options: NormalizedSchema) {
|
||||
implicitDependencies: [options.projectName],
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isUsingTsSolutionConfig) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.e2eProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
}
|
||||
|
||||
const e2eTask = await configurationGenerator(host, {
|
||||
project: options.e2eProjectName,
|
||||
skipFormat: true,
|
||||
|
||||
@ -46,6 +46,7 @@ export async function normalizeOptions(
|
||||
parsedTags,
|
||||
style: options.style ?? 'none',
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
||||
} as NormalizedSchema;
|
||||
|
||||
normalized.unitTestRunner ??= 'vitest';
|
||||
|
||||
@ -16,6 +16,7 @@ export interface Schema {
|
||||
style?: 'css' | 'scss' | 'less' | 'none';
|
||||
nxCloudToken?: string;
|
||||
useTsSolution?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
export interface NormalizedSchema extends Omit<Schema, 'useTsSolution'> {
|
||||
|
||||
@ -106,6 +106,10 @@
|
||||
"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
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"],
|
||||
|
||||
@ -286,6 +286,7 @@ describe('app', () => {
|
||||
unitTestRunner: 'jest',
|
||||
bundler: 'vite',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(tree, 'tsconfig.json').references).toMatchInlineSnapshot(`
|
||||
@ -422,6 +423,7 @@ describe('app', () => {
|
||||
unitTestRunner: 'jest',
|
||||
bundler: 'vite',
|
||||
addPlugin: true,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
const packageJson = readJson(tree, 'my-app/package.json');
|
||||
@ -437,5 +439,51 @@ describe('app', () => {
|
||||
]
|
||||
`);
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await reactNativeApplicationGenerator(tree, {
|
||||
directory: 'my-app',
|
||||
linter: Linter.EsLint,
|
||||
e2eTestRunner: 'cypress',
|
||||
install: false,
|
||||
unitTestRunner: 'jest',
|
||||
bundler: 'vite',
|
||||
addPlugin: true,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(tree.exists('my-app/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/my-app'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/my-app",
|
||||
"projectType": "application",
|
||||
"root": "my-app",
|
||||
"sourceRoot": "my-app/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'my-app/package.json').nx).toBeUndefined();
|
||||
expect(tree.exists('my-app-e2e/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(tree, '@proj/my-app-e2e'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"implicitDependencies": [
|
||||
"@proj/my-app",
|
||||
],
|
||||
"name": "@proj/my-app-e2e",
|
||||
"projectType": "application",
|
||||
"root": "my-app-e2e",
|
||||
"sourceRoot": "my-app-e2e/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(tree, 'my-app-e2e/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -37,6 +37,7 @@ export async function reactNativeApplicationGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await reactNativeApplicationGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
|
||||
@ -8,7 +8,6 @@ import {
|
||||
writeJson,
|
||||
} from '@nx/devkit';
|
||||
import { NormalizedSchema } from './normalize-options';
|
||||
import { isUsingTsSolutionSetup } from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import type { PackageJson } from 'nx/src/utils/package-json';
|
||||
|
||||
export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
@ -27,13 +26,13 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
tags: options.parsedTags,
|
||||
};
|
||||
|
||||
if (isUsingTsSolutionSetup(host)) {
|
||||
const packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
private: true,
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
if (options.projectName !== options.importPath) {
|
||||
packageJson.nx = { name: options.projectName };
|
||||
}
|
||||
@ -45,16 +44,18 @@ export function addProject(host: Tree, options: NormalizedSchema) {
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
} else {
|
||||
addProjectConfiguration(host, options.projectName, {
|
||||
...project,
|
||||
});
|
||||
}
|
||||
|
||||
if (!options.useProjectJson || options.isTsSolutionSetup) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.appProjectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(host, options.projectName, {
|
||||
...project,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -45,6 +45,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -82,6 +83,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'myApp-e2e',
|
||||
e2eProjectRoot: 'myApp-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -120,6 +122,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'directory/my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -157,6 +160,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'directory/my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
|
||||
@ -195,6 +199,7 @@ describe('Normalize Options', () => {
|
||||
e2eProjectName: 'my-app-e2e',
|
||||
e2eProjectRoot: 'my-app-e2e',
|
||||
isTsSolutionSetup: false,
|
||||
useProjectJson: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -80,5 +80,6 @@ export async function normalizeOptions(
|
||||
e2eProjectName,
|
||||
e2eProjectRoot,
|
||||
isTsSolutionSetup,
|
||||
useProjectJson: options.useProjectJson ?? !isTsSolutionSetup,
|
||||
};
|
||||
}
|
||||
|
||||
@ -21,4 +21,5 @@ export interface Schema {
|
||||
nxCloudToken?: string;
|
||||
useTsSolution?: boolean;
|
||||
formatter?: 'prettier' | 'none';
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -95,6 +95,10 @@
|
||||
"x-prompt": "Which bundler do you want to use to build the application?",
|
||||
"default": "vite",
|
||||
"x-priority": "important"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
@ -55,6 +55,7 @@ export async function normalizeOptions(
|
||||
parsedTags,
|
||||
importPath,
|
||||
isUsingTsSolutionConfig,
|
||||
useProjectJson: options.useProjectJson ?? !isUsingTsSolutionConfig,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
|
||||
@ -471,6 +471,7 @@ describe('lib', () => {
|
||||
it('should add project references when using TS solution', async () => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
useProjectJson: false,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'tsconfig.json').references)
|
||||
@ -481,8 +482,11 @@ describe('lib', () => {
|
||||
},
|
||||
]
|
||||
`);
|
||||
const packageJson = readJson(appTree, 'my-lib/package.json');
|
||||
expect(packageJson.name).toBe('@proj/my-lib');
|
||||
expect(packageJson.nx).toBeUndefined();
|
||||
// Make sure keys are in idiomatic order
|
||||
expect(readJson(appTree, 'my-lib/package.json')).toMatchInlineSnapshot(`
|
||||
expect(packageJson).toMatchInlineSnapshot(`
|
||||
{
|
||||
"exports": {
|
||||
".": {
|
||||
@ -600,6 +604,7 @@ describe('lib', () => {
|
||||
...defaultSchema,
|
||||
directory: 'my-lib',
|
||||
name: 'my-lib', // import path contains the npm scope, so it would be different
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -613,6 +618,7 @@ describe('lib', () => {
|
||||
...defaultSchema,
|
||||
directory: 'my-lib',
|
||||
name: '@proj/my-lib',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
@ -623,10 +629,34 @@ describe('lib', () => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
directory: 'my-lib',
|
||||
useProjectJson: false,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(readJson(appTree, 'my-lib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should generate project.json if useProjectJson is true', async () => {
|
||||
await libraryGenerator(appTree, {
|
||||
...defaultSchema,
|
||||
useProjectJson: true,
|
||||
skipFormat: true,
|
||||
});
|
||||
|
||||
expect(appTree.exists('my-lib/project.json')).toBeTruthy();
|
||||
expect(readProjectConfiguration(appTree, '@proj/my-lib'))
|
||||
.toMatchInlineSnapshot(`
|
||||
{
|
||||
"$schema": "../node_modules/nx/schemas/project-schema.json",
|
||||
"name": "@proj/my-lib",
|
||||
"projectType": "library",
|
||||
"root": "my-lib",
|
||||
"sourceRoot": "my-lib/src",
|
||||
"tags": [],
|
||||
"targets": {},
|
||||
}
|
||||
`);
|
||||
expect(readJson(appTree, 'my-lib/package.json').nx).toBeUndefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@ -33,11 +33,6 @@ import {
|
||||
updateTsconfigFiles,
|
||||
} from '@nx/js/src/utils/typescript/ts-solution-setup';
|
||||
import { sortPackageJsonFields } from '@nx/js/src/utils/package-json/sort-fields';
|
||||
import {
|
||||
addReleaseConfigForNonTsSolution,
|
||||
addReleaseConfigForTsSolution,
|
||||
releaseTasks,
|
||||
} from '@nx/js/src/generators/library/utils/add-release-config';
|
||||
import { PackageJson } from 'nx/src/utils/package-json';
|
||||
import { addRollupBuildTarget } from '@nx/react/src/generators/library/lib/add-rollup-build-target';
|
||||
import { getRelativeCwd } from '@nx/devkit/src/generators/artifact-name-and-directory-utils';
|
||||
@ -50,6 +45,7 @@ export async function reactNativeLibraryGenerator(
|
||||
): Promise<GeneratorCallback> {
|
||||
return await reactNativeLibraryGeneratorInternal(host, {
|
||||
addPlugin: false,
|
||||
useProjectJson: true,
|
||||
...schema,
|
||||
});
|
||||
}
|
||||
@ -180,10 +176,14 @@ async function addProject(
|
||||
targets: {},
|
||||
};
|
||||
|
||||
if (options.isUsingTsSolutionConfig) {
|
||||
const packageJson: PackageJson = {
|
||||
let packageJson: PackageJson = {
|
||||
name: options.importPath,
|
||||
version: '0.0.1',
|
||||
};
|
||||
|
||||
if (!options.useProjectJson) {
|
||||
packageJson = {
|
||||
...packageJson,
|
||||
...determineEntryFields(options),
|
||||
files: options.publishable ? ['dist', '!**/*.tsbuildinfo'] : undefined,
|
||||
peerDependencies: {
|
||||
@ -191,7 +191,6 @@ async function addProject(
|
||||
'react-native': reactNativeVersion,
|
||||
},
|
||||
};
|
||||
|
||||
if (options.name !== options.importPath) {
|
||||
packageJson.nx = { name: options.name };
|
||||
}
|
||||
@ -199,14 +198,21 @@ async function addProject(
|
||||
packageJson.nx ??= {};
|
||||
packageJson.nx.tags = options.parsedTags;
|
||||
}
|
||||
} else {
|
||||
addProjectConfiguration(host, options.name, project);
|
||||
}
|
||||
|
||||
if (
|
||||
!options.useProjectJson ||
|
||||
options.isUsingTsSolutionConfig ||
|
||||
options.publishable ||
|
||||
options.buildable
|
||||
) {
|
||||
writeJson(
|
||||
host,
|
||||
joinPathFragments(options.projectRoot, 'package.json'),
|
||||
packageJson
|
||||
);
|
||||
} else {
|
||||
addProjectConfiguration(host, options.name, project);
|
||||
}
|
||||
|
||||
if (options.publishable || options.buildable) {
|
||||
|
||||
@ -19,4 +19,5 @@ export interface Schema {
|
||||
setParserOptionsProject?: boolean;
|
||||
skipPackageJson?: boolean; //default is false
|
||||
addPlugin?: boolean;
|
||||
useProjectJson?: boolean;
|
||||
}
|
||||
|
||||
@ -93,6 +93,10 @@
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"x-priority": "internal"
|
||||
},
|
||||
"useProjectJson": {
|
||||
"type": "boolean",
|
||||
"description": "Use a `project.json` configuration file instead of inlining the Nx configuration in the `package.json` file."
|
||||
}
|
||||
},
|
||||
"required": ["directory"]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user