feat(core): make nx.json optional

This commit is contained in:
Victor Savkin 2022-05-31 11:01:57 -04:00
parent b35e3836c2
commit e491c6f738
156 changed files with 711 additions and 1479 deletions

View File

@ -89,7 +89,7 @@
} }
}, },
"serve": { "serve": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": [], "outputs": [],
"options": { "options": {
"commands": [ "commands": [
@ -113,7 +113,7 @@
} }
}, },
"serve-for-e2e": { "serve-for-e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": [], "outputs": [],
"options": { "options": {
"commands": [ "commands": [

View File

@ -0,0 +1,16 @@
---
title: 'init - CLI command'
description: 'Adds nx.json file and installs nx if not installed already'
---
# init
Adds nx.json file and installs nx if not installed already
## Usage
```bash
nx init
```
[Install `nx` globally](/getting-started/nx-setup#install-nx) to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpx nx`.

View File

@ -76,12 +76,12 @@ It only uses language primitives and immutable objects
- [NxAffectedConfig](../../devkit/index#nxaffectedconfig) - [NxAffectedConfig](../../devkit/index#nxaffectedconfig)
- [NxJsonConfiguration](../../devkit/index#nxjsonconfiguration) - [NxJsonConfiguration](../../devkit/index#nxjsonconfiguration)
- [ProjectConfiguration](../../devkit/index#projectconfiguration) - [ProjectConfiguration](../../devkit/index#projectconfiguration)
- [ProjectsConfigurations](../../devkit/index#projectsconfigurations)
- [TargetConfiguration](../../devkit/index#targetconfiguration) - [TargetConfiguration](../../devkit/index#targetconfiguration)
- [TargetDependencyConfig](../../devkit/index#targetdependencyconfig) - [TargetDependencyConfig](../../devkit/index#targetdependencyconfig)
- [Task](../../devkit/index#task) - [Task](../../devkit/index#task)
- [TaskGraph](../../devkit/index#taskgraph) - [TaskGraph](../../devkit/index#taskgraph)
- [Workspace](../../devkit/index#workspace) - [Workspace](../../devkit/index#workspace)
- [WorkspaceJsonConfiguration](../../devkit/index#workspacejsonconfiguration)
### Generators Type aliases ### Generators Type aliases
@ -112,6 +112,7 @@ It only uses language primitives and immutable objects
- [ImplicitDependencyEntry](../../devkit/index#implicitdependencyentry) - [ImplicitDependencyEntry](../../devkit/index#implicitdependencyentry)
- [ProjectType](../../devkit/index#projecttype) - [ProjectType](../../devkit/index#projecttype)
- [TaskGraphExecutor](../../devkit/index#taskgraphexecutor) - [TaskGraphExecutor](../../devkit/index#taskgraphexecutor)
- [WorkspaceJsonConfiguration](../../devkit/index#workspacejsonconfiguration)
### Logger Variables ### Logger Variables
@ -151,6 +152,7 @@ It only uses language primitives and immutable objects
- [offsetFromRoot](../../devkit/index#offsetfromroot) - [offsetFromRoot](../../devkit/index#offsetfromroot)
- [parseJson](../../devkit/index#parsejson) - [parseJson](../../devkit/index#parsejson)
- [parseTargetString](../../devkit/index#parsetargetstring) - [parseTargetString](../../devkit/index#parsetargetstring)
- [readAllWorkspaceConfiguration](../../devkit/index#readallworkspaceconfiguration)
- [readCachedProjectGraph](../../devkit/index#readcachedprojectgraph) - [readCachedProjectGraph](../../devkit/index#readcachedprojectgraph)
- [readJson](../../devkit/index#readjson) - [readJson](../../devkit/index#readjson)
- [readJsonFile](../../devkit/index#readjsonfile) - [readJsonFile](../../devkit/index#readjsonfile)
@ -424,6 +426,12 @@ A plugin for Nx
--- ---
### ProjectsConfigurations
**ProjectsConfigurations**: `Object`
---
### TargetConfiguration ### TargetConfiguration
**TargetConfiguration**: `Object` **TargetConfiguration**: `Object`
@ -452,17 +460,11 @@ A plugin for Nx
**Workspace**: `Object` **Workspace**: `Object`
---
### WorkspaceJsonConfiguration
**WorkspaceJsonConfiguration**: `Object`
## Generators Type aliases ## Generators Type aliases
### WorkspaceConfiguration ### WorkspaceConfiguration
Ƭ **WorkspaceConfiguration**: `Omit`<[`WorkspaceJsonConfiguration`](../../devkit/index#workspacejsonconfiguration), `"projects"`\> & `Partial`<[`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)\> Ƭ **WorkspaceConfiguration**: `Omit`<[`ProjectsConfigurations`](../../devkit/index#projectsconfigurations), `"projects"`\> & `Partial`<[`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)\>
--- ---
@ -666,6 +668,12 @@ Implementation of a target of a project that handles multiple projects to be bat
`Promise`<`Record`<`string`, `Object`\>\> `Promise`<`Record`<`string`, `Object`\>\>
---
### WorkspaceJsonConfiguration
Ƭ **WorkspaceJsonConfiguration**: [`ProjectsConfigurations`](../../devkit/index#projectsconfigurations)
## Logger Variables ## Logger Variables
### logger ### logger
@ -689,7 +697,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### appRootPath ### appRootPath
**appRootPath**: `string` **appRootPath**: `string` = `workspaceRoot`
--- ---
@ -707,7 +715,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### workspaceRoot ### workspaceRoot
**workspaceRoot**: `string` = `appRootPath` **workspaceRoot**: `string`
## Functions ## Functions
@ -1357,6 +1365,16 @@ parseTargetString('proj:test:production'); // returns { project: "proj", target:
--- ---
### readAllWorkspaceConfiguration
**readAllWorkspaceConfiguration**(): [`ProjectsConfigurations`](../../devkit/index#projectsconfigurations) & [`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)
#### Returns
[`ProjectsConfigurations`](../../devkit/index#projectsconfigurations) & [`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)
---
### readCachedProjectGraph ### readCachedProjectGraph
**readCachedProjectGraph**(): [`ProjectGraph`](../../devkit/index#projectgraph) **readCachedProjectGraph**(): [`ProjectGraph`](../../devkit/index#projectgraph)
@ -1426,17 +1444,7 @@ Object the JSON content of the file represents
### readNxJson ### readNxJson
**readNxJson**(`path?`): [`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration) **readNxJson**(): [`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)
Returns the contents of nx.json.
If nx.json extends another config file, it will be inlined here.
#### Parameters
| Name | Type |
| :----- | :------- |
| `path` | `string` |
#### Returns #### Returns

View File

@ -11,6 +11,12 @@
"file": "generated/cli/create-nx-workspace", "file": "generated/cli/create-nx-workspace",
"content": "---\ntitle: 'create-nx-workspace - CLI command'\ndescription: 'Create a new Nx workspace'\n---\n\n# create-nx-workspace\n\nCreate a new Nx workspace\n\n## Usage\n\n```bash\ncreate-nx-workspace [name] [options]\n```\n\nInstall `create-nx-workspace` globally to invoke the command directly, or use `npx create-nx-workspace`, `yarn create nx-workspace`, or `pnpx create-nx-workspace`.\n\n## Options\n\n### allPrompts\n\nType: boolean\n\nDefault: false\n\nShow all prompts\n\n### appName\n\nType: string\n\nThe name of the application when a preset with pregenerated app is selected\n\n### ci\n\nType: string\n\nChoices: [github, circleci, azure]\n\nGenerate a CI workflow file\n\n### cli\n\nType: string\n\nChoices: [nx, angular]\n\nCLI to power the Nx workspace\n\n### defaultBase\n\nType: string\n\nDefault: main\n\nDefault base to use for new projects\n\n### help\n\nType: boolean\n\nShow help\n\n### interactive\n\nType: boolean\n\nEnable interactive mode with presets\n\n### name\n\nType: string\n\nWorkspace name (e.g. org name)\n\n### nxCloud\n\nType: boolean\n\nUse Nx Cloud\n\n### packageManager\n\nType: string\n\nChoices: [npm, pnpm, yarn]\n\nDefault: npm\n\nPackage manager to use\n\n### preset\n\nType: string\n\nCustomizes the initial content of your workspace. Default presets include: [\"apps\", \"empty\", \"core\", \"npm\", \"ts\", \"web-components\", \"angular\", \"angular-nest\", \"react\", \"react-express\", \"react-native\", \"next\", \"nest\", \"express\"]. To build your own see https://nx.dev/packages/nx-plugin#preset\n\n### style\n\nType: string\n\nStyle option to be used when a preset with pregenerated app is selected\n\n### version\n\nType: boolean\n\nShow version number\n" "content": "---\ntitle: 'create-nx-workspace - CLI command'\ndescription: 'Create a new Nx workspace'\n---\n\n# create-nx-workspace\n\nCreate a new Nx workspace\n\n## Usage\n\n```bash\ncreate-nx-workspace [name] [options]\n```\n\nInstall `create-nx-workspace` globally to invoke the command directly, or use `npx create-nx-workspace`, `yarn create nx-workspace`, or `pnpx create-nx-workspace`.\n\n## Options\n\n### allPrompts\n\nType: boolean\n\nDefault: false\n\nShow all prompts\n\n### appName\n\nType: string\n\nThe name of the application when a preset with pregenerated app is selected\n\n### ci\n\nType: string\n\nChoices: [github, circleci, azure]\n\nGenerate a CI workflow file\n\n### cli\n\nType: string\n\nChoices: [nx, angular]\n\nCLI to power the Nx workspace\n\n### defaultBase\n\nType: string\n\nDefault: main\n\nDefault base to use for new projects\n\n### help\n\nType: boolean\n\nShow help\n\n### interactive\n\nType: boolean\n\nEnable interactive mode with presets\n\n### name\n\nType: string\n\nWorkspace name (e.g. org name)\n\n### nxCloud\n\nType: boolean\n\nUse Nx Cloud\n\n### packageManager\n\nType: string\n\nChoices: [npm, pnpm, yarn]\n\nDefault: npm\n\nPackage manager to use\n\n### preset\n\nType: string\n\nCustomizes the initial content of your workspace. Default presets include: [\"apps\", \"empty\", \"core\", \"npm\", \"ts\", \"web-components\", \"angular\", \"angular-nest\", \"react\", \"react-express\", \"react-native\", \"next\", \"nest\", \"express\"]. To build your own see https://nx.dev/packages/nx-plugin#preset\n\n### style\n\nType: string\n\nStyle option to be used when a preset with pregenerated app is selected\n\n### version\n\nType: boolean\n\nShow version number\n"
}, },
{
"name": "init",
"id": "init",
"file": "generated/cli/init",
"content": "---\ntitle: 'init - CLI command'\ndescription: 'Adds nx.json file and installs nx if not installed already'\n---\n\n# init\n\nAdds nx.json file and installs nx if not installed already\n\n## Usage\n\n```bash\nnx init\n```\n\n[Install `nx` globally](/getting-started/nx-setup#install-nx) to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpx nx`.\n"
},
{ {
"name": "generate", "name": "generate",
"id": "generate", "id": "generate",

File diff suppressed because one or more lines are too long

View File

@ -870,6 +870,7 @@
"id": "create-nx-workspace", "id": "create-nx-workspace",
"file": "generated/cli/create-nx-workspace" "file": "generated/cli/create-nx-workspace"
}, },
{ "name": "init", "id": "init", "file": "generated/cli/init" },
{ {
"name": "generate", "name": "generate",
"id": "generate", "id": "generate",

View File

@ -42,7 +42,6 @@ package.json
```json ```json
{ {
"extends": "nx/presets/core.json", "extends": "nx/presets/core.json",
"npmScope": "myorg",
"tasksRunnerOptions": { "tasksRunnerOptions": {
"default": { "default": {
"runner": "nx/tasks-runners/default", "runner": "nx/tasks-runners/default",

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -23,12 +23,20 @@ describe('add-nx-to-monorepo', () => {
'packages/package-a/package.json', 'packages/package-a/package.json',
JSON.stringify({ JSON.stringify({
name: 'package-a', name: 'package-a',
scripts: {
serve: 'some serve',
build: 'some build',
test: 'some test',
},
}) })
); );
updateFile( updateFile(
'packages/package-b/package.json', 'packages/package-b/package.json',
JSON.stringify({ JSON.stringify({
name: 'package-b', name: 'package-b',
scripts: {
lint: 'some lint',
},
}) })
); );
@ -40,6 +48,13 @@ describe('add-nx-to-monorepo', () => {
expect(output).toContain('🎉 Done!'); expect(output).toContain('🎉 Done!');
expect(readWorkspaceConfig().projects['package-a']).toBeTruthy(); expect(readWorkspaceConfig().projects['package-a']).toBeTruthy();
expect(readWorkspaceConfig().projects['package-b']).toBeTruthy(); expect(readWorkspaceConfig().projects['package-b']).toBeTruthy();
expect(readWorkspaceConfig().targetDependencies).toEqual({
build: [{ projects: 'dependencies', target: 'build' }],
});
expect(
readWorkspaceConfig().tasksRunnerOptions['default'].options
.cacheableOperations
).toEqual(['build', 'test', 'lint']);
} }
}); });

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -0,0 +1,10 @@
export default {
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'html'],
maxWorkers: 1,
globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json' } },
displayName: 'e2e-nx-init',
preset: '../../jest.preset.js',
};

34
e2e/nx-init/project.json Normal file
View File

@ -0,0 +1,34 @@
{
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "e2e/nx-init",
"projectType": "application",
"targets": {
"e2e": {
"executor": "nx:run-commands",
"options": {
"commands": [
{
"command": "yarn e2e-start-local-registry"
},
{
"command": "yarn e2e-build-package-publish"
},
{
"command": "nx run-e2e-tests e2e-nx-init"
}
],
"parallel": false
}
},
"run-e2e-tests": {
"executor": "@nrwl/jest:jest",
"options": {
"jestConfig": "e2e/nx-init/jest.config.ts",
"passWithNoTests": true,
"runInBand": true
},
"outputs": ["coverage/e2e/nx-init"]
}
},
"implicitDependencies": ["nx"]
}

View File

@ -0,0 +1,37 @@
import {
createNonNxProjectDirectory,
getPackageManagerCommand,
getSelectedPackageManager,
renameFile,
runCLI,
runCommand,
updateFile,
} from '@nrwl/e2e/utils';
describe('nx init', () => {
const packageManagerCommand = getPackageManagerCommand({
packageManager: getSelectedPackageManager(),
}).runUninstalledPackage;
it('should work', () => {
createNonNxProjectDirectory();
updateFile(
'packages/package/package.json',
JSON.stringify({
name: 'package',
scripts: {
echo: 'echo 123',
},
})
);
const output = runCommand(`${packageManagerCommand} nx init`);
expect(output).toContain('Nx has been installed');
expect(output).toContain('nx.json has been created');
expect(runCLI('run package:echo')).toContain('123');
renameFile('nx.json', 'nx.json.old');
expect(runCLI('run package:echo')).toContain('123');
});
});

13
e2e/nx-init/tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"types": ["node", "jest"]
},
"include": [],
"files": [],
"references": [
{
"path": "./tsconfig.spec.json"
}
]
}

View File

@ -0,0 +1,20 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.test.ts",
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.test.tsx",
"**/*.spec.js",
"**/*.test.js",
"**/*.spec.jsx",
"**/*.test.jsx",
"**/*.d.ts",
"jest.config.ts"
]
}

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -3,7 +3,7 @@ import {
parseJson, parseJson,
ProjectConfiguration, ProjectConfiguration,
readJsonFile, readJsonFile,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
import { angularCliVersion } from '@nrwl/workspace/src/utils/versions'; import { angularCliVersion } from '@nrwl/workspace/src/utils/versions';
import { ChildProcess, exec, execSync, ExecSyncOptions } from 'child_process'; import { ChildProcess, exec, execSync, ExecSyncOptions } from 'child_process';
@ -101,7 +101,7 @@ export function updateProjectConfig(
* if you need a project's configuration. * if you need a project's configuration.
*/ */
export function readWorkspaceConfig(): Omit< export function readWorkspaceConfig(): Omit<
WorkspaceJsonConfiguration, ProjectsConfigurations,
'projects' 'projects'
> { > {
const w = readJson(workspaceConfigName()); const w = readJson(workspaceConfigName());

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -4,7 +4,7 @@
"projectType": "application", "projectType": "application",
"targets": { "targets": {
"e2e": { "e2e": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -1,6 +1,6 @@
{ {
"packages": ["build/packages/*"], "packages": ["build/packages/*"],
"version": "14.1.9", "version": "14.2.0",
"granularPathspec": false, "granularPathspec": false,
"command": { "command": {
"publish": { "publish": {

View File

@ -10,28 +10,28 @@
"projects": "self" "projects": "self"
} }
], ],
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"outputPath": "dist/nx-dev/nx-dev", "outputPath": "dist/nx-dev/nx-dev",
"command": "nx run nx-dev:sitemap" "command": "nx run nx-dev:sitemap"
} }
}, },
"sitemap": { "sitemap": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": [], "outputs": [],
"options": { "options": {
"command": "yarn next-sitemap --config ./nx-dev/nx-dev/next-sitemap.js" "command": "yarn next-sitemap --config ./nx-dev/nx-dev/next-sitemap.js"
} }
}, },
"sync-documentation": { "sync-documentation": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["nx-dev/nx-dev/public/documentation"], "outputs": ["nx-dev/nx-dev/public/documentation"],
"options": { "options": {
"command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/nx-dev-docs-latest-sync.ts" "command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/nx-dev-docs-latest-sync.ts"
} }
}, },
"generate-og-images": { "generate-og-images": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["nx-dev/nx-dev/public/images/open-graph"], "outputs": ["nx-dev/nx-dev/public/images/open-graph"],
"options": { "options": {
"command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/open-graph/generate-images.ts" "command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/open-graph/generate-images.ts"
@ -68,7 +68,7 @@
"defaultConfiguration": "development" "defaultConfiguration": "development"
}, },
"deploy-build": { "deploy-build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["nx-dev/nx-dev/public/documentation"], "outputs": ["nx-dev/nx-dev/public/documentation"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -37,7 +37,7 @@
} }
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/add-nx-to-monorepo"], "outputs": ["build/packages/add-nx-to-monorepo"],
"options": { "options": {
"commands": [ "commands": [
@ -52,7 +52,7 @@
} }
}, },
"test-against-repo": { "test-against-repo": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"commands": [ "commands": [
{ {

View File

@ -41,7 +41,7 @@ export async function addNxToMonorepo() {
process.exit(1); process.exit(1);
} }
createNxJsonFile(repoRoot); createNxJsonFile(repoRoot, pds);
addDepsToPackageJson(repoRoot, useCloud); addDepsToPackageJson(repoRoot, useCloud);
@ -135,6 +135,7 @@ interface ProjectDesc {
name: string; name: string;
dir: string; dir: string;
mainFilePath: string; mainFilePath: string;
scripts: string[];
} }
function createProjectDesc( function createProjectDesc(
@ -147,61 +148,64 @@ function createProjectDesc(
const packageJson = readJsonFile(path.join(repoRoot, p)); const packageJson = readJsonFile(path.join(repoRoot, p));
if (!packageJson.name) return; if (!packageJson.name) return;
const scripts = Object.keys(packageJson.scripts || {});
if (packageJson.main) { if (packageJson.main) {
res.push({ res.push({
name: packageJson.name, name: packageJson.name,
dir, dir,
mainFilePath: path.join(dir, packageJson.main), mainFilePath: path.join(dir, packageJson.main),
scripts,
}); });
} else if (packageJson.index) { } else if (packageJson.index) {
res.push({ res.push({
name: packageJson.name, name: packageJson.name,
dir, dir,
mainFilePath: path.join(dir, packageJson.index), mainFilePath: path.join(dir, packageJson.index),
scripts,
}); });
} else { } else {
res.push({ name: packageJson.name, dir, mainFilePath: null }); res.push({ name: packageJson.name, dir, mainFilePath: null, scripts });
} }
}); });
return res; return res;
} }
function detectWorkspaceScope(repoRoot: string) { function createNxJsonFile(repoRoot: string, projects: ProjectDesc[]) {
let scope = readJsonFile(path.join(repoRoot, `package.json`)).name; const allScripts = {};
if (!scope) return 'undetermined'; for (const p of projects) {
for (const s of p.scripts) {
if (scope.startsWith('@')) { allScripts[s] = true;
scope = scope.substring(1); }
} }
return scope.split('/')[0]; const cacheableOperations = Object.keys(allScripts).filter(
} (s) => s.indexOf('serve') === -1 && s.indexOf('start') === -1
);
const targetDependencies = cacheableOperations
.filter((c) => c === 'build' || c === 'prepare' || c === 'package')
.reduce(
(m, c) => ({
...m,
[c]: [{ target: c, projects: 'dependencies' }],
}),
{}
);
function createNxJsonFile(repoRoot: string) {
const res = { const res = {
extends: 'nx/presets/npm.json', extends: 'nx/presets/core.json',
tasksRunnerOptions: { tasksRunnerOptions: {
default: { default: {
runner: 'nx/tasks-runners/default', runner: 'nx/tasks-runners/default',
options: { options: {
cacheableOperations: ['build', 'test', 'lint', 'package', 'prepare'], cacheableOperations,
}, },
}, },
}, },
targetDependencies: { targetDependencies,
build: [{ target: 'build', projects: 'dependencies' }],
prepare: [{ target: 'prepare', projects: 'dependencies' }],
package: [{ target: 'package', projects: 'dependencies' }],
},
affected: { affected: {
defaultBase: deduceDefaultBase(), defaultBase: deduceDefaultBase(),
}, },
workspaceLayout: deduceWorkspaceLayout(repoRoot), workspaceLayout: deduceWorkspaceLayout(repoRoot),
pluginsConfig: {
'@nrwl/js': {
analyzeSourceFiles: false,
},
},
}; };
writeJsonFile(`${repoRoot}/nx.json`, res); writeJsonFile(`${repoRoot}/nx.json`, res);

View File

@ -61,7 +61,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/angular"], "outputs": ["build/packages/angular"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -1,5 +1,8 @@
import type { Schema } from './schema'; import type { Schema } from './schema';
import { ProjectConfiguration, Workspaces } from '@nrwl/devkit'; import {
ProjectConfiguration,
readAllWorkspaceConfiguration,
} from '@nrwl/devkit';
import { scheduleTarget } from 'nx/src/adapter/ngcli-adapter'; import { scheduleTarget } from 'nx/src/adapter/ngcli-adapter';
import { BuilderContext, createBuilder } from '@angular-devkit/architect'; import { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core'; import { JsonObject } from '@angular-devkit/core';
@ -59,9 +62,7 @@ export function executeModuleFederationDevServerBuilder(
schema: Schema, schema: Schema,
context: BuilderContext context: BuilderContext
) { ) {
const workspaces = new Workspaces(context.workspaceRoot); const workspaceConfig = readAllWorkspaceConfiguration();
const workspaceConfig = workspaces.readWorkspaceConfiguration();
const p = workspaceConfig.projects[context.target.project]; const p = workspaceConfig.projects[context.target.project];
const mfConfigPath = join( const mfConfigPath = join(

View File

@ -4,7 +4,12 @@ import {
serveWebpackBrowser, serveWebpackBrowser,
} from '@angular-devkit/build-angular/src/builders/dev-server'; } from '@angular-devkit/build-angular/src/builders/dev-server';
import { JsonObject } from '@angular-devkit/core'; import { JsonObject } from '@angular-devkit/core';
import { joinPathFragments, parseTargetString, Workspaces } from '@nrwl/devkit'; import {
joinPathFragments,
parseTargetString,
readAllWorkspaceConfiguration,
Workspaces,
} from '@nrwl/devkit';
import { existsSync } from 'fs'; import { existsSync } from 'fs';
import { merge } from 'webpack-merge'; import { merge } from 'webpack-merge';
import { resolveCustomWebpackConfig } from '../utilities/webpack'; import { resolveCustomWebpackConfig } from '../utilities/webpack';
@ -21,9 +26,7 @@ export function executeWebpackServerBuilder(
); );
const options = normalizeOptions(schema); const options = normalizeOptions(schema);
const workspaceConfig = new Workspaces( const workspaceConfig = readAllWorkspaceConfiguration();
context.workspaceRoot
).readWorkspaceConfiguration();
const parsedBrowserTarget = parseTargetString(options.browserTarget); const parsedBrowserTarget = parseTargetString(options.browserTarget);
const buildTarget = const buildTarget =

View File

@ -1,257 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`withModuleFederation should apply additional shared dependencies when specified 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/common": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"@angular/core": Object {
"singleton": true,
"strictVersion": false,
},
"@angular/router": Object {
"requiredVersion": "^13.0.0",
"singleton": false,
"strictVersion": true,
},
"shared": Object {
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should apply the user-specified shared function correctly 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": undefined,
"singleton": true,
"strictVersion": false,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should collect dependencies correctly 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"core": Object {
"eager": undefined,
"requiredVersion": false,
},
"lodash": Object {
"requiredVersion": "~4.17.20",
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should create a host config correctly 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": undefined,
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "host",
"remotes": Object {
"remote1": "http://localhost:4201/remoteEntry.mjs",
},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should create a remote config correctly 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should map dependencies from project name to import name 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"@myorg/core": Object {
"eager": undefined,
"requiredVersion": false,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;
exports[`withModuleFederation should not have duplicated entries for duplicated dependencies 1`] = `
Array [
ModuleFederationPlugin {
"_options": Object {
"exposes": Object {
"./Module": "apps/remote1/src/module.ts",
},
"filename": "remoteEntry.mjs",
"library": Object {
"type": "module",
},
"name": "remote1",
"remotes": Object {},
"shared": Object {
"@angular/core": Object {
"requiredVersion": "~13.2.0",
"singleton": true,
"strictVersion": true,
},
"core": Object {
"eager": undefined,
"requiredVersion": false,
},
"shared": Object {
"eager": undefined,
"requiredVersion": false,
},
},
},
},
NormalModuleReplacementPlugin {
"newResource": [Function],
"resourceRegExp": /\\./,
},
]
`;

View File

@ -1,475 +0,0 @@
jest.mock('fs');
jest.mock('@nrwl/devkit');
jest.mock('@nrwl/workspace/src/utilities/typescript');
jest.mock('nx/src/project-graph/file-utils');
import * as graph from '@nrwl/devkit';
import * as typescriptUtils from '@nrwl/workspace/src/utilities/typescript';
import * as workspace from 'nx/src/project-graph/file-utils';
import * as fs from 'fs';
import * as devkit from '@nrwl/devkit';
import { withModuleFederation } from './with-module-federation';
describe('withModuleFederation', () => {
afterEach(() => jest.clearAllMocks());
it('should create a host config correctly', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
host: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'shared' },
],
},
});
(workspace.readWorkspaceJson as jest.Mock).mockReturnValue({
projects: {
remote1: {
targets: {
serve: {
options: {
publicHost: 'http://localhost:4201',
},
},
},
},
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'host',
remotes: ['remote1'],
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should create a remote config correctly', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'shared' },
],
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should collect dependencies correctly', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'core' },
],
core: [{ target: 'shared' }, { target: 'npm:lodash' }],
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0', lodash: '~4.17.20' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
core: ['/libs/core/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should not have duplicated entries for duplicated dependencies', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'core' },
],
core: [{ target: 'shared' }, { target: 'npm:@angular/core' }],
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
core: ['/libs/core/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should map dependencies from project name to import name', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'core' },
],
core: [{ target: 'shared' }],
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockImplementation(() => ({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
'@myorg/core': ['/libs/core/src/index.ts'],
},
},
}));
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should apply the user-specified shared function correctly', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [
{ target: 'npm:@angular/core' },
{ target: 'npm:zone.js' },
{ target: 'core' },
],
core: [{ target: 'shared' }, { target: 'npm:@angular/core' }],
},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
core: ['/libs/core/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
shared: (dep, config) => {
if (dep === 'core') {
return false;
}
if (dep === '@angular/core') {
return {
...config,
strictVersion: false,
requiredVersion: undefined,
};
}
},
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should apply additional shared dependencies when specified', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [{ target: 'npm:@angular/core' }, { target: 'core' }],
core: [{ target: 'npm:@angular/core' }],
},
nodes: { shared: {} },
externalNodes: { '@angular/common': {} },
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: {
'@angular/core': '~13.2.0',
'@angular/common': '~13.2.0',
'@angular/router': '~13.2.0',
},
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
core: ['/libs/core/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT
const config = (
await withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
shared: (dep, config) => {
if (dep === 'core') {
return false;
}
},
additionalShared: [
'@angular/common',
[
'@angular/core',
{
strictVersion: false,
singleton: true,
},
],
{
libraryName: '@angular/router',
sharedConfig: {
requiredVersion: '^13.0.0',
singleton: false,
strictVersion: true,
},
},
'shared',
],
})
)({});
// ASSERT
expect(config.plugins).toMatchSnapshot();
});
it('should throw when an additionalShared entry is a string and it is not in the project graph', async () => {
// ARRANGE
(graph.readCachedProjectGraph as jest.Mock).mockReturnValue({
dependencies: {
remote1: [{ target: 'npm:@angular/core' }, { target: 'core' }],
core: [{ target: 'npm:@angular/core' }],
},
nodes: {},
externalNodes: {},
});
(fs.existsSync as jest.Mock).mockReturnValue(true);
jest.spyOn(devkit, 'readJsonFile').mockImplementation(() => ({
dependencies: { '@angular/core': '~13.2.0' },
}));
(typescriptUtils.readTsConfig as jest.Mock).mockReturnValue({
options: {
paths: {
shared: ['/libs/shared/src/index.ts'],
core: ['/libs/core/src/index.ts'],
},
},
});
(graph.Workspaces as jest.Mock).mockReturnValue({
readWorkspaceConfiguration: () => ({
projects: {
shared: {
sourceRoot: '/libs/shared/src/',
},
core: {
sourceRoot: '/libs/core/src/',
},
},
}),
});
(fs.readdirSync as jest.Mock).mockReturnValue([]);
// ACT & ASSERT
await expect(
withModuleFederation({
name: 'remote1',
exposes: { './Module': 'apps/remote1/src/module.ts' },
additionalShared: ['shared'],
})
).rejects.toThrow(
'The specified dependency "shared" in the additionalShared configuration does not exist in the project graph.'
);
});
});

View File

@ -7,16 +7,14 @@ import {
import { import {
createProjectGraphAsync, createProjectGraphAsync,
ProjectGraph, ProjectGraph,
readAllWorkspaceConfiguration,
readCachedProjectGraph, readCachedProjectGraph,
workspaceRoot,
Workspaces,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
import { import {
getRootTsConfigPath, getRootTsConfigPath,
readTsConfig, readTsConfig,
} from '@nrwl/workspace/src/utilities/typescript'; } from '@nrwl/workspace/src/utilities/typescript';
import { ParsedCommandLine } from 'typescript'; import { ParsedCommandLine } from 'typescript';
import { readWorkspaceJson } from 'nx/src/project-graph/file-utils';
import { readRootPackageJson } from './utils'; import { readRootPackageJson } from './utils';
import { extname, join } from 'path'; import { extname, join } from 'path';
import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
@ -71,9 +69,7 @@ function collectDependencies(
} }
function mapWorkspaceLibrariesToTsConfigImport(workspaceLibraries: string[]) { function mapWorkspaceLibrariesToTsConfigImport(workspaceLibraries: string[]) {
const { projects } = new Workspaces( const { projects } = readAllWorkspaceConfiguration();
workspaceRoot
).readWorkspaceConfiguration();
const tsConfigPath = process.env.NX_TSCONFIG_PATH ?? getRootTsConfigPath(); const tsConfigPath = process.env.NX_TSCONFIG_PATH ?? getRootTsConfigPath();
const tsConfig: ParsedCommandLine = readTsConfig(tsConfigPath); const tsConfig: ParsedCommandLine = readTsConfig(tsConfigPath);
@ -123,7 +119,7 @@ async function getDependentPackagesForProject(
} }
function determineRemoteUrl(remote: string) { function determineRemoteUrl(remote: string) {
const workspace = readWorkspaceJson(); const workspace = readAllWorkspaceConfiguration();
let publicHost = ''; let publicHost = '';
try { try {
publicHost = workspace.projects[remote].targets.serve.options.publicHost; publicHost = workspace.projects[remote].targets.serve.options.publicHost;

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/cli"], "outputs": ["build/packages/cli"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -38,7 +38,7 @@
} }
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/cra-to-nx"], "outputs": ["build/packages/cra-to-nx"],
"options": { "options": {
"commands": [ "commands": [
@ -53,7 +53,7 @@
} }
}, },
"publish": { "publish": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"options": { "options": {
"command": "node tools/scripts/publish.js cra-to-nx {args.ver} {args.tag} {args.local}" "command": "node tools/scripts/publish.js cra-to-nx {args.ver} {args.tag} {args.local}"
} }

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/create-nx-plugin"], "outputs": ["build/packages/create-nx-plugin"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/create-nx-workspace"], "outputs": ["build/packages/create-nx-workspace"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/cypress"], "outputs": ["build/packages/cypress"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js cypress" "command": "node ./scripts/copy-readme.js cypress"

View File

@ -5,7 +5,7 @@ import {
ProjectGraph, ProjectGraph,
Task, Task,
TaskGraph, TaskGraph,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
export default async function run( export default async function run(
@ -14,7 +14,7 @@ export default async function run(
hasher: Hasher; hasher: Hasher;
projectGraph: ProjectGraph; projectGraph: ProjectGraph;
taskGraph: TaskGraph; taskGraph: TaskGraph;
workspaceConfig: WorkspaceJsonConfiguration & NxJsonConfiguration; workspaceConfig: ProjectsConfigurations & NxJsonConfiguration;
} }
): Promise<Hash> { ): Promise<Hash> {
const cypressPluginConfig = context.workspaceConfig.pluginsConfig const cypressPluginConfig = context.workspaceConfig.pluginsConfig

View File

@ -71,7 +71,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/detox"], "outputs": ["build/packages/detox"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js detox" "command": "node ./scripts/copy-readme.js detox"

View File

@ -19,6 +19,7 @@ export type { Tree, FileChange } from 'nx/src/generators/tree';
*/ */
export type { export type {
WorkspaceJsonConfiguration, WorkspaceJsonConfiguration,
ProjectsConfigurations,
TargetDependencyConfig, TargetDependencyConfig,
TargetConfiguration, TargetConfiguration,
ProjectConfiguration, ProjectConfiguration,
@ -47,6 +48,12 @@ export type {
*/ */
export { Workspaces } from 'nx/src/config/workspaces'; export { Workspaces } from 'nx/src/config/workspaces';
export {
readNxJson,
readAllWorkspaceConfiguration,
workspaceLayout,
} from 'nx/src/config/configuration';
export type { export type {
NxPlugin, NxPlugin,
ProjectTargetConfigurator, ProjectTargetConfigurator,
@ -275,7 +282,7 @@ export { moveFilesToNewDirectory } from './src/utils/move-dir';
/** /**
* @category Utils * @category Utils
*/ */
export { workspaceRoot, appRootPath } from 'nx/src/utils/app-root'; export { workspaceRoot, appRootPath } from 'nx/src/utils/workspace-root';
/** /**
* @category Utils * @category Utils
@ -289,11 +296,6 @@ export {
readCachedProjectGraph, readCachedProjectGraph,
} from 'nx/src/project-graph/project-graph'; } from 'nx/src/project-graph/project-graph';
/**
* @category Utils
*/
export { readNxJson, workspaceLayout } from 'nx/src/project-graph/file-utils';
/** /**
* @category Utils * @category Utils
*/ */

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/devkit"], "outputs": ["build/packages/devkit"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js devkit" "command": "node ./scripts/copy-readme.js devkit"

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/eslint-plugin-nx"], "outputs": ["build/packages/eslint-plugin-nx"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js eslint-plugin-nx" "command": "node ./scripts/copy-readme.js eslint-plugin-nx"

View File

@ -16,7 +16,7 @@ jest.mock('@nrwl/devkit', () => ({
workspaceRoot: '/root', workspaceRoot: '/root',
})); }));
jest.mock('nx/src/utils/app-root', () => ({ jest.mock('nx/src/utils/workspace-root', () => ({
workspaceRoot: '/root', workspaceRoot: '/root',
})); }));

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/express"], "outputs": ["build/packages/express"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js express" "command": "node ./scripts/copy-readme.js express"

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/jest"], "outputs": ["build/packages/jest"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js jest" "command": "node ./scripts/copy-readme.js jest"

View File

@ -1,5 +1,5 @@
import { dirname, join } from 'path'; import { dirname, join } from 'path';
import type { WorkspaceJsonConfiguration } from '@nrwl/devkit'; import type { ProjectsConfigurations } from '@nrwl/devkit';
import { readWorkspaceConfig } from 'nx/src/project-graph/file-utils'; import { readWorkspaceConfig } from 'nx/src/project-graph/file-utils';
const JEST_RUNNER_TOKEN = '@nrwl/jest:jest'; const JEST_RUNNER_TOKEN = '@nrwl/jest:jest';
@ -11,7 +11,7 @@ function getJestConfigProjectPath(projectJestConfigPath: string): string {
export function getJestProjects() { export function getJestProjects() {
const ws = readWorkspaceConfig({ const ws = readWorkspaceConfig({
format: 'nx', format: 'nx',
}) as WorkspaceJsonConfiguration; }) as ProjectsConfigurations;
const jestConfigurationSet = new Set(); const jestConfigurationSet = new Set();
for (const projectConfig of Object.values(ws.projects)) { for (const projectConfig of Object.values(ws.projects)) {
if (!projectConfig.targets) { if (!projectConfig.targets) {

View File

@ -67,7 +67,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/js"], "outputs": ["build/packages/js"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js js" "command": "node ./scripts/copy-readme.js js"

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/linter"], "outputs": ["build/packages/linter"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js linter" "command": "node ./scripts/copy-readme.js linter"

View File

@ -2,7 +2,7 @@ import {
ProjectGraph, ProjectGraph,
Task, Task,
TaskGraph, TaskGraph,
WorkspaceJsonConfiguration, ProjectsConfigurations,
Hasher, Hasher,
Hash, Hash,
} from '@nrwl/devkit'; } from '@nrwl/devkit';
@ -13,7 +13,7 @@ export default async function run(
hasher: Hasher; hasher: Hasher;
projectGraph: ProjectGraph; projectGraph: ProjectGraph;
taskGraph: TaskGraph; taskGraph: TaskGraph;
workspaceConfig: WorkspaceJsonConfiguration; workspaceConfig: ProjectsConfigurations;
} }
): Promise<Hash> { ): Promise<Hash> {
if (task.overrides['hasTypeAwareRules'] === true) { if (task.overrides['hasTypeAwareRules'] === true) {

View File

@ -25,7 +25,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/make-angular-cli-faster"], "outputs": ["build/packages/make-angular-cli-faster"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/nest"], "outputs": ["build/packages/nest"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js nest" "command": "node ./scripts/copy-readme.js nest"

View File

@ -61,7 +61,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/next"], "outputs": ["build/packages/next"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js next" "command": "node ./scripts/copy-readme.js next"

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/node"], "outputs": ["build/packages/node"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js node" "command": "node ./scripts/copy-readme.js node"

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"] "outputs": ["{options.outputPath}"]
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/nx-plugin"], "outputs": ["build/packages/nx-plugin"],
"options": { "options": {
"command": "node ./scripts/copy-readme.js nx-plugin" "command": "node ./scripts/copy-readme.js nx-plugin"

View File

@ -9,7 +9,11 @@ import { detectPackageManager } from '../src/utils/package-manager';
import { output } from '../src/utils/output'; import { output } from '../src/utils/output';
// new is a special case because there is no local workspace to load // new is a special case because there is no local workspace to load
if (process.argv[2] === 'new' || process.argv[2] === '_migrate') { if (
process.argv[2] === 'new' ||
process.argv[2] === '_migrate' ||
process.argv[2] === 'init'
) {
require('nx/src/command-line/nx-commands').commandsObject.argv; require('nx/src/command-line/nx-commands').commandsObject.argv;
} else { } else {
const workspace = findWorkspaceRoot(process.cwd()); const workspace = findWorkspaceRoot(process.cwd());
@ -27,6 +31,12 @@ if (process.argv[2] === 'new' || process.argv[2] === '_migrate') {
bodyLines: [ bodyLines: [
`To create a workspace run:`, `To create a workspace run:`,
chalk.bold.white(`npx create-nx-workspace@latest <workspace name>`), chalk.bold.white(`npx create-nx-workspace@latest <workspace name>`),
'',
`To add Nx to existing workspace run with a workspace-specific nx.json:`,
chalk.bold.white(`npx add-nx-to-monorepo@latest`),
'',
`To add the default nx.json file run:`,
chalk.bold.white(`nx init`),
], ],
}); });

View File

@ -8,7 +8,7 @@
"directory": "packages/nx" "directory": "packages/nx"
}, },
"scripts": { "scripts": {
"postinstall": "node ./bin/init" "postinstall": "node ./bin/compute-project-graph"
}, },
"keywords": [ "keywords": [
"Monorepo", "Monorepo",

View File

@ -6,16 +6,21 @@
}, },
".eslintrc.json": "*" ".eslintrc.json": "*"
}, },
"targetDependencies": { "tasksRunnerOptions": {
"build": [ "default": {
{ "runner": "nx/tasks-runners/default",
"target": "build", "options": {
"projects": "dependencies" "cacheableOperations": []
}
} }
]
}, },
"workspaceLayout": { "workspaceLayout": {
"appsDir": "packages", "libsDir": "packages",
"libsDir": "packages" "appsDir": "packages"
},
"pluginsConfig": {
"@nrwl/js": {
"analyzeSourceFiles": false
}
} }
} }

View File

@ -6,15 +6,21 @@
}, },
".eslintrc.json": "*" ".eslintrc.json": "*"
}, },
"targetDependencies": { "tasksRunnerOptions": {
"build": [ "default": {
{ "runner": "nx/tasks-runners/default",
"target": "build", "options": {
"projects": "dependencies" "cacheableOperations": []
}
} }
]
}, },
"workspaceLayout": { "workspaceLayout": {
"libsDir": "packages" "libsDir": "packages",
"appsDir": "packages"
},
"pluginsConfig": {
"@nrwl/js": {
"analyzeSourceFiles": false
}
} }
} }

View File

@ -56,7 +56,7 @@
} }
}, },
"build": { "build": {
"executor": "@nrwl/workspace:run-commands", "executor": "nx:run-commands",
"outputs": ["build/packages/nx"], "outputs": ["build/packages/nx"],
"options": { "options": {
"commands": [ "commands": [

View File

@ -4,7 +4,7 @@ import {
workspaceConfigName, workspaceConfigName,
Workspaces, Workspaces,
} from '../config/workspaces'; } from '../config/workspaces';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
/* eslint-disable */ /* eslint-disable */
const Module = require('module'); const Module = require('module');

View File

@ -35,8 +35,8 @@ import { parseJson, serializeJson } from '../utils/json';
import { NxJsonConfiguration } from '../config/nx-json'; import { NxJsonConfiguration } from '../config/nx-json';
import { import {
ProjectConfiguration, ProjectConfiguration,
RawWorkspaceJsonConfiguration, RawProjectsConfigurations,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '../config/workspace-json-project-json'; } from '../config/workspace-json-project-json';
import { readNxJson } from '../generators/utils/project-configuration'; import { readNxJson } from '../generators/utils/project-configuration';
@ -210,7 +210,7 @@ async function runSchematic(
return { status: 0, loggingQueue: record.loggingQueue }; return { status: 0, loggingQueue: record.loggingQueue };
} }
type AngularJsonConfiguration = WorkspaceJsonConfiguration & type AngularJsonConfiguration = ProjectsConfigurations &
Pick<NxJsonConfiguration, 'cli' | 'defaultProject' | 'generators'> & { Pick<NxJsonConfiguration, 'cli' | 'defaultProject' | 'generators'> & {
schematics?: NxJsonConfiguration['generators']; schematics?: NxJsonConfiguration['generators'];
cli?: NxJsonConfiguration['cli'] & { cli?: NxJsonConfiguration['cli'] & {
@ -218,7 +218,7 @@ type AngularJsonConfiguration = WorkspaceJsonConfiguration &
}; };
}; };
export class NxScopedHost extends virtualFs.ScopedHost<any> { export class NxScopedHost extends virtualFs.ScopedHost<any> {
protected __nxInMemoryWorkspace: WorkspaceJsonConfiguration | null; protected __nxInMemoryWorkspace: ProjectsConfigurations | null;
constructor(private root: string) { constructor(private root: string) {
super(new NodeJsSyncHost(), normalize(root)); super(new NodeJsSyncHost(), normalize(root));
@ -227,7 +227,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
protected __readWorkspaceConfiguration = ( protected __readWorkspaceConfiguration = (
configFileName: ChangeContext['actualConfigFileName'], configFileName: ChangeContext['actualConfigFileName'],
overrides?: { overrides?: {
workspace?: Observable<RawWorkspaceJsonConfiguration>; workspace?: Observable<RawProjectsConfigurations>;
nx?: Observable<NxJsonConfiguration>; nx?: Observable<NxJsonConfiguration>;
} }
): Observable<FileBuffer> => { ): Observable<FileBuffer> => {
@ -238,7 +238,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
const readWorkspaceJsonFile = ( const readWorkspaceJsonFile = (
nxJson: NxJsonConfiguration nxJson: NxJsonConfiguration
): Observable<RawWorkspaceJsonConfiguration> => { ): Observable<RawProjectsConfigurations> => {
if (overrides?.workspace) { if (overrides?.workspace) {
return overrides.workspace; return overrides.workspace;
} else if (this.__nxInMemoryWorkspace) { } else if (this.__nxInMemoryWorkspace) {
@ -286,7 +286,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
} else { } else {
nxJsonObservable = of({} as NxJsonConfiguration); nxJsonObservable = of({} as NxJsonConfiguration);
} }
const workspaceJsonObservable: Observable<RawWorkspaceJsonConfiguration> = const workspaceJsonObservable: Observable<RawProjectsConfigurations> =
nxJsonObservable.pipe(switchMap((x) => readWorkspaceJsonFile(x))); nxJsonObservable.pipe(switchMap((x) => readWorkspaceJsonFile(x)));
return forkJoin([nxJsonObservable, workspaceJsonObservable]); return forkJoin([nxJsonObservable, workspaceJsonObservable]);
}), }),
@ -534,8 +534,8 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
} }
protected resolveInlineProjectConfigurations( protected resolveInlineProjectConfigurations(
config: RawWorkspaceJsonConfiguration config: RawProjectsConfigurations
): Observable<WorkspaceJsonConfiguration> { ): Observable<ProjectsConfigurations> {
// Creates an observable where each emission is a project configuration // Creates an observable where each emission is a project configuration
// that is not listed inside workspace.json. Each time it encounters a // that is not listed inside workspace.json. Each time it encounters a
// standalone config, observable is updated by concatenating the new // standalone config, observable is updated by concatenating the new
@ -572,7 +572,7 @@ export class NxScopedHost extends virtualFs.ScopedHost<any> {
configs.forEach(({ project, projectConfig }) => { configs.forEach(({ project, projectConfig }) => {
config.projects[project] = projectConfig; config.projects[project] = projectConfig;
}); });
return config as WorkspaceJsonConfiguration; return config as ProjectsConfigurations;
}) })
); );
} }
@ -598,7 +598,7 @@ export class NxScopeHostUsedForWrappedSchematics extends NxScopedHost {
const nxJsonChange = findMatchingFileChange(this.host, 'nx.json' as Path); const nxJsonChange = findMatchingFileChange(this.host, 'nx.json' as Path);
const match = findWorkspaceConfigFileChange(this.host); const match = findWorkspaceConfigFileChange(this.host);
let workspaceJsonOverride: Observable<RawWorkspaceJsonConfiguration>; let workspaceJsonOverride: Observable<RawProjectsConfigurations>;
let actualConfigFileName: ConfigFilePath = [ let actualConfigFileName: ConfigFilePath = [
'/workspace.json', '/workspace.json',
'/angular.json', '/angular.json',

View File

@ -23,19 +23,20 @@ export async function affected(
parsedArgs: yargs.Arguments & RawNxArgs parsedArgs: yargs.Arguments & RawNxArgs
): Promise<void> { ): Promise<void> {
performance.mark('command-execution-begins'); performance.mark('command-execution-begins');
const env = readEnvironment();
const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides( const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides(
parsedArgs, parsedArgs,
'affected', 'affected',
{ {
printWarnings: command !== 'print-affected' && !parsedArgs.plain, printWarnings: command !== 'print-affected' && !parsedArgs.plain,
} },
env.nxJson
); );
await connectToNxCloudUsingScan(nxArgs.scan); await connectToNxCloudUsingScan(nxArgs.scan);
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync();
const projects = projectsToRun(nxArgs, projectGraph); const projects = projectsToRun(nxArgs, projectGraph);
const env = readEnvironment();
try { try {
switch (command) { switch (command) {

View File

@ -1,7 +1,7 @@
import { readNxJson } from '../project-graph/file-utils';
import { output } from '../utils/output'; import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager'; import { getPackageManagerCommand } from '../utils/package-manager';
import { execSync } from 'child_process'; import { execSync } from 'child_process';
import { readNxJson } from '../config/configuration';
export async function connectToNxCloudUsingScan(scan: boolean): Promise<void> { export async function connectToNxCloudUsingScan(scan: boolean): Promise<void> {
if (!scan) return; if (!scan) return;

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from 'nx/src/utils/app-root'; import { workspaceRoot } from 'nx/src/utils/workspace-root';
import { watch } from 'chokidar'; import { watch } from 'chokidar';
import { createHash } from 'crypto'; import { createHash } from 'crypto';
import { existsSync, readFileSync, statSync, writeFileSync } from 'fs'; import { existsSync, readFileSync, statSync, writeFileSync } from 'fs';
@ -9,7 +9,7 @@ import * as open from 'open';
import { basename, dirname, extname, isAbsolute, join, parse } from 'path'; import { basename, dirname, extname, isAbsolute, join, parse } from 'path';
import { performance } from 'perf_hooks'; import { performance } from 'perf_hooks';
import { URL, URLSearchParams } from 'url'; import { URL, URLSearchParams } from 'url';
import { workspaceLayout } from '../project-graph/file-utils'; import { workspaceLayout } from '../config/configuration';
import { defaultFileHasher } from '../hasher/file-hasher'; import { defaultFileHasher } from '../hasher/file-hasher';
import { output } from '../utils/output'; import { output } from '../utils/output';
import { writeJsonFile } from '../utils/fileutils'; import { writeJsonFile } from '../utils/fileutils';

View File

@ -13,7 +13,7 @@ import {
reformattedWorkspaceJsonOrNull, reformattedWorkspaceJsonOrNull,
workspaceConfigName, workspaceConfigName,
} from '../config/workspaces'; } from '../config/workspaces';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import * as prettier from 'prettier'; import * as prettier from 'prettier';
import { sortObjectByKeys } from '../utils/object-sort'; import { sortObjectByKeys } from '../utils/object-sort';
import { import {
@ -26,8 +26,9 @@ import { createProjectGraphAsync } from '../project-graph/project-graph';
import { filterAffected } from '../project-graph/affected/affected-project-graph'; import { filterAffected } from '../project-graph/affected/affected-project-graph';
import { import {
ProjectConfiguration, ProjectConfiguration,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '../config/workspace-json-project-json'; } from '../config/workspace-json-project-json';
import { readNxJson } from '../config/configuration';
const PRETTIER_PATH = require.resolve('prettier/bin-prettier'); const PRETTIER_PATH = require.resolve('prettier/bin-prettier');
@ -35,7 +36,12 @@ export async function format(
command: 'check' | 'write', command: 'check' | 'write',
args: yargs.Arguments args: yargs.Arguments
): Promise<void> { ): Promise<void> {
const { nxArgs } = splitArgsIntoNxArgsAndOverrides(args, 'affected'); const { nxArgs } = splitArgsIntoNxArgsAndOverrides(
args,
'affected',
{ printWarnings: true },
readNxJson()
);
const patterns = (await getPatterns({ ...args, ...nxArgs } as any)).map( const patterns = (await getPatterns({ ...args, ...nxArgs } as any)).map(
(p) => `"${p}"` (p) => `"${p}"`
); );
@ -242,11 +248,11 @@ function sortTsConfig() {
function movePropertiesToNewLocations(workspaceJsonPath: string) { function movePropertiesToNewLocations(workspaceJsonPath: string) {
try { try {
const workspaceJson = readJsonFile< const workspaceJson = readJsonFile<
NxJsonConfiguration & WorkspaceJsonConfiguration NxJsonConfiguration & ProjectsConfigurations
>(workspaceJsonPath); >(workspaceJsonPath);
const nxJson = readJsonFile< const nxJson = readJsonFile<NxJsonConfiguration & ProjectsConfigurations>(
NxJsonConfiguration & WorkspaceJsonConfiguration 'nx.json'
>('nx.json'); );
if ( if (
workspaceJson.cli || workspaceJson.cli ||
workspaceJson.generators || workspaceJson.generators ||
@ -273,7 +279,7 @@ function movePropertiesToNewLocations(workspaceJsonPath: string) {
} }
export function moveTagsAndImplicitDepsFromNxJsonToWorkspaceJson( export function moveTagsAndImplicitDepsFromNxJsonToWorkspaceJson(
workspaceJson: WorkspaceJsonConfiguration, workspaceJson: ProjectsConfigurations,
nxJson: NxJsonConfiguration & { nxJson: NxJsonConfiguration & {
projects: Record< projects: Record<
string, string,

View File

@ -8,7 +8,7 @@ import { Workspaces } from '../config/workspaces';
import { FileChange, flushChanges, FsTree } from '../generators/tree'; import { FileChange, flushChanges, FsTree } from '../generators/tree';
import { logger } from '../utils/logger'; import { logger } from '../utils/logger';
import * as chalk from 'chalk'; import * as chalk from 'chalk';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { NxJsonConfiguration } from '../config/nx-json'; import { NxJsonConfiguration } from '../config/nx-json';
import { printHelp } from '../utils/print-help'; import { printHelp } from '../utils/print-help';
import { prompt } from 'enquirer'; import { prompt } from 'enquirer';

View File

@ -0,0 +1,40 @@
import { execSync } from 'child_process';
import { join } from 'path';
import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager';
import { fileExists } from '../utils/workspace-root';
import { readJsonFile, writeJsonFile } from '../utils/fileutils';
export function initHandler() {
const nxIsInstalled = !!execSync(getPackageManagerCommand().list)
.toString()
.split('\n')
.find((line) => line.indexOf(' nx@') > -1);
if (nxIsInstalled) {
output.log({
title: 'Nx is already installed',
});
} else {
output.log({
title: 'Installing Nx...',
});
execSync(`${getPackageManagerCommand().addDev} nx@latest`, {
stdio: [0, 1, 2],
});
output.success({
title: 'Nx has been installed',
});
}
if (!fileExists('nx.json')) {
writeJsonFile(
'nx.json',
readJsonFile(join(__dirname, '..', '..', 'presets', 'core.json'))
);
output.success({
title: 'nx.json has been created',
});
}
}

View File

@ -1,5 +1,6 @@
import { WorkspaceIntegrityChecks } from './workspace-integrity-checks'; import { WorkspaceIntegrityChecks } from './workspace-integrity-checks';
import { FileData, workspaceLayout } from '../project-graph/file-utils'; import { FileData } from '../project-graph/file-utils';
import { workspaceLayout } from '../config/configuration';
import { output } from '../utils/output'; import { output } from '../utils/output';
import * as path from 'path'; import * as path from 'path';
import { createProjectGraphAsync } from '../project-graph/project-graph'; import { createProjectGraphAsync } from '../project-graph/project-graph';

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { output } from '../utils/output'; import { output } from '../utils/output';
import { import {
fetchCommunityPlugins, fetchCommunityPlugins,

View File

@ -5,7 +5,7 @@ import * as yargs from 'yargs';
import { generateDaemonHelpOutput } from '../daemon/client/generate-help-output'; import { generateDaemonHelpOutput } from '../daemon/client/generate-help-output';
import { nxVersion } from '../utils/versions'; import { nxVersion } from '../utils/versions';
import { examples } from './examples'; import { examples } from './examples';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { getPackageManagerCommand } from '../utils/package-manager'; import { getPackageManagerCommand } from '../utils/package-manager';
import { writeJsonFile } from '../utils/fileutils'; import { writeJsonFile } from '../utils/fileutils';
@ -270,6 +270,11 @@ ${daemonHelpOutput}
'Reports useful version numbers to copy into the Nx issue template', 'Reports useful version numbers to copy into the Nx issue template',
handler: async () => (await import('./report')).reportHandler(), handler: async () => (await import('./report')).reportHandler(),
}) })
.command({
command: 'init',
describe: 'Adds nx.json file and installs nx if not installed already',
handler: async () => (await import('./init')).initHandler(),
})
.command({ .command({
command: 'list [plugin]', command: 'list [plugin]',
describe: describe:

View File

@ -1,5 +1,8 @@
import { readNxJson, readWorkspaceJson } from '../project-graph/file-utils';
import { NxJsonConfiguration } from '../config/nx-json'; import { NxJsonConfiguration } from '../config/nx-json';
import {
readNxJson,
readAllWorkspaceConfiguration,
} from '../config/configuration';
export interface Environment { export interface Environment {
nxJson: NxJsonConfiguration; nxJson: NxJsonConfiguration;
@ -14,6 +17,6 @@ export interface Environment {
export function readEnvironment(): Environment { export function readEnvironment(): Environment {
const nxJson = readNxJson(); const nxJson = readNxJson();
const workspaceJson = readWorkspaceJson(); const workspaceJson = readAllWorkspaceConfiguration();
return { nxJson, workspaceJson, workspaceResults: null } as any; return { nxJson, workspaceJson, workspaceResults: null } as any;
} }

View File

@ -1,7 +1,7 @@
// import * as devkit from '@nrwl/devkit'; // import * as devkit from '@nrwl/devkit';
import * as fileUtils from '../utils/fileutils'; import * as fileUtils from '../utils/fileutils';
jest.mock('nx/src/utils/app-root', () => ({ jest.mock('nx/src/utils/workspace-root', () => ({
workspaceRoot: '', workspaceRoot: '',
})); }));

View File

@ -1,5 +1,5 @@
import * as chalk from 'chalk'; import * as chalk from 'chalk';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { output } from '../utils/output'; import { output } from '../utils/output';
import { join } from 'path'; import { join } from 'path';
import { import {

View File

@ -12,16 +12,18 @@ import { readEnvironment } from './read-environment';
export async function runMany(parsedArgs: yargs.Arguments & RawNxArgs) { export async function runMany(parsedArgs: yargs.Arguments & RawNxArgs) {
performance.mark('command-execution-begins'); performance.mark('command-execution-begins');
const env = readEnvironment();
const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides( const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides(
parsedArgs, parsedArgs,
'run-many' 'run-many',
{ printWarnings: true },
env.nxJson
); );
await connectToNxCloudUsingScan(nxArgs.scan); await connectToNxCloudUsingScan(nxArgs.scan);
const projectGraph = await createProjectGraphAsync(); const projectGraph = await createProjectGraphAsync();
const projects = projectsToRun(nxArgs, projectGraph); const projects = projectsToRun(nxArgs, projectGraph);
const env = readEnvironment();
await runCommand(projects, projectGraph, env, nxArgs, overrides, null); await runCommand(projects, projectGraph, env, nxArgs, overrides, null);
} }

View File

@ -5,11 +5,11 @@ import { performance } from 'perf_hooks';
import { createProjectGraphAsync } from '../project-graph/project-graph'; import { createProjectGraphAsync } from '../project-graph/project-graph';
import { ProjectGraph } from '../config/project-graph'; import { ProjectGraph } from '../config/project-graph';
import { NxJsonConfiguration } from '../config/nx-json'; import { NxJsonConfiguration } from '../config/nx-json';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { splitTarget } from '../utils/split-target'; import { splitTarget } from '../utils/split-target';
import { output } from '../utils/output'; import { output } from '../utils/output';
import { readEnvironment } from './read-environment'; import { readEnvironment } from './read-environment';
import { WorkspaceJsonConfiguration } from '../config/workspace-json-project-json'; import { ProjectsConfigurations } from '../config/workspace-json-project-json';
export async function runOne( export async function runOne(
cwd: string, cwd: string,
@ -27,7 +27,9 @@ export async function runOne(
configuration: opts.configuration, configuration: opts.configuration,
target: opts.target, target: opts.target,
}, },
'run-one' 'run-one',
{ printWarnings: true },
env.nxJson
); );
if (nxArgs.help) { if (nxArgs.help) {
@ -79,7 +81,7 @@ const targetAliases = {
function parseRunOneOptions( function parseRunOneOptions(
cwd: string, cwd: string,
parsedArgs: { [k: string]: any }, parsedArgs: { [k: string]: any },
workspaceConfiguration: WorkspaceJsonConfiguration & NxJsonConfiguration workspaceConfiguration: ProjectsConfigurations & NxJsonConfiguration
): { project; target; configuration; parsedArgs } { ): { project; target; configuration; parsedArgs } {
const defaultProjectName = calculateDefaultProjectName( const defaultProjectName = calculateDefaultProjectName(
cwd, cwd,
@ -135,7 +137,7 @@ function parseRunOneOptions(
function calculateDefaultProjectName( function calculateDefaultProjectName(
cwd: string, cwd: string,
root: string, root: string,
workspaceConfiguration: WorkspaceJsonConfiguration & NxJsonConfiguration workspaceConfiguration: ProjectsConfigurations & NxJsonConfiguration
) { ) {
let relativeCwd = cwd.replace(/\\/g, '/').split(root.replace(/\\/g, '/'))[1]; let relativeCwd = cwd.replace(/\\/g, '/').split(root.replace(/\\/g, '/'))[1];
if (relativeCwd) { if (relativeCwd) {

View File

@ -17,7 +17,7 @@ import {
import { import {
ProjectConfiguration, ProjectConfiguration,
TargetConfiguration, TargetConfiguration,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '../config/workspace-json-project-json'; } from '../config/workspace-json-project-json';
import { Executor, ExecutorContext } from '../config/misc-interfaces'; import { Executor, ExecutorContext } from '../config/misc-interfaces';
@ -39,7 +39,7 @@ export function printRunHelp(
} }
export function validateProject( export function validateProject(
workspace: WorkspaceJsonConfiguration, workspace: ProjectsConfigurations,
projectName: string projectName: string
) { ) {
const project = workspace.projects[projectName]; const project = workspace.projects[projectName];
@ -126,7 +126,7 @@ async function runExecutorInternal<T extends { success: boolean }>(
options: { [k: string]: any }, options: { [k: string]: any },
root: string, root: string,
cwd: string, cwd: string,
workspace: WorkspaceJsonConfiguration & NxJsonConfiguration, workspace: ProjectsConfigurations & NxJsonConfiguration,
isVerbose: boolean, isVerbose: boolean,
printHelp: boolean printHelp: boolean
): Promise<AsyncIterableIterator<T>> { ): Promise<AsyncIterableIterator<T>> {

View File

@ -4,7 +4,7 @@ import { readdirSync, existsSync } from 'fs';
import { copySync, removeSync } from 'fs-extra'; import { copySync, removeSync } from 'fs-extra';
import * as path from 'path'; import * as path from 'path';
import * as yargsParser from 'yargs-parser'; import * as yargsParser from 'yargs-parser';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { fileExists } from '../utils/fileutils'; import { fileExists } from '../utils/fileutils';
import { output } from '../utils/output'; import { output } from '../utils/output';
import type { CompilerOptions } from 'typescript'; import type { CompilerOptions } from 'typescript';

View File

@ -0,0 +1,24 @@
import { Workspaces } from './workspaces';
import { workspaceRoot } from '../utils/workspace-root';
import { NxJsonConfiguration } from './nx-json';
import { ProjectsConfigurations } from './workspace-json-project-json';
export function readNxJson(): NxJsonConfiguration {
return new Workspaces(workspaceRoot).readNxJson();
}
export function readAllWorkspaceConfiguration(): ProjectsConfigurations &
NxJsonConfiguration {
return new Workspaces(workspaceRoot).readWorkspaceConfiguration();
}
/**
* Returns information about where apps and libs will be created.
*/
export function workspaceLayout(): { appsDir: string; libsDir: string } {
const nxJson = readNxJson();
return {
appsDir: nxJson.workspaceLayout?.appsDir ?? 'apps',
libsDir: nxJson.workspaceLayout?.libsDir ?? 'libs',
};
}

View File

@ -3,7 +3,7 @@ import { ProjectGraph } from './project-graph';
import { Task, TaskGraph } from './task-graph'; import { Task, TaskGraph } from './task-graph';
import { import {
TargetConfiguration, TargetConfiguration,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from './workspace-json-project-json'; } from './workspace-json-project-json';
import type { NxJsonConfiguration } from './nx-json'; import type { NxJsonConfiguration } from './nx-json';
@ -107,7 +107,7 @@ export interface HasherContext {
hasher: Hasher; hasher: Hasher;
projectGraph: ProjectGraph<any>; projectGraph: ProjectGraph<any>;
taskGraph: TaskGraph; taskGraph: TaskGraph;
workspaceConfig: WorkspaceJsonConfiguration & NxJsonConfiguration; workspaceConfig: ProjectsConfigurations & NxJsonConfiguration;
} }
export type CustomHasher = ( export type CustomHasher = (
@ -166,7 +166,7 @@ export interface ExecutorContext {
/** /**
* The full workspace configuration * The full workspace configuration
*/ */
workspace: WorkspaceJsonConfiguration & NxJsonConfiguration; workspace: ProjectsConfigurations & NxJsonConfiguration;
/** /**
* The current working directory * The current working directory

View File

@ -1,15 +1,18 @@
import type { NxJsonConfiguration } from './nx-json'; import type { NxJsonConfiguration } from './nx-json';
export interface Workspace export interface Workspace extends ProjectsConfigurations, NxJsonConfiguration {
extends WorkspaceJsonConfiguration,
NxJsonConfiguration {
projects: Record<string, ProjectConfiguration>; projects: Record<string, ProjectConfiguration>;
} }
/** /**
* Workspace configuration * @deprecated use ProjectsConfigurations
*/ */
export interface WorkspaceJsonConfiguration { export type WorkspaceJsonConfiguration = ProjectsConfigurations;
/**
* Projects Configurations
*/
export interface ProjectsConfigurations {
/** /**
* Version of the configuration format * Version of the configuration format
*/ */
@ -22,8 +25,8 @@ export interface WorkspaceJsonConfiguration {
}; };
} }
export interface RawWorkspaceJsonConfiguration export interface RawProjectsConfigurations
extends Omit<WorkspaceJsonConfiguration, 'projects'> { extends Omit<ProjectsConfigurations, 'projects'> {
projects: { [projectName: string]: ProjectConfiguration | string }; projects: { [projectName: string]: ProjectConfiguration | string };
} }

View File

@ -5,7 +5,7 @@ import * as path from 'path';
import { basename, dirname, join } from 'path'; import { basename, dirname, join } from 'path';
import { performance } from 'perf_hooks'; import { performance } from 'perf_hooks';
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { readJsonFile } from '../utils/fileutils'; import { readJsonFile } from '../utils/fileutils';
import { logger } from '../utils/logger'; import { logger } from '../utils/logger';
import { loadNxPlugins, readPluginPackageJson } from '../utils/nx-plugin'; import { loadNxPlugins, readPluginPackageJson } from '../utils/nx-plugin';
@ -13,7 +13,7 @@ import { loadNxPlugins, readPluginPackageJson } from '../utils/nx-plugin';
import type { NxJsonConfiguration } from './nx-json'; import type { NxJsonConfiguration } from './nx-json';
import { import {
ProjectConfiguration, ProjectConfiguration,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from './workspace-json-project-json'; } from './workspace-json-project-json';
import { import {
Executor, Executor,
@ -38,8 +38,7 @@ export function workspaceConfigName(root: string) {
} }
export class Workspaces { export class Workspaces {
private cachedWorkspaceConfig: WorkspaceJsonConfiguration & private cachedWorkspaceConfig: ProjectsConfigurations & NxJsonConfiguration;
NxJsonConfiguration;
constructor(private root: string) {} constructor(private root: string) {}
@ -49,7 +48,7 @@ export class Workspaces {
calculateDefaultProjectName( calculateDefaultProjectName(
cwd: string, cwd: string,
wc: WorkspaceJsonConfiguration & NxJsonConfiguration wc: ProjectsConfigurations & NxJsonConfiguration
) { ) {
const relativeCwd = this.relativeCwd(cwd); const relativeCwd = this.relativeCwd(cwd);
if (relativeCwd) { if (relativeCwd) {
@ -67,10 +66,9 @@ export class Workspaces {
readWorkspaceConfiguration(opts?: { readWorkspaceConfiguration(opts?: {
_ignorePluginInference?: boolean; _ignorePluginInference?: boolean;
}): WorkspaceJsonConfiguration & NxJsonConfiguration { }): ProjectsConfigurations & NxJsonConfiguration {
if (this.cachedWorkspaceConfig) return this.cachedWorkspaceConfig; if (this.cachedWorkspaceConfig) return this.cachedWorkspaceConfig;
const nxJsonPath = path.join(this.root, 'nx.json'); const nxJson = this.readNxJson();
const nxJson = readNxJson(nxJsonPath);
const workspaceFile = workspaceConfigName(this.root); const workspaceFile = workspaceConfigName(this.root);
const workspacePath = workspaceFile const workspacePath = workspaceFile
? path.join(this.root, workspaceFile) ? path.join(this.root, workspaceFile)
@ -179,6 +177,31 @@ export class Workspaces {
} }
} }
readNxJson(): NxJsonConfiguration {
const nxJson = path.join(this.root, 'nx.json');
if (existsSync(nxJson)) {
const nxJsonConfig = readJsonFile<NxJsonConfiguration>(nxJson);
if (nxJsonConfig.extends) {
const extendedNxJsonPath = require.resolve(nxJsonConfig.extends, {
paths: [dirname(nxJson)],
});
const baseNxJson =
readJsonFile<NxJsonConfiguration>(extendedNxJsonPath);
return { ...baseNxJson, ...nxJsonConfig };
} else {
return nxJsonConfig;
}
} else {
try {
return readJsonFile(
join(__dirname, '..', '..', 'presets', 'core.json')
);
} catch (e) {
return {};
}
}
}
private getImplementationFactory<T>( private getImplementationFactory<T>(
implementation: string, implementation: string,
directory: string directory: string
@ -326,7 +349,7 @@ export function reformattedWorkspaceJsonOrNull(w: any) {
return workspaceJson; return workspaceJson;
} }
export function toNewFormat(w: any): WorkspaceJsonConfiguration { export function toNewFormat(w: any): ProjectsConfigurations {
const f = toNewFormatOrNull(w); const f = toNewFormatOrNull(w);
return f ?? w; return f ?? w;
} }
@ -431,22 +454,6 @@ function inlineProjectConfigurations(w: any, root: string = workspaceRoot) {
/** /**
* Reads an nx.json file from a given path or extends a local nx.json config. * Reads an nx.json file from a given path or extends a local nx.json config.
*/ */
function readNxJson(nxJson: string): NxJsonConfiguration {
let nxJsonConfig: NxJsonConfiguration;
if (existsSync(nxJson)) {
nxJsonConfig = readJsonFile<NxJsonConfiguration>(nxJson);
} else {
nxJsonConfig = {} as NxJsonConfiguration;
}
if (nxJsonConfig.extends) {
const extendedNxJsonPath = require.resolve(nxJsonConfig.extends, {
paths: [dirname(nxJson)],
});
const baseNxJson = readJsonFile<NxJsonConfiguration>(extendedNxJsonPath);
nxJsonConfig = { ...baseNxJson, ...nxJsonConfig };
}
return nxJsonConfig;
}
/** /**
* Pulled from toFileName in names from @nrwl/devkit. * Pulled from toFileName in names from @nrwl/devkit.
@ -641,7 +648,7 @@ export function buildWorkspaceConfigurationFromGlobs(
nxJson: NxJsonConfiguration, nxJson: NxJsonConfiguration,
projectFiles: string[], // making this parameter allows devkit to pick up newly created projects projectFiles: string[], // making this parameter allows devkit to pick up newly created projects
readJson: (string) => any = readJsonFile // making this an arg allows us to reuse in devkit readJson: (string) => any = readJsonFile // making this an arg allows us to reuse in devkit
): WorkspaceJsonConfiguration { ): ProjectsConfigurations {
const projects: Record<string, ProjectConfiguration> = {}; const projects: Record<string, ProjectConfiguration> = {};
for (const file of projectFiles) { for (const file of projectFiles) {

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../../utils/app-root'; import { workspaceRoot } from '../../utils/workspace-root';
import { ChildProcess, spawn, spawnSync } from 'child_process'; import { ChildProcess, spawn, spawnSync } from 'child_process';
import { openSync, readFileSync } from 'fs'; import { openSync, readFileSync } from 'fs';
import { ensureDirSync, ensureFileSync } from 'fs-extra'; import { ensureDirSync, ensureFileSync } from 'fs-extra';

View File

@ -1,5 +1,5 @@
import { performance } from 'perf_hooks'; import { performance } from 'perf_hooks';
import { readWorkspaceJson } from '../../project-graph/file-utils'; import { readAllWorkspaceConfiguration } from '../../config/configuration';
import { defaultFileHasher } from '../../hasher/file-hasher'; import { defaultFileHasher } from '../../hasher/file-hasher';
import { serverLogger } from './logger'; import { serverLogger } from './logger';
import { buildProjectGraphUsingProjectFileMap } from '../../project-graph/build-project-graph'; import { buildProjectGraphUsingProjectFileMap } from '../../project-graph/build-project-graph';
@ -101,7 +101,7 @@ async function processCollectedUpdatedAndDeletedFiles() {
'hash-watched-changes-end' 'hash-watched-changes-end'
); );
defaultFileHasher.incrementalUpdate(updatedFiles, deletedFiles); defaultFileHasher.incrementalUpdate(updatedFiles, deletedFiles);
const workspaceJson = readWorkspaceJson(); const workspaceJson = readAllWorkspaceConfiguration();
const workspaceConfigHash = computeWorkspaceConfigHash(workspaceJson); const workspaceConfigHash = computeWorkspaceConfigHash(workspaceJson);
serverLogger.requestLog( serverLogger.requestLog(
`Updated file-hasher based on watched changes, recomputing project graph...` `Updated file-hasher based on watched changes, recomputing project graph...`
@ -170,7 +170,7 @@ function copyFileMap(m: ProjectFileMap) {
async function createAndSerializeProjectGraph() { async function createAndSerializeProjectGraph() {
try { try {
performance.mark('create-project-graph-start'); performance.mark('create-project-graph-start');
const workspaceJson = readWorkspaceJson(); const workspaceJson = readAllWorkspaceConfiguration();
const { projectGraph, projectGraphCache } = const { projectGraph, projectGraphCache } =
await buildProjectGraphUsingProjectFileMap( await buildProjectGraphUsingProjectFileMap(
workspaceJson, workspaceJson,

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../../utils/app-root'; import { workspaceRoot } from '../../utils/workspace-root';
import { createServer, Server, Socket } from 'net'; import { createServer, Server, Socket } from 'net';
import { join } from 'path'; import { join } from 'path';
import { performance, PerformanceObserver } from 'perf_hooks'; import { performance, PerformanceObserver } from 'perf_hooks';

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../../utils/app-root'; import { workspaceRoot } from '../../utils/workspace-root';
import type { Server } from 'net'; import type { Server } from 'net';
import { serverLogger } from './logger'; import { serverLogger } from './logger';
import type { WatcherSubscription } from './watcher'; import type { WatcherSubscription } from './watcher';

View File

@ -5,7 +5,7 @@
* *
* See https://github.com/parcel-bundler/watcher for more details. * See https://github.com/parcel-bundler/watcher for more details.
*/ */
import { workspaceRoot } from '../../utils/app-root'; import { workspaceRoot } from '../../utils/workspace-root';
import type { AsyncSubscription, Event } from '@parcel/watcher'; import type { AsyncSubscription, Event } from '@parcel/watcher';
import { readFileSync } from 'fs'; import { readFileSync } from 'fs';
import { join, relative } from 'path'; import { join, relative } from 'path';

View File

@ -2,8 +2,8 @@ import { basename, dirname, join, relative } from 'path';
import type { NxJsonConfiguration } from '../../config/nx-json'; import type { NxJsonConfiguration } from '../../config/nx-json';
import { import {
ProjectConfiguration, ProjectConfiguration,
RawWorkspaceJsonConfiguration, RawProjectsConfigurations,
WorkspaceJsonConfiguration, ProjectsConfigurations,
} from '../../config/workspace-json-project-json'; } from '../../config/workspace-json-project-json';
import { import {
buildWorkspaceConfigurationFromGlobs, buildWorkspaceConfigurationFromGlobs,
@ -18,10 +18,7 @@ import type { Tree } from '../tree';
import { readJson, updateJson, writeJson } from './json'; import { readJson, updateJson, writeJson } from './json';
export type WorkspaceConfiguration = Omit< export type WorkspaceConfiguration = Omit<ProjectsConfigurations, 'projects'> &
WorkspaceJsonConfiguration,
'projects'
> &
Partial<NxJsonConfiguration>; Partial<NxJsonConfiguration>;
/** /**
@ -181,7 +178,7 @@ export function updateWorkspaceConfiguration(
// in project config. // in project config.
const workspacePath = getWorkspacePath(tree); const workspacePath = getWorkspacePath(tree);
if (workspacePath) { if (workspacePath) {
updateJson<WorkspaceJsonConfiguration>(tree, workspacePath, (json) => { updateJson<ProjectsConfigurations>(tree, workspacePath, (json) => {
const config = { const config = {
...json, ...json,
version: workspaceConfig.version, version: workspaceConfig.version,
@ -257,7 +254,7 @@ export function isStandaloneProject(tree: Tree, project: string): boolean {
const path = getWorkspacePath(tree); const path = getWorkspacePath(tree);
const rawWorkspace = const rawWorkspace =
path && tree.exists(path) path && tree.exists(path)
? readJson<RawWorkspaceJsonConfiguration>(tree, path) ? readJson<RawProjectsConfigurations>(tree, path)
: null; : null;
if (rawWorkspace) { if (rawWorkspace) {
const projectConfig = rawWorkspace.projects?.[project]; const projectConfig = rawWorkspace.projects?.[project];
@ -268,7 +265,7 @@ export function isStandaloneProject(tree: Tree, project: string): boolean {
function getProjectConfiguration( function getProjectConfiguration(
projectName: string, projectName: string,
workspace: WorkspaceJsonConfiguration workspace: ProjectsConfigurations
): ProjectConfiguration { ): ProjectConfiguration {
return { return {
...readWorkspaceSection(workspace, projectName), ...readWorkspaceSection(workspace, projectName),
@ -276,7 +273,7 @@ function getProjectConfiguration(
} }
function readWorkspaceSection( function readWorkspaceSection(
workspace: WorkspaceJsonConfiguration, workspace: ProjectsConfigurations,
projectName: string projectName: string
) { ) {
return workspace.projects[projectName]; return workspace.projects[projectName];
@ -391,7 +388,7 @@ function addProjectToWorkspaceJson(
/** /**
* Read the workspace configuration, including projects. * Read the workspace configuration, including projects.
*/ */
export function readWorkspace(tree: Tree): WorkspaceJsonConfiguration { export function readWorkspace(tree: Tree): ProjectsConfigurations {
const workspaceJson = inlineProjectConfigurationsWithTree(tree); const workspaceJson = inlineProjectConfigurationsWithTree(tree);
const originalVersion = workspaceJson.version; const originalVersion = workspaceJson.version;
return { return {
@ -408,7 +405,7 @@ export function readWorkspace(tree: Tree): WorkspaceJsonConfiguration {
*/ */
function inlineProjectConfigurationsWithTree( function inlineProjectConfigurationsWithTree(
tree: Tree tree: Tree
): WorkspaceJsonConfiguration { ): ProjectsConfigurations {
const workspaceJson = readRawWorkspaceJson(tree); const workspaceJson = readRawWorkspaceJson(tree);
Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => { Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => {
if (typeof config === 'string') { if (typeof config === 'string') {
@ -419,7 +416,7 @@ function inlineProjectConfigurationsWithTree(
}; };
} }
}); });
return workspaceJson as WorkspaceJsonConfiguration; return workspaceJson as ProjectsConfigurations;
} }
/** /**
@ -458,12 +455,12 @@ function findDeletedProjects(tree: Tree) {
}); });
} }
let staticFSWorkspace: RawWorkspaceJsonConfiguration; let staticFSWorkspace: RawProjectsConfigurations;
function readRawWorkspaceJson(tree: Tree): RawWorkspaceJsonConfiguration { function readRawWorkspaceJson(tree: Tree): RawProjectsConfigurations {
const path = getWorkspacePath(tree); const path = getWorkspacePath(tree);
if (path && tree.exists(path)) { if (path && tree.exists(path)) {
// `workspace.json` exists, use it. // `workspace.json` exists, use it.
return readJson<RawWorkspaceJsonConfiguration>(tree, path); return readJson<RawProjectsConfigurations>(tree, path);
} else { } else {
const nxJson = readNxJson(tree); const nxJson = readNxJson(tree);
const createdProjects = buildWorkspaceConfigurationFromGlobs( const createdProjects = buildWorkspaceConfigurationFromGlobs(
@ -513,10 +510,7 @@ function getProjectFileLocation(tree: Tree, project: string): string | null {
function validateProjectConfigurationOperationsGivenWorkspaceJson( function validateProjectConfigurationOperationsGivenWorkspaceJson(
mode: 'create' | 'update' | 'delete', mode: 'create' | 'update' | 'delete',
workspaceJson: workspaceJson: RawProjectsConfigurations | ProjectsConfigurations | null,
| RawWorkspaceJsonConfiguration
| WorkspaceJsonConfiguration
| null,
projectName: string projectName: string
) { ) {
if (mode == 'create' && workspaceJson.projects[projectName]) { if (mode == 'create' && workspaceJson.projects[projectName]) {
@ -569,7 +563,7 @@ export function shouldDefaultToUsingStandaloneConfigs(tree: Tree): boolean {
const workspacePath = getWorkspacePath(tree); const workspacePath = getWorkspacePath(tree);
const rawWorkspace = const rawWorkspace =
workspacePath && tree.exists(workspacePath) workspacePath && tree.exists(workspacePath)
? readJson<RawWorkspaceJsonConfiguration>(tree, workspacePath) ? readJson<RawProjectsConfigurations>(tree, workspacePath)
: null; : null;
return !rawWorkspace return !rawWorkspace
? true // if workspace.json doesn't exist, all projects **must** be standalone ? true // if workspace.json doesn't exist, all projects **must** be standalone

View File

@ -1,4 +1,4 @@
import { workspaceRoot } from '../utils/app-root'; import { workspaceRoot } from '../utils/workspace-root';
import { performance } from 'perf_hooks'; import { performance } from 'perf_hooks';
import { defaultHashing } from './hashing-impl'; import { defaultHashing } from './hashing-impl';
import { FileData } from '../config/project-graph'; import { FileData } from '../config/project-graph';

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