diff --git a/docs/shared/concepts/how-caching-works.md b/docs/shared/concepts/how-caching-works.md index 54d8998672..98f0d33e9d 100644 --- a/docs/shared/concepts/how-caching-works.md +++ b/docs/shared/concepts/how-caching-works.md @@ -59,14 +59,14 @@ We can define a more precise configuration as follows: { "namedInputs": { "default": ["{projectRoot}/**/*"], - "prod": ["!{projectRoot}/**/*.spec.tsx"] + "production": ["!{projectRoot}/**/*.spec.tsx"] }, "targetDefaults": { "build": { - "inputs": ["prod", "^prod"] + "inputs": ["production", "^production"] }, "test": { - "inputs": ["default", "^prod", "{workspaceRoot}/jest.config.ts"] + "inputs": ["default", "^production", "{workspaceRoot}/jest.config.ts"] } } } diff --git a/docs/shared/reference/nx-json.md b/docs/shared/reference/nx-json.md index 21a5eab54f..605e0d5d27 100644 --- a/docs/shared/reference/nx-json.md +++ b/docs/shared/reference/nx-json.md @@ -25,11 +25,11 @@ The following is an expanded version showing all options. Your `nx.json` will li }, "namedInputs": { "default": ["{projectRoot}/**/*"], - "prod": ["!{projectRoot}/**/*.spec.tsx"] + "production": ["!{projectRoot}/**/*.spec.tsx"] }, "targetDefaults": { "build": { - "inputs": ["prod", "^prod"], + "inputs": ["production", "^production"], "dependsOn": ["^build"] } }, @@ -127,7 +127,7 @@ like this (which applies to every project): "test": { "inputs": [ "default", - "^prod" + "^production" ] } ``` @@ -137,7 +137,10 @@ And projects can define their prod fileset, without having to redefine the input ```json title="project.json" { "namedInputs": { - "prod": ["!{projectRoot}/**/*.test.js", "{workspacRoot}/jest.config.js"] + "production": [ + "!{projectRoot}/**/*.test.js", + "{workspacRoot}/jest.config.js" + ] } } ``` diff --git a/docs/shared/reference/project-configuration.md b/docs/shared/reference/project-configuration.md index 4c14e5b4a0..177aeef24f 100644 --- a/docs/shared/reference/project-configuration.md +++ b/docs/shared/reference/project-configuration.md @@ -64,18 +64,18 @@ You can add Nx-specific configuration as follows: "default": [ "{projectRoot}/**/*" ], - "prod": [ + "production": [ "!{projectRoot}/**/*.spec.tsx" ] }, "targets": { "build": { - "inputs": ["prod", "^prod"], + "inputs": ["production", "^production"], "outputs": ["dist/libs/mylib"], "dependsOn": ["^build"] }, "test": { - "inputs": ["default", "^prod"], + "inputs": ["default", "^production"], "outputs": [], "dependsOn": ["build"] } @@ -94,19 +94,19 @@ You can add Nx-specific configuration as follows: "projectType": "library", "namedInputs": { "default": ["{projectRoot}/**/*"], - "prod": ["!{projectRoot}/**/*.spec.tsx"] + "production": ["!{projectRoot}/**/*.spec.tsx"] }, "targets": { "test": { "executor": "@nrwl/jest:jest", - "inputs": ["default", "^prod"], + "inputs": ["default", "^production"], "outputs": [], "dependsOn": ["build"], "options": {} }, "build": { "executor": "@nrwl/js:tsc", - "inputs": ["prod", "^prod"], + "inputs": ["production", "^production"], "outputs": ["dist/libs/mylib"], "dependsOn": ["^build"], "options": {} @@ -154,8 +154,8 @@ _Named Inputs_ Examples: -- `inputs: ["prod"]` -- same as `inputs: [{input: "prod", projects: "self"}]` +- `inputs: ["production"]` +- same as `inputs: [{input: "production", projects: "self"}]` Often the same glob will appear in many places (e.g., prod fileset will exclude spec files for all projects). Because keeping them in sync is error-prone, we recommend defining named inputs, which you can then reference in all of those @@ -165,15 +165,15 @@ places. Examples: -- `inputs: ["^prod"]` -- same as `inputs: [{input: "prod", projects: "dependencies"}]` +- `inputs: ["^production"]` +- same as `inputs: [{input: "production", projects: "dependencies"}]` Similar to `dependsOn`, the "^" symbols means "dependencies". This is a very important idea, so let's illustrate it with an example. ``` "test": { - "inputs": [ "default", "^prod" ] + "inputs": [ "default", "^production" ] } ``` diff --git a/nx.json b/nx.json index 6edd21f9eb..3621fdaf5a 100644 --- a/nx.json +++ b/nx.json @@ -30,19 +30,22 @@ }, "namedInputs": { "default": ["{projectRoot}/**/*"], - "prod": ["!{projectRoot}/**/*.spec.ts{,.snap}"] + "production": [ + "default", + "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)" + ] }, "targetDefaults": { "build": { "dependsOn": ["build-base"], - "inputs": ["prod", "^prod"] + "inputs": ["production", "^production"] }, "build-base": { "dependsOn": ["^build-base"], - "inputs": ["prod", "^prod"] + "inputs": ["production", "^production"] }, "test": { - "inputs": ["default", "^prod", "{workspaceRoot}/jest.config.ts"] + "inputs": ["default", "^production", "{workspaceRoot}/jest.preset.js"] }, "lint": { "inputs": [ @@ -54,7 +57,7 @@ "e2e": { "inputs": [ "default", - "^prod", + "^production", { "env": "SELECTED_CLI" }, diff --git a/packages/angular/src/generators/karma/karma.spec.ts b/packages/angular/src/generators/karma/karma.spec.ts index f1637a494b..f97ef4511e 100644 --- a/packages/angular/src/generators/karma/karma.spec.ts +++ b/packages/angular/src/generators/karma/karma.spec.ts @@ -1,12 +1,13 @@ import * as devkit from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { karmaGenerator } from './karma'; +import { NxJsonConfiguration, readJson, updateJson } from '@nrwl/devkit'; describe('karma', () => { let tree: devkit.Tree; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); it('should do nothing when karma is already installed and karma.conf.js exists', () => { @@ -57,4 +58,27 @@ describe('karma', () => { expect(tree.exists('karma.conf.js')).toBeTruthy(); }); + + it('should add inputs for test targets', () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs ??= {}; + json.namedInputs.production = ['default', '^production']; + return json; + }); + karmaGenerator(tree, {}); + + const nxJson = readJson(tree, 'nx.json'); + expect(nxJson.namedInputs.production).toContain( + '!{projectRoot}/karma.conf.js' + ); + expect(nxJson.namedInputs.production).toContain( + '!{projectRoot}/tsconfig.spec.json' + ); + expect(nxJson.namedInputs.production).toContain( + '!{projectRoot}/**/*.spec.[jt]s' + ); + expect(nxJson.targetDefaults.test).toEqual({ + inputs: ['default', '^production', '{workspaceRoot}/karma.conf.js'], + }); + }); }); diff --git a/packages/angular/src/generators/karma/karma.ts b/packages/angular/src/generators/karma/karma.ts index 16e421c208..8f9717e520 100644 --- a/packages/angular/src/generators/karma/karma.ts +++ b/packages/angular/src/generators/karma/karma.ts @@ -4,6 +4,8 @@ import { generateFiles, joinPathFragments, readJson, + readWorkspaceConfiguration, + updateWorkspaceConfiguration, } from '@nrwl/devkit'; import { jasmineCoreVersion, @@ -18,6 +20,39 @@ import { } from '../../utils/versions'; import { GeneratorOptions } from './schema'; +function addTestInputs(tree: Tree) { + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + const productionFileSet = workspaceConfiguration.namedInputs?.production; + if (productionFileSet) { + productionFileSet.push( + // Exclude spec files from production fileset + '!{projectRoot}/**/*.spec.[jt]s', + // Remove tsconfig.spec.json + '!{projectRoot}/tsconfig.spec.json', + // Remove karma.conf.js + '!{projectRoot}/karma.conf.js' + ); + // Dedupe and set + workspaceConfiguration.namedInputs.production = Array.from( + new Set(productionFileSet) + ); + } + + // Test targets depend on all their project's sources + production sources of dependencies + workspaceConfiguration.targetDefaults ??= {}; + workspaceConfiguration.targetDefaults.test ??= {}; + workspaceConfiguration.targetDefaults.test.inputs ??= [ + 'default', + productionFileSet ? '^production' : '^default', + ]; + workspaceConfiguration.targetDefaults.test.inputs.push( + '{workspaceRoot}/karma.conf.js' + ); + + updateWorkspaceConfiguration(tree, workspaceConfiguration); +} + export function karmaGenerator(tree: Tree, options: GeneratorOptions) { const packageJson = readJson(tree, 'package.json'); @@ -25,11 +60,14 @@ export function karmaGenerator(tree: Tree, options: GeneratorOptions) { generateFiles(tree, joinPathFragments(__dirname, 'files'), '.', { tmpl: '', }); + + addTestInputs(tree); } if (options.skipPackageJson || packageJson.devDependencies['karma']) { return () => {}; } + return addDependenciesToPackageJson( tree, {}, diff --git a/packages/angular/src/generators/ng-add/__snapshots__/migrate-from-angular-cli.spec.ts.snap b/packages/angular/src/generators/ng-add/__snapshots__/migrate-from-angular-cli.spec.ts.snap index 46ca8be7a9..93c10fffe1 100644 --- a/packages/angular/src/generators/ng-add/__snapshots__/migrate-from-angular-cli.spec.ts.snap +++ b/packages/angular/src/generators/ng-add/__snapshots__/migrate-from-angular-cli.spec.ts.snap @@ -176,6 +176,12 @@ Object { "^build", ], }, + "lint": Object { + "inputs": Array [ + "default", + "{workspaceRoot}/.eslintrc.json", + ], + }, }, "tasksRunnerOptions": Object { "default": Object { diff --git a/packages/cypress/src/generators/init/init.spec.ts b/packages/cypress/src/generators/init/init.spec.ts index 839365489d..c1bd389088 100644 --- a/packages/cypress/src/generators/init/init.spec.ts +++ b/packages/cypress/src/generators/init/init.spec.ts @@ -1,5 +1,5 @@ -import { readJson, Tree, updateJson } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { NxJsonConfiguration, readJson, Tree, updateJson } from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { cypressVersion } from '../../utils/versions'; import { cypressInitGenerator } from './init'; @@ -8,7 +8,7 @@ describe('init', () => { let tree: Tree; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); it('should add dependencies into `package.json` file', async () => { @@ -31,4 +31,20 @@ describe('init', () => { expect(packageJson.dependencies['@nrwl/cypress']).toBeUndefined(); expect(packageJson.dependencies[existing]).toBeDefined(); }); + + it('should setup e2e target defaults', async () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs ??= {}; + json.namedInputs.production = ['default']; + return json; + }); + + cypressInitGenerator(tree, {}); + + expect( + readJson(tree, 'nx.json').targetDefaults.e2e + ).toEqual({ + inputs: ['default', '^production'], + }); + }); }); diff --git a/packages/cypress/src/generators/init/init.ts b/packages/cypress/src/generators/init/init.ts index 05cb27e5db..7025647dbd 100644 --- a/packages/cypress/src/generators/init/init.ts +++ b/packages/cypress/src/generators/init/init.ts @@ -1,8 +1,10 @@ import { addDependenciesToPackageJson, convertNxGenerator, + readWorkspaceConfiguration, removeDependenciesFromPackageJson, Tree, + updateWorkspaceConfiguration, } from '@nrwl/devkit'; import { cypressVersion, @@ -11,11 +13,27 @@ import { } from '../../utils/versions'; import { Schema } from './schema'; -function updateDependencies(host: Tree) { - removeDependenciesFromPackageJson(host, ['@nrwl/cypress'], []); +function setupE2ETargetDefaults(tree: Tree) { + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + // E2e targets depend on all their project's sources + production sources of dependencies + workspaceConfiguration.targetDefaults ??= {}; + + const productionFileSet = !!workspaceConfiguration.namedInputs?.production; + workspaceConfiguration.targetDefaults.e2e ??= {}; + workspaceConfiguration.targetDefaults.e2e.inputs ??= [ + 'default', + productionFileSet ? '^production' : '^default', + ]; + + updateWorkspaceConfiguration(tree, workspaceConfiguration); +} + +function updateDependencies(tree: Tree) { + removeDependenciesFromPackageJson(tree, ['@nrwl/cypress'], []); return addDependenciesToPackageJson( - host, + tree, {}, { ['@nrwl/cypress']: nxVersion, @@ -25,8 +43,9 @@ function updateDependencies(host: Tree) { ); } -export function cypressInitGenerator(host: Tree, options: Schema) { - return !options.skipPackageJson ? updateDependencies(host) : () => {}; +export function cypressInitGenerator(tree: Tree, options: Schema) { + setupE2ETargetDefaults(tree); + return !options.skipPackageJson ? updateDependencies(tree) : () => {}; } export default cypressInitGenerator; diff --git a/packages/jest/preset/jest-preset.ts b/packages/jest/preset/jest-preset.ts index 1c9c2c5bc1..1c692da1c1 100644 --- a/packages/jest/preset/jest-preset.ts +++ b/packages/jest/preset/jest-preset.ts @@ -1,5 +1,6 @@ export const nxPreset = { - testMatch: ['**/+(*.)+(spec|test).+(ts|js)?(x)'], + // This is one of the patterns that jest finds by default https://jestjs.io/docs/configuration#testmatch-arraystring + testMatch: ['**/?(*.)+(spec|test).[jt]s?(x)'], resolver: '@nrwl/jest/plugins/resolver', moduleFileExtensions: ['ts', 'js', 'mjs', 'html'], coverageReporters: ['html'], diff --git a/packages/jest/src/generators/init/init.spec.ts b/packages/jest/src/generators/init/init.spec.ts index 4e39b37c63..a23e8e300f 100644 --- a/packages/jest/src/generators/init/init.spec.ts +++ b/packages/jest/src/generators/init/init.spec.ts @@ -1,4 +1,11 @@ -import { readJson, stripIndents, Tree, writeJson } from '@nrwl/devkit'; +import { + NxJsonConfiguration, + readJson, + stripIndents, + Tree, + updateJson, + writeJson, +} from '@nrwl/devkit'; import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; import { jestInitGenerator } from './init'; @@ -39,6 +46,61 @@ describe('jest', () => { expect(tree.read('jest.config.ts', 'utf-8')).toEqual('test'); }); + it('should add target defaults for test', async () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs ??= {}; + json.namedInputs.production = ['default']; + return json; + }); + + jestInitGenerator(tree, {}); + + const productionFileSet = readJson(tree, 'nx.json') + .namedInputs.production; + const testDefaults = readJson(tree, 'nx.json') + .targetDefaults.test; + expect(productionFileSet).toContain( + '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)' + ); + expect(productionFileSet).toContain('!{projectRoot}/tsconfig.spec.json'); + expect(productionFileSet).toContain('!{projectRoot}/jest.config.[jt]s'); + expect(testDefaults).toEqual({ + inputs: ['default', '^production', '{workspaceRoot}/jest.preset.js'], + }); + }); + + it('should not alter target defaults if jest.preset.js already exists', async () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs ??= {}; + json.namedInputs.production = ['default', '^production']; + return json; + }); + + jestInitGenerator(tree, {}); + + let nxJson: NxJsonConfiguration; + updateJson(tree, 'nx.json', (json) => { + json.namedInputs.production = [ + 'default', + '^production', + '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)', + '!{projectRoot}/**/*.md', + ]; + json.targetDefaults.test = { + inputs: [ + 'default', + '^production', + '{workspaceRoot}/jest.preset.js', + '{workspaceRoot}/testSetup.ts', + ], + }; + nxJson = json; + return json; + }); + jestInitGenerator(tree, {}); + expect(readJson(tree, 'nx.json')).toEqual(nxJson); + }); + it('should add dependencies', async () => { jestInitGenerator(tree, {}); const packageJson = readJson(tree, 'package.json'); diff --git a/packages/jest/src/generators/init/init.ts b/packages/jest/src/generators/init/init.ts index d7bcb6b9a8..87692a383b 100644 --- a/packages/jest/src/generators/init/init.ts +++ b/packages/jest/src/generators/init/init.ts @@ -2,10 +2,12 @@ import { addDependenciesToPackageJson, convertNxGenerator, GeneratorCallback, + readWorkspaceConfiguration, removeDependenciesFromPackageJson, stripIndents, Tree, updateJson, + updateWorkspaceConfiguration, } from '@nrwl/devkit'; import { babelJestVersion, @@ -26,9 +28,9 @@ const schemaDefaults = { js: false, } as const; -function createJestConfig(host: Tree, js: boolean = false) { +function createJestConfig(tree: Tree, js: boolean = false) { // if the root ts config already exists then don't make a js one or vice versa - if (!host.exists('jest.config.ts') && !host.exists('jest.config.js')) { + if (!tree.exists('jest.config.ts') && !tree.exists('jest.config.js')) { const contents = js ? stripIndents` const { getJestProjects } = require('@nrwl/jest'); @@ -42,21 +44,57 @@ function createJestConfig(host: Tree, js: boolean = false) { export default { projects: getJestProjects() };`; - host.write(`jest.config.${js ? 'js' : 'ts'}`, contents); + tree.write(`jest.config.${js ? 'js' : 'ts'}`, contents); } - if (!host.exists('jest.preset.js')) { + if (!tree.exists('jest.preset.js')) { // preset is always js file. - host.write( + tree.write( `jest.preset.js`, ` const nxPreset = require('@nrwl/jest/preset').default; module.exports = { ...nxPreset }` ); + + addTestInputs(tree); } } +function addTestInputs(tree: Tree) { + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + const productionFileSet = workspaceConfiguration.namedInputs?.production; + if (productionFileSet) { + // This is one of the patterns in the default jest patterns + productionFileSet.push( + // Remove spec, test, and snapshots from the production fileset + '!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)', + // Remove tsconfig.spec.json + '!{projectRoot}/tsconfig.spec.json', + // Remove jest.config.js/ts + '!{projectRoot}/jest.config.[jt]s' + ); + // Dedupe and set + workspaceConfiguration.namedInputs.production = Array.from( + new Set(productionFileSet) + ); + } + + // Test targets depend on all their project's sources + production sources of dependencies + workspaceConfiguration.targetDefaults ??= {}; + workspaceConfiguration.targetDefaults.test ??= {}; + workspaceConfiguration.targetDefaults.test.inputs ??= [ + 'default', + productionFileSet ? '^production' : '^default', + ]; + workspaceConfiguration.targetDefaults.test.inputs.push( + '{workspaceRoot}/jest.preset.js' + ); + + updateWorkspaceConfiguration(tree, workspaceConfiguration); +} + function updateDependencies(tree: Tree, options: NormalizedSchema) { const dependencies = { tslib: tslibVersion, diff --git a/packages/linter/src/generators/init/init.spec.ts b/packages/linter/src/generators/init/init.spec.ts index 984bfdb301..a2281f0d97 100644 --- a/packages/linter/src/generators/init/init.spec.ts +++ b/packages/linter/src/generators/init/init.spec.ts @@ -1,13 +1,13 @@ import { Linter } from '../utils/linter'; -import { Tree } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { readJson, Tree } from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { lintInitGenerator } from './init'; describe('@nrwl/linter:init', () => { let tree: Tree; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); describe('--linter', () => { @@ -20,6 +20,16 @@ describe('@nrwl/linter:init', () => { expect(tree.read('.eslintrc.json', 'utf-8')).toMatchSnapshot(); }); + it('should add the root eslint config to the lint targetDefaults for lint', async () => { + await lintInitGenerator(tree, { + linter: Linter.EsLint, + }); + + expect(readJson(tree, 'nx.json').targetDefaults.lint).toEqual({ + inputs: ['default', '{workspaceRoot}/.eslintrc.json'], + }); + }); + it('should not generate the global eslint config if it already exist', async () => { tree.write('.eslintrc.js', '{}'); diff --git a/packages/linter/src/generators/init/init.ts b/packages/linter/src/generators/init/init.ts index 8f39e70593..b4db914407 100644 --- a/packages/linter/src/generators/init/init.ts +++ b/packages/linter/src/generators/init/init.ts @@ -1,8 +1,10 @@ import type { GeneratorCallback, Tree } from '@nrwl/devkit'; import { addDependenciesToPackageJson, + readWorkspaceConfiguration, removeDependenciesFromPackageJson, updateJson, + updateWorkspaceConfiguration, writeJson, } from '@nrwl/devkit'; import { @@ -15,7 +17,7 @@ import { } from '../../utils/versions'; import { Linter } from '../utils/linter'; -import { containsEslint } from '../utils/eslint-file'; +import { findEslintFile } from '../utils/eslint-file'; import { ESLint } from 'eslint'; export interface LinterInitOptions { @@ -180,8 +182,31 @@ function initTsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback { : () => {}; } +function addTargetDefaults(tree: Tree) { + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + const productionFileSet = workspaceConfiguration.namedInputs?.production; + if (productionFileSet) { + // Remove .eslintrc.json + productionFileSet.push('!{projectRoot}/.eslintrc.json'); + // Dedupe and set + workspaceConfiguration.namedInputs.production = Array.from( + new Set(productionFileSet) + ); + } + + workspaceConfiguration.targetDefaults ??= {}; + + workspaceConfiguration.targetDefaults.lint ??= {}; + workspaceConfiguration.targetDefaults.lint.inputs ??= [ + 'default', + `{workspaceRoot}/.eslintrc.json`, + ]; + updateWorkspaceConfiguration(tree, workspaceConfiguration); +} + function initEsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback { - if (containsEslint(tree)) { + if (findEslintFile(tree)) { return () => {}; } @@ -194,6 +219,7 @@ function initEsLint(tree: Tree, options: LinterInitOptions): GeneratorCallback { '.eslintrc.json', getGlobalEsLintConfiguration(options.unitTestRunner) ); + addTargetDefaults(tree); if (tree.exists('.vscode/extensions.json')) { updateJson(tree, '.vscode/extensions.json', (json) => { diff --git a/packages/linter/src/generators/lint-project/lint-project.ts b/packages/linter/src/generators/lint-project/lint-project.ts index bea245a3d9..83839f770b 100644 --- a/packages/linter/src/generators/lint-project/lint-project.ts +++ b/packages/linter/src/generators/lint-project/lint-project.ts @@ -42,8 +42,11 @@ function createEsLintConfiguration( projectConfig: ProjectConfiguration, setParserOptionsProject: boolean ) { + const eslintConfig = findEslintFile(tree); writeJson(tree, join(projectConfig.root, `.eslintrc.json`), { - extends: [`${offsetFromRoot(projectConfig.root)}${findEslintFile(tree)}`], + extends: eslintConfig + ? [`${offsetFromRoot(projectConfig.root)}${eslintConfig}`] + : undefined, // Include project files to be linted since the global one excludes all files. ignorePatterns: ['!**/*'], overrides: [ diff --git a/packages/linter/src/generators/utils/eslint-file.spec.ts b/packages/linter/src/generators/utils/eslint-file.spec.ts index bd936229ce..78fd172402 100644 --- a/packages/linter/src/generators/utils/eslint-file.spec.ts +++ b/packages/linter/src/generators/utils/eslint-file.spec.ts @@ -1,4 +1,4 @@ -import { containsEslint, findEslintFile } from './eslint-file'; +import { findEslintFile } from './eslint-file'; import { Tree } from '@nrwl/devkit'; import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; @@ -10,30 +10,9 @@ describe('@nrwl/linter:eslint-file', () => { tree = createTreeWithEmptyV1Workspace(); }); - describe('containsEslint', () => { - it('should return false when calling containsEslint without a eslint config', () => { - expect(containsEslint(tree)).toBe(false); - }); - - it('should return true when calling containsEslint with a .eslintrc.json config', () => { - tree.write('.eslintrc.json', '{}'); - expect(containsEslint(tree)).toBe(true); - }); - - it('should return true when calling containsEslint with a .eslintrc.js config', () => { - tree.write('.eslintrc.js', '{}'); - expect(containsEslint(tree)).toBe(true); - }); - - it('should return false when calling containsEslint witn an incorrect eslint file name', () => { - tree.write('.eslintrc.yaml', '{}'); - expect(containsEslint(tree)).toBe(false); - }); - }); - describe('findEslintFile', () => { - it('should return default name when calling findEslintFile when no eslint is found', () => { - expect(findEslintFile(tree)).toBe('.eslintrc.json'); + it('should return null when calling findEslintFile when no eslint is found', () => { + expect(findEslintFile(tree)).toBe(null); }); it('should return the name of the eslint config when calling findEslintFile', () => { @@ -49,7 +28,7 @@ describe('@nrwl/linter:eslint-file', () => { it('should return default name when calling findEslintFile when no eslint is found', () => { tree.write('.eslintrc.yaml', '{}'); - expect(findEslintFile(tree)).toBe('.eslintrc.json'); + expect(findEslintFile(tree)).toBe(null); }); }); }); diff --git a/packages/linter/src/generators/utils/eslint-file.ts b/packages/linter/src/generators/utils/eslint-file.ts index 43b4ddecb7..b48b4f7fe5 100644 --- a/packages/linter/src/generators/utils/eslint-file.ts +++ b/packages/linter/src/generators/utils/eslint-file.ts @@ -2,21 +2,11 @@ import type { Tree } from '@nrwl/devkit'; const eslintFileList = ['.eslintrc.json', '.eslintrc.js']; -export function containsEslint(tree: Tree): boolean { - for (const file of eslintFileList) { - if (tree.exists(file)) { - return true; - } - } - return false; -} - -export function findEslintFile(tree: Tree): string { +export function findEslintFile(tree: Tree): string | null { for (const file of eslintFileList) { if (tree.exists(file)) { return file; } } - // Default file - return '.eslintrc.json'; + return null; } diff --git a/packages/linter/src/generators/workspace-rule/workspace-rule.spec.ts b/packages/linter/src/generators/workspace-rule/workspace-rule.spec.ts index b41eadf1be..89a9be5a8d 100644 --- a/packages/linter/src/generators/workspace-rule/workspace-rule.spec.ts +++ b/packages/linter/src/generators/workspace-rule/workspace-rule.spec.ts @@ -1,12 +1,12 @@ -import { Tree } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { NxJsonConfiguration, readJson, Tree } from '@nrwl/devkit'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { lintWorkspaceRuleGenerator } from './workspace-rule'; describe('@nrwl/linter:workspace-rule', () => { let tree: Tree; beforeEach(async () => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); it('should generate the required files', async () => { diff --git a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.spec.ts b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.spec.ts index 0039b358a1..bebac35632 100644 --- a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.spec.ts +++ b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.spec.ts @@ -1,10 +1,12 @@ import { addProjectConfiguration, + NxJsonConfiguration, readJson, readProjectConfiguration, Tree, + updateJson, } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { lintWorkspaceRulesProjectGenerator, WORKSPACE_RULES_PROJECT_NAME, @@ -14,22 +16,23 @@ describe('@nrwl/linter:workspace-rules-project', () => { let tree: Tree; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); - it('should update implicitDependencies in nx.json', async () => { - expect( - readJson(tree, 'nx.json').implicitDependencies - ).toMatchInlineSnapshot(`undefined`); - + it('should add lint project files to lint inputs', async () => { + updateJson(tree, 'nx.json', (json) => { + json.targetDefaults = { + lint: { + inputs: ['default', '{workspaceRoot}/.eslintrc.json'], + }, + }; + return json; + }); await lintWorkspaceRulesProjectGenerator(tree); - expect(readJson(tree, 'nx.json').implicitDependencies) - .toMatchInlineSnapshot(` - Object { - "tools/eslint-rules/**/*": "*", - } - `); + expect( + readJson(tree, 'nx.json').targetDefaults.lint.inputs + ).toContain('{workspaceRoot}/tools/eslint-rules/**/*'); }); it('should generate the required files', async () => { @@ -72,6 +75,7 @@ describe('@nrwl/linter:workspace-rules-project', () => { expect(readProjectConfiguration(tree, WORKSPACE_RULES_PROJECT_NAME)) .toMatchInlineSnapshot(` Object { + "$schema": "../../node_modules/nx/schemas/project-schema.json", "root": "tools/eslint-rules", "sourceRoot": "tools/eslint-rules", "targets": Object { diff --git a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts index 2fcf5c3341..0a212ce109 100644 --- a/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts +++ b/packages/linter/src/generators/workspace-rules-project/workspace-rules-project.ts @@ -47,13 +47,14 @@ export async function lintWorkspaceRulesProjectGenerator(tree: Tree) { * TODO: Explore writing a ProjectGraph plugin to make this more surgical. */ const workspaceConfig = readWorkspaceConfiguration(tree); - updateWorkspaceConfiguration(tree, { - ...workspaceConfig, - implicitDependencies: { - ...workspaceConfig.implicitDependencies, - [`${WORKSPACE_PLUGIN_DIR}/**/*`]: '*', - }, - }); + + if (workspaceConfig.targetDefaults?.lint?.inputs) { + workspaceConfig.targetDefaults.lint.inputs.push( + `{workspaceRoot}/${WORKSPACE_PLUGIN_DIR}/**/*` + ); + + updateWorkspaceConfiguration(tree, workspaceConfig); + } // Add jest to the project and return installation task const installTask = await jestProjectGenerator(tree, { diff --git a/packages/react-native/src/generators/init/init.spec.ts b/packages/react-native/src/generators/init/init.spec.ts index e4f0e585af..1af24307a8 100644 --- a/packages/react-native/src/generators/init/init.spec.ts +++ b/packages/react-native/src/generators/init/init.spec.ts @@ -1,4 +1,4 @@ -import { logger } from '@nrwl/devkit'; +import { NxJsonConfiguration } from '@nrwl/devkit'; import { Tree, readJson, updateJson } from '@nrwl/devkit'; import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; import { reactNativeInitGenerator } from './init'; @@ -38,11 +38,23 @@ describe('init', () => { describe('babel config', () => { it('should create babel config if not present', async () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs = { + sharedGlobals: ['{workspaceRoot}/exiting-file.json'], + }; + return json; + }); + await reactNativeInitGenerator(tree, { unitTestRunner: 'none', e2eTestRunner: 'none', }); + expect(tree.exists('babel.config.json')).toBe(true); + const sharedGloabls = readJson(tree, 'nx.json') + .namedInputs.sharedGlobals; + expect(sharedGloabls).toContain('{workspaceRoot}/exiting-file.json'); + expect(sharedGloabls).toContain('{workspaceRoot}/babel.config.json'); }); it('should not overwrite existing babel config', async () => { diff --git a/packages/react-native/src/generators/init/lib/init-root-babel-config.ts b/packages/react-native/src/generators/init/lib/init-root-babel-config.ts index a3f079a2ce..4b836f344c 100644 --- a/packages/react-native/src/generators/init/lib/init-root-babel-config.ts +++ b/packages/react-native/src/generators/init/lib/init-root-babel-config.ts @@ -1,4 +1,9 @@ -import { Tree, writeJson } from '@nrwl/devkit'; +import { + readWorkspaceConfiguration, + Tree, + updateWorkspaceConfiguration, + writeJson, +} from '@nrwl/devkit'; export function initRootBabelConfig(tree: Tree) { if (tree.exists('/babel.config.json') || tree.exists('/babel.config.js')) { @@ -8,4 +13,13 @@ export function initRootBabelConfig(tree: Tree) { writeJson(tree, '/babel.config.json', { babelrcRoots: ['*'], // Make sure .babelrc files other than root can be loaded in a monorepo }); + + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + if (workspaceConfiguration.namedInputs?.sharedGlobals) { + workspaceConfiguration.namedInputs.sharedGlobals.push( + '{workspaceRoot}/babel.config.json' + ); + } + updateWorkspaceConfiguration(tree, workspaceConfiguration); } diff --git a/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap b/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap index 85c92caf11..fe7f89089e 100644 --- a/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap +++ b/packages/storybook/src/generators/configuration/__snapshots__/configuration.spec.ts.snap @@ -39,7 +39,46 @@ Object { "affected": Object { "defaultBase": "main", }, + "namedInputs": Object { + "production": Array [ + "default", + "!{projectRoot}/.eslintrc.json", + "!{projectRoot}/**/?(*.)+(spec|test).[jt]s?(x)?(.snap)", + "!{projectRoot}/tsconfig.spec.json", + "!{projectRoot}/jest.config.[jt]s", + "!{projectRoot}/.storybook/**/*", + "!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)", + ], + }, "npmScope": "proj", + "targetDefaults": Object { + "build-storybook": Object { + "inputs": Array [ + "default", + "^production", + "{workspaceRoot}/.storybook/**/*", + ], + }, + "e2e": Object { + "inputs": Array [ + "default", + "^production", + ], + }, + "lint": Object { + "inputs": Array [ + "default", + "{workspaceRoot}/.eslintrc.json", + ], + }, + "test": Object { + "inputs": Array [ + "default", + "^production", + "{workspaceRoot}/jest.preset.js", + ], + }, + }, "tasksRunnerOptions": Object { "default": Object { "options": Object { diff --git a/packages/storybook/src/generators/configuration/configuration.spec.ts b/packages/storybook/src/generators/configuration/configuration.spec.ts index 62d841ed3d..6e04d06ccf 100644 --- a/packages/storybook/src/generators/configuration/configuration.spec.ts +++ b/packages/storybook/src/generators/configuration/configuration.spec.ts @@ -1,11 +1,12 @@ import { + NxJsonConfiguration, readJson, readProjectConfiguration, Tree, updateJson, writeJson, } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { Linter } from '@nrwl/linter'; import { libraryGenerator } from '@nrwl/workspace/generators'; @@ -18,7 +19,13 @@ describe('@nrwl/storybook:configuration', () => { let tree: Tree; beforeEach(async () => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); + updateJson(tree, 'nx.json', (json) => { + json.namedInputs = { + production: ['default'], + }; + return json; + }); await libraryGenerator(tree, { name: 'test-ui-lib', standaloneConfig: false, @@ -425,7 +432,7 @@ describe('@nrwl/storybook:configuration', () => { describe('for js Storybook configurations', () => { let tree: Tree; beforeAll(async () => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); writeJson(tree, 'workspace.json', workspaceConfiguration); writeJson(tree, 'apps/nxapp/tsconfig.json', {}); writeJson(tree, 'apps/reapp/tsconfig.json', {}); @@ -523,7 +530,7 @@ describe('@nrwl/storybook:configuration', () => { describe('for TypeScript Storybook configurations', () => { let tree: Tree; beforeAll(async () => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); writeJson(tree, 'workspace.json', workspaceConfiguration); writeJson(tree, 'apps/nxapp/tsconfig.json', {}); writeJson(tree, 'apps/reapp/tsconfig.json', {}); diff --git a/packages/storybook/src/generators/configuration/util-functions.ts b/packages/storybook/src/generators/configuration/util-functions.ts index f49997d7d3..6bd13ea9af 100644 --- a/packages/storybook/src/generators/configuration/util-functions.ts +++ b/packages/storybook/src/generators/configuration/util-functions.ts @@ -5,10 +5,12 @@ import { offsetFromRoot, readJson, readProjectConfiguration, + readWorkspaceConfiguration, toJS, Tree, updateJson, updateProjectConfiguration, + updateWorkspaceConfiguration, writeJson, } from '@nrwl/devkit'; import { Linter } from '@nrwl/linter'; @@ -263,6 +265,31 @@ export function createRootStorybookDir( rootTsConfigPath: getRootTsConfigPathInTree(tree), }); + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + const hasProductionFileset = !!workspaceConfiguration.namedInputs?.production; + if (hasProductionFileset) { + workspaceConfiguration.namedInputs.production.push( + '!{projectRoot}/.storybook/**/*' + ); + workspaceConfiguration.namedInputs.production.push( + '!{projectRoot}/**/*.stories.@(js|jsx|ts|tsx|mdx)' + ); + } + + workspaceConfiguration.targetDefaults ??= {}; + workspaceConfiguration.targetDefaults['build-storybook'] ??= {}; + workspaceConfiguration.targetDefaults['build-storybook'].inputs ??= [ + 'default', + hasProductionFileset ? '^production' : '^default', + ]; + + workspaceConfiguration.targetDefaults['build-storybook'].inputs.push( + '{workspaceRoot}/.storybook/**/*' + ); + + updateWorkspaceConfiguration(tree, workspaceConfiguration); + if (js) { toJS(tree); } diff --git a/packages/web/src/generators/init/init.spec.ts b/packages/web/src/generators/init/init.spec.ts index ea505c5582..787ec81e30 100644 --- a/packages/web/src/generators/init/init.spec.ts +++ b/packages/web/src/generators/init/init.spec.ts @@ -5,7 +5,7 @@ import { Tree, updateJson, } from '@nrwl/devkit'; -import { createTreeWithEmptyV1Workspace } from '@nrwl/devkit/testing'; +import { createTreeWithEmptyWorkspace } from '@nrwl/devkit/testing'; import { nxVersion } from '../../utils/versions'; @@ -15,7 +15,7 @@ describe('init', () => { let tree: Tree; beforeEach(() => { - tree = createTreeWithEmptyV1Workspace(); + tree = createTreeWithEmptyWorkspace(); }); it('should add web dependencies', async () => { @@ -48,10 +48,22 @@ describe('init', () => { describe('babel config', () => { it('should create babel config if not present', async () => { + updateJson(tree, 'nx.json', (json) => { + json.namedInputs = { + sharedGlobals: ['{workspaceRoot}/exiting-file.json'], + }; + return json; + }); + await webInitGenerator(tree, { unitTestRunner: 'none', }); + expect(tree.exists('babel.config.json')).toBe(true); + const sharedGloabls = readJson(tree, 'nx.json') + .namedInputs.sharedGlobals; + expect(sharedGloabls).toContain('{workspaceRoot}/exiting-file.json'); + expect(sharedGloabls).toContain('{workspaceRoot}/babel.config.json'); }); it('should not overwrite existing babel config', async () => { diff --git a/packages/web/src/generators/init/init.ts b/packages/web/src/generators/init/init.ts index 21d1de243e..8c03ac7aef 100644 --- a/packages/web/src/generators/init/init.ts +++ b/packages/web/src/generators/init/init.ts @@ -4,8 +4,10 @@ import { convertNxGenerator, formatFiles, GeneratorCallback, + readWorkspaceConfiguration, removeDependenciesFromPackageJson, Tree, + updateWorkspaceConfiguration, writeJson, } from '@nrwl/devkit'; import { jestInitGenerator } from '@nrwl/jest'; @@ -42,6 +44,15 @@ function initRootBabelConfig(tree: Tree) { writeJson(tree, '/babel.config.json', { babelrcRoots: ['*'], // Make sure .babelrc files other than root can be loaded in a monorepo }); + + const workspaceConfiguration = readWorkspaceConfiguration(tree); + + if (workspaceConfiguration.namedInputs?.sharedGlobals) { + workspaceConfiguration.namedInputs.sharedGlobals.push( + '{workspaceRoot}/babel.config.json' + ); + } + updateWorkspaceConfiguration(tree, workspaceConfiguration); } export async function webInitGenerator(tree: Tree, schema: Schema) { diff --git a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap index 06132c4e07..7daa1c15ac 100644 --- a/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap +++ b/packages/workspace/src/generators/new/__snapshots__/new.spec.ts.snap @@ -75,12 +75,15 @@ Object { "affected": Object { "defaultBase": "main", }, - "implicitDependencies": Object { - ".eslintrc.json": "*", - "package.json": Object { - "dependencies": "*", - "devDependencies": "*", - }, + "namedInputs": Object { + "default": Array [ + "{projectRoot}/**/*", + "sharedGlobals", + ], + "production": Array [ + "default", + ], + "sharedGlobals": Array [], }, "npmScope": "npmScope", "targetDefaults": Object { @@ -88,6 +91,10 @@ Object { "dependsOn": Array [ "^build", ], + "inputs": Array [ + "production", + "^production", + ], }, }, "tasksRunnerOptions": Object { diff --git a/packages/workspace/src/generators/workspace/files/nx.json__tmpl__ b/packages/workspace/src/generators/workspace/files/nx.json__tmpl__ deleted file mode 100644 index 76914de804..0000000000 --- a/packages/workspace/src/generators/workspace/files/nx.json__tmpl__ +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "./node_modules/nx/schemas/nx-schema.json", - "npmScope": "<%= npmScope %>", - "affected": { - "defaultBase": "<%= defaultBase %>" - }, -<% if (packageManager && cli === 'angular') { -%> - "cli": { - "packageManager": "<%=packageManager%>" - }, -<% } -%> - "implicitDependencies": { - "package.json": { - "dependencies": "*", - "devDependencies": "*" - }, - ".eslintrc.json": "*" - }, - "tasksRunnerOptions": { - "default": { - "runner": "nx/tasks-runners/default", - "options": { - "cacheableOperations": ["build", "lint", "test", "e2e"] - } - } - }, - "targetDefaults": { - "build": { - "dependsOn": ["^build"] - } - } -} diff --git a/packages/workspace/src/generators/workspace/schema.d.ts b/packages/workspace/src/generators/workspace/schema.d.ts index 10398c15a7..9690c6e02c 100644 --- a/packages/workspace/src/generators/workspace/schema.d.ts +++ b/packages/workspace/src/generators/workspace/schema.d.ts @@ -1,3 +1,5 @@ +import { PackageManager } from '@nrwl/devkit'; + export interface Schema { name: string; directory: string; @@ -9,5 +11,5 @@ export interface Schema { cli: 'nx' | 'angular'; preset: string; defaultBase: string; - packageManager?: string; + packageManager?: PackageManager; } diff --git a/packages/workspace/src/generators/workspace/workspace.spec.ts b/packages/workspace/src/generators/workspace/workspace.spec.ts index 18049d6afe..57d94b4a2c 100644 --- a/packages/workspace/src/generators/workspace/workspace.spec.ts +++ b/packages/workspace/src/generators/workspace/workspace.spec.ts @@ -45,13 +45,6 @@ describe('@nrwl/workspace:workspace', () => { affected: { defaultBase: 'main', }, - implicitDependencies: { - 'package.json': { - dependencies: '*', - devDependencies: '*', - }, - '.eslintrc.json': '*', - }, tasksRunnerOptions: { default: { runner: 'nx/tasks-runners/default', @@ -60,11 +53,6 @@ describe('@nrwl/workspace:workspace', () => { }, }, }, - targetDefaults: { - build: { - dependsOn: ['^build'], - }, - }, }); const validateNxJson = ajv.compile(nxSchema); expect(validateNxJson(nxJson)).toEqual(true); @@ -79,6 +67,43 @@ describe('@nrwl/workspace:workspace', () => { expect(validateWorkspaceJson(workspaceJson)).toEqual(true); }); + it('should setup named inputs and target defaults for non-empty presets', async () => { + await workspaceGenerator(tree, { + name: 'proj', + directory: 'proj', + cli: 'nx', + preset: Preset.React, + defaultBase: 'main', + }); + const nxJson = readJson(tree, '/proj/nx.json'); + expect(nxJson).toEqual({ + $schema: './node_modules/nx/schemas/nx-schema.json', + npmScope: 'proj', + affected: { + defaultBase: 'main', + }, + tasksRunnerOptions: { + default: { + runner: 'nx/tasks-runners/default', + options: { + cacheableOperations: ['build', 'lint', 'test', 'e2e'], + }, + }, + }, + namedInputs: { + default: ['{projectRoot}/**/*', 'sharedGlobals'], + production: ['default'], + sharedGlobals: [], + }, + targetDefaults: { + build: { + dependsOn: ['^build'], + inputs: ['production', '^production'], + }, + }, + }); + }); + it('should create a prettierrc file', async () => { await workspaceGenerator(tree, { name: 'proj', diff --git a/packages/workspace/src/generators/workspace/workspace.ts b/packages/workspace/src/generators/workspace/workspace.ts index f307f2b893..502022de2a 100644 --- a/packages/workspace/src/generators/workspace/workspace.ts +++ b/packages/workspace/src/generators/workspace/workspace.ts @@ -8,6 +8,7 @@ import { formatFiles, getPackageManagerVersion, PackageManager, + NxJsonConfiguration, } from '@nrwl/devkit'; import { Schema } from './schema'; import { @@ -59,8 +60,54 @@ function createAppsAndLibsFolders(host: Tree, options: Schema) { } } +function createNxJson( + host: Tree, + { directory, npmScope, cli, packageManager, defaultBase, preset }: Schema +) { + const nxJson: NxJsonConfiguration & { $schema: string } = { + $schema: './node_modules/nx/schemas/nx-schema.json', + npmScope: npmScope, + affected: { + defaultBase, + }, + tasksRunnerOptions: { + default: { + runner: 'nx/tasks-runners/default', + options: { + cacheableOperations: ['build', 'lint', 'test', 'e2e'], + }, + }, + }, + }; + + if ( + preset !== Preset.Core && + preset !== Preset.NPM && + preset !== Preset.Empty + ) { + nxJson.namedInputs = { + default: ['{projectRoot}/**/*', 'sharedGlobals'], + production: ['default'], + sharedGlobals: [], + }; + nxJson.targetDefaults = { + build: { + dependsOn: ['^build'], + inputs: ['production', '^production'], + }, + }; + } + + if (packageManager && cli === 'angular') { + nxJson.cli = { + packageManager: packageManager, + }; + } + + writeJson(host, join(directory, 'nx.json'), nxJson); +} + function createFiles(host: Tree, options: Schema) { - const npmScope = options.npmScope ?? options.name; const formattedNames = names(options.name); generateFiles(host, pathJoin(__dirname, './files'), options.directory, { formattedNames, @@ -75,7 +122,6 @@ function createFiles(host: Tree, options: Schema) { angularCliVersion, ...(options as object), nxVersion, - npmScope, packageManager: options.packageManager, }); } @@ -157,6 +203,7 @@ export async function workspaceGenerator(host: Tree, options: Schema) { } options = normalizeOptions(options); createFiles(host, options); + createNxJson(host, options); createPrettierrc(host, options); if (options.cli === 'angular') { decorateAngularClI(host, options); @@ -193,6 +240,7 @@ function addPropertyWithStableKeys(obj: any, key: string, value: string) { function normalizeOptions(options: Schema) { let defaultBase = options.defaultBase || deduceDefaultBase(); return { + npmScope: options.name, ...options, defaultBase, }; diff --git a/scripts/nx-release.ts b/scripts/nx-release.ts index 0a10bb881f..8d7966bd85 100755 --- a/scripts/nx-release.ts +++ b/scripts/nx-release.ts @@ -1,7 +1,7 @@ #!/usr/bin/env node import * as yargs from 'yargs'; import { execSync } from 'child_process'; -import { readFileSync, writeFileSync } from 'fs'; +import { existsSync, readFileSync, writeFileSync } from 'fs'; import { URL } from 'url'; import { join } from 'path'; @@ -75,7 +75,8 @@ function hideFromGitIndex(uncommittedFiles: string[]) { const uncommittedFiles = execSync('git diff --name-only --relative HEAD .') .toString() .split('\n') - .filter((i) => i.length > 0); + .filter((i) => i.length > 0) + .filter((f) => existsSync(f)); const unhideFromGitIndex = hideFromGitIndex(uncommittedFiles); process.on('exit', unhideFromGitIndex);