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": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"outputs": [],
"options": {
"commands": [
@ -113,7 +113,7 @@
}
},
"serve-for-e2e": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"outputs": [],
"options": {
"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)
- [NxJsonConfiguration](../../devkit/index#nxjsonconfiguration)
- [ProjectConfiguration](../../devkit/index#projectconfiguration)
- [ProjectsConfigurations](../../devkit/index#projectsconfigurations)
- [TargetConfiguration](../../devkit/index#targetconfiguration)
- [TargetDependencyConfig](../../devkit/index#targetdependencyconfig)
- [Task](../../devkit/index#task)
- [TaskGraph](../../devkit/index#taskgraph)
- [Workspace](../../devkit/index#workspace)
- [WorkspaceJsonConfiguration](../../devkit/index#workspacejsonconfiguration)
### Generators Type aliases
@ -112,6 +112,7 @@ It only uses language primitives and immutable objects
- [ImplicitDependencyEntry](../../devkit/index#implicitdependencyentry)
- [ProjectType](../../devkit/index#projecttype)
- [TaskGraphExecutor](../../devkit/index#taskgraphexecutor)
- [WorkspaceJsonConfiguration](../../devkit/index#workspacejsonconfiguration)
### Logger Variables
@ -151,6 +152,7 @@ It only uses language primitives and immutable objects
- [offsetFromRoot](../../devkit/index#offsetfromroot)
- [parseJson](../../devkit/index#parsejson)
- [parseTargetString](../../devkit/index#parsetargetstring)
- [readAllWorkspaceConfiguration](../../devkit/index#readallworkspaceconfiguration)
- [readCachedProjectGraph](../../devkit/index#readcachedprojectgraph)
- [readJson](../../devkit/index#readjson)
- [readJsonFile](../../devkit/index#readjsonfile)
@ -424,6 +426,12 @@ A plugin for Nx
---
### ProjectsConfigurations
**ProjectsConfigurations**: `Object`
---
### TargetConfiguration
**TargetConfiguration**: `Object`
@ -452,17 +460,11 @@ A plugin for Nx
**Workspace**: `Object`
---
### WorkspaceJsonConfiguration
**WorkspaceJsonConfiguration**: `Object`
## Generators Type aliases
### 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`\>\>
---
### WorkspaceJsonConfiguration
Ƭ **WorkspaceJsonConfiguration**: [`ProjectsConfigurations`](../../devkit/index#projectsconfigurations)
## Logger Variables
### logger
@ -689,7 +697,7 @@ Implementation of a target of a project that handles multiple projects to be bat
### 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**: `string` = `appRootPath`
**workspaceRoot**: `string`
## 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**(): [`ProjectGraph`](../../devkit/index#projectgraph)
@ -1426,17 +1444,7 @@ Object the JSON content of the file represents
### readNxJson
**readNxJson**(`path?`): [`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` |
**readNxJson**(): [`NxJsonConfiguration`](../../devkit/index#nxjsonconfiguration)
#### Returns

View File

@ -11,6 +11,12 @@
"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"
},
{
"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",
"id": "generate",

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

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

View File

@ -23,12 +23,20 @@ describe('add-nx-to-monorepo', () => {
'packages/package-a/package.json',
JSON.stringify({
name: 'package-a',
scripts: {
serve: 'some serve',
build: 'some build',
test: 'some test',
},
})
);
updateFile(
'packages/package-b/package.json',
JSON.stringify({
name: 'package-b',
scripts: {
lint: 'some lint',
},
})
);
@ -40,6 +48,13 @@ describe('add-nx-to-monorepo', () => {
expect(output).toContain('🎉 Done!');
expect(readWorkspaceConfig().projects['package-a']).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",
"targets": {
"e2e": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"options": {
"commands": [
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,7 +4,7 @@
"projectType": "application",
"targets": {
"e2e": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"options": {
"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",
"targets": {
"e2e": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"options": {
"commands": [
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,8 @@
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 { BuilderContext, createBuilder } from '@angular-devkit/architect';
import { JsonObject } from '@angular-devkit/core';
@ -59,9 +62,7 @@ export function executeModuleFederationDevServerBuilder(
schema: Schema,
context: BuilderContext
) {
const workspaces = new Workspaces(context.workspaceRoot);
const workspaceConfig = workspaces.readWorkspaceConfiguration();
const workspaceConfig = readAllWorkspaceConfiguration();
const p = workspaceConfig.projects[context.target.project];
const mfConfigPath = join(

View File

@ -4,7 +4,12 @@ import {
serveWebpackBrowser,
} from '@angular-devkit/build-angular/src/builders/dev-server';
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 { merge } from 'webpack-merge';
import { resolveCustomWebpackConfig } from '../utilities/webpack';
@ -21,9 +26,7 @@ export function executeWebpackServerBuilder(
);
const options = normalizeOptions(schema);
const workspaceConfig = new Workspaces(
context.workspaceRoot
).readWorkspaceConfiguration();
const workspaceConfig = readAllWorkspaceConfiguration();
const parsedBrowserTarget = parseTargetString(options.browserTarget);
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 {
createProjectGraphAsync,
ProjectGraph,
readAllWorkspaceConfiguration,
readCachedProjectGraph,
workspaceRoot,
Workspaces,
} from '@nrwl/devkit';
import {
getRootTsConfigPath,
readTsConfig,
} from '@nrwl/workspace/src/utilities/typescript';
import { ParsedCommandLine } from 'typescript';
import { readWorkspaceJson } from 'nx/src/project-graph/file-utils';
import { readRootPackageJson } from './utils';
import { extname, join } from 'path';
import ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin');
@ -71,9 +69,7 @@ function collectDependencies(
}
function mapWorkspaceLibrariesToTsConfigImport(workspaceLibraries: string[]) {
const { projects } = new Workspaces(
workspaceRoot
).readWorkspaceConfiguration();
const { projects } = readAllWorkspaceConfiguration();
const tsConfigPath = process.env.NX_TSCONFIG_PATH ?? getRootTsConfigPath();
const tsConfig: ParsedCommandLine = readTsConfig(tsConfigPath);
@ -123,7 +119,7 @@ async function getDependentPackagesForProject(
}
function determineRemoteUrl(remote: string) {
const workspace = readWorkspaceJson();
const workspace = readAllWorkspaceConfiguration();
let publicHost = '';
try {
publicHost = workspace.projects[remote].targets.serve.options.publicHost;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
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';
const JEST_RUNNER_TOKEN = '@nrwl/jest:jest';
@ -11,7 +11,7 @@ function getJestConfigProjectPath(projectJestConfigPath: string): string {
export function getJestProjects() {
const ws = readWorkspaceConfig({
format: 'nx',
}) as WorkspaceJsonConfiguration;
}) as ProjectsConfigurations;
const jestConfigurationSet = new Set();
for (const projectConfig of Object.values(ws.projects)) {
if (!projectConfig.targets) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -56,7 +56,7 @@
"outputs": ["{options.outputPath}"]
},
"build": {
"executor": "@nrwl/workspace:run-commands",
"executor": "nx:run-commands",
"outputs": ["build/packages/nx-plugin"],
"options": {
"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';
// 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;
} else {
const workspace = findWorkspaceRoot(process.cwd());
@ -27,6 +31,12 @@ if (process.argv[2] === 'new' || process.argv[2] === '_migrate') {
bodyLines: [
`To create a workspace run:`,
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"
},
"scripts": {
"postinstall": "node ./bin/init"
"postinstall": "node ./bin/compute-project-graph"
},
"keywords": [
"Monorepo",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import { readNxJson } from '../project-graph/file-utils';
import { output } from '../utils/output';
import { getPackageManagerCommand } from '../utils/package-manager';
import { execSync } from 'child_process';
import { readNxJson } from '../config/configuration';
export async function connectToNxCloudUsingScan(scan: boolean): Promise<void> {
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 { createHash } from 'crypto';
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 { performance } from 'perf_hooks';
import { URL, URLSearchParams } from 'url';
import { workspaceLayout } from '../project-graph/file-utils';
import { workspaceLayout } from '../config/configuration';
import { defaultFileHasher } from '../hasher/file-hasher';
import { output } from '../utils/output';
import { writeJsonFile } from '../utils/fileutils';

View File

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

View File

@ -8,7 +8,7 @@ import { Workspaces } from '../config/workspaces';
import { FileChange, flushChanges, FsTree } from '../generators/tree';
import { logger } from '../utils/logger';
import * as chalk from 'chalk';
import { workspaceRoot } from '../utils/app-root';
import { workspaceRoot } from '../utils/workspace-root';
import { NxJsonConfiguration } from '../config/nx-json';
import { printHelp } from '../utils/print-help';
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 { 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 * as path from 'path';
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 {
fetchCommunityPlugins,

View File

@ -5,7 +5,7 @@ import * as yargs from 'yargs';
import { generateDaemonHelpOutput } from '../daemon/client/generate-help-output';
import { nxVersion } from '../utils/versions';
import { examples } from './examples';
import { workspaceRoot } from '../utils/app-root';
import { workspaceRoot } from '../utils/workspace-root';
import { getPackageManagerCommand } from '../utils/package-manager';
import { writeJsonFile } from '../utils/fileutils';
@ -270,6 +270,11 @@ ${daemonHelpOutput}
'Reports useful version numbers to copy into the Nx issue template',
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: 'list [plugin]',
describe:

View File

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

View File

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

View File

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

View File

@ -12,16 +12,18 @@ import { readEnvironment } from './read-environment';
export async function runMany(parsedArgs: yargs.Arguments & RawNxArgs) {
performance.mark('command-execution-begins');
const env = readEnvironment();
const { nxArgs, overrides } = splitArgsIntoNxArgsAndOverrides(
parsedArgs,
'run-many'
'run-many',
{ printWarnings: true },
env.nxJson
);
await connectToNxCloudUsingScan(nxArgs.scan);
const projectGraph = await createProjectGraphAsync();
const projects = projectsToRun(nxArgs, projectGraph);
const env = readEnvironment();
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 { ProjectGraph } from '../config/project-graph';
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 { output } from '../utils/output';
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(
cwd: string,
@ -27,7 +27,9 @@ export async function runOne(
configuration: opts.configuration,
target: opts.target,
},
'run-one'
'run-one',
{ printWarnings: true },
env.nxJson
);
if (nxArgs.help) {
@ -79,7 +81,7 @@ const targetAliases = {
function parseRunOneOptions(
cwd: string,
parsedArgs: { [k: string]: any },
workspaceConfiguration: WorkspaceJsonConfiguration & NxJsonConfiguration
workspaceConfiguration: ProjectsConfigurations & NxJsonConfiguration
): { project; target; configuration; parsedArgs } {
const defaultProjectName = calculateDefaultProjectName(
cwd,
@ -135,7 +137,7 @@ function parseRunOneOptions(
function calculateDefaultProjectName(
cwd: string,
root: string,
workspaceConfiguration: WorkspaceJsonConfiguration & NxJsonConfiguration
workspaceConfiguration: ProjectsConfigurations & NxJsonConfiguration
) {
let relativeCwd = cwd.replace(/\\/g, '/').split(root.replace(/\\/g, '/'))[1];
if (relativeCwd) {

View File

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

View File

@ -4,7 +4,7 @@ import { readdirSync, existsSync } from 'fs';
import { copySync, removeSync } from 'fs-extra';
import * as path from 'path';
import * as yargsParser from 'yargs-parser';
import { workspaceRoot } from '../utils/app-root';
import { workspaceRoot } from '../utils/workspace-root';
import { fileExists } from '../utils/fileutils';
import { output } from '../utils/output';
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 {
TargetConfiguration,
WorkspaceJsonConfiguration,
ProjectsConfigurations,
} from './workspace-json-project-json';
import type { NxJsonConfiguration } from './nx-json';
@ -107,7 +107,7 @@ export interface HasherContext {
hasher: Hasher;
projectGraph: ProjectGraph<any>;
taskGraph: TaskGraph;
workspaceConfig: WorkspaceJsonConfiguration & NxJsonConfiguration;
workspaceConfig: ProjectsConfigurations & NxJsonConfiguration;
}
export type CustomHasher = (
@ -166,7 +166,7 @@ export interface ExecutorContext {
/**
* The full workspace configuration
*/
workspace: WorkspaceJsonConfiguration & NxJsonConfiguration;
workspace: ProjectsConfigurations & NxJsonConfiguration;
/**
* The current working directory

View File

@ -1,15 +1,18 @@
import type { NxJsonConfiguration } from './nx-json';
export interface Workspace
extends WorkspaceJsonConfiguration,
NxJsonConfiguration {
export interface Workspace extends ProjectsConfigurations, NxJsonConfiguration {
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
*/
@ -22,8 +25,8 @@ export interface WorkspaceJsonConfiguration {
};
}
export interface RawWorkspaceJsonConfiguration
extends Omit<WorkspaceJsonConfiguration, 'projects'> {
export interface RawProjectsConfigurations
extends Omit<ProjectsConfigurations, 'projects'> {
projects: { [projectName: string]: ProjectConfiguration | string };
}

View File

@ -5,7 +5,7 @@ import * as path from 'path';
import { basename, dirname, join } from 'path';
import { performance } from 'perf_hooks';
import { workspaceRoot } from '../utils/app-root';
import { workspaceRoot } from '../utils/workspace-root';
import { readJsonFile } from '../utils/fileutils';
import { logger } from '../utils/logger';
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 {
ProjectConfiguration,
WorkspaceJsonConfiguration,
ProjectsConfigurations,
} from './workspace-json-project-json';
import {
Executor,
@ -38,8 +38,7 @@ export function workspaceConfigName(root: string) {
}
export class Workspaces {
private cachedWorkspaceConfig: WorkspaceJsonConfiguration &
NxJsonConfiguration;
private cachedWorkspaceConfig: ProjectsConfigurations & NxJsonConfiguration;
constructor(private root: string) {}
@ -49,7 +48,7 @@ export class Workspaces {
calculateDefaultProjectName(
cwd: string,
wc: WorkspaceJsonConfiguration & NxJsonConfiguration
wc: ProjectsConfigurations & NxJsonConfiguration
) {
const relativeCwd = this.relativeCwd(cwd);
if (relativeCwd) {
@ -67,10 +66,9 @@ export class Workspaces {
readWorkspaceConfiguration(opts?: {
_ignorePluginInference?: boolean;
}): WorkspaceJsonConfiguration & NxJsonConfiguration {
}): ProjectsConfigurations & NxJsonConfiguration {
if (this.cachedWorkspaceConfig) return this.cachedWorkspaceConfig;
const nxJsonPath = path.join(this.root, 'nx.json');
const nxJson = readNxJson(nxJsonPath);
const nxJson = this.readNxJson();
const workspaceFile = workspaceConfigName(this.root);
const workspacePath = 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>(
implementation: string,
directory: string
@ -326,7 +349,7 @@ export function reformattedWorkspaceJsonOrNull(w: any) {
return workspaceJson;
}
export function toNewFormat(w: any): WorkspaceJsonConfiguration {
export function toNewFormat(w: any): ProjectsConfigurations {
const f = toNewFormatOrNull(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.
*/
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.
@ -641,7 +648,7 @@ export function buildWorkspaceConfigurationFromGlobs(
nxJson: NxJsonConfiguration,
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
): WorkspaceJsonConfiguration {
): ProjectsConfigurations {
const projects: Record<string, ProjectConfiguration> = {};
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 { openSync, readFileSync } from 'fs';
import { ensureDirSync, ensureFileSync } from 'fs-extra';

View File

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

View File

@ -5,7 +5,7 @@
*
* 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 { readFileSync } from 'fs';
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 {
ProjectConfiguration,
RawWorkspaceJsonConfiguration,
WorkspaceJsonConfiguration,
RawProjectsConfigurations,
ProjectsConfigurations,
} from '../../config/workspace-json-project-json';
import {
buildWorkspaceConfigurationFromGlobs,
@ -18,10 +18,7 @@ import type { Tree } from '../tree';
import { readJson, updateJson, writeJson } from './json';
export type WorkspaceConfiguration = Omit<
WorkspaceJsonConfiguration,
'projects'
> &
export type WorkspaceConfiguration = Omit<ProjectsConfigurations, 'projects'> &
Partial<NxJsonConfiguration>;
/**
@ -181,7 +178,7 @@ export function updateWorkspaceConfiguration(
// in project config.
const workspacePath = getWorkspacePath(tree);
if (workspacePath) {
updateJson<WorkspaceJsonConfiguration>(tree, workspacePath, (json) => {
updateJson<ProjectsConfigurations>(tree, workspacePath, (json) => {
const config = {
...json,
version: workspaceConfig.version,
@ -257,7 +254,7 @@ export function isStandaloneProject(tree: Tree, project: string): boolean {
const path = getWorkspacePath(tree);
const rawWorkspace =
path && tree.exists(path)
? readJson<RawWorkspaceJsonConfiguration>(tree, path)
? readJson<RawProjectsConfigurations>(tree, path)
: null;
if (rawWorkspace) {
const projectConfig = rawWorkspace.projects?.[project];
@ -268,7 +265,7 @@ export function isStandaloneProject(tree: Tree, project: string): boolean {
function getProjectConfiguration(
projectName: string,
workspace: WorkspaceJsonConfiguration
workspace: ProjectsConfigurations
): ProjectConfiguration {
return {
...readWorkspaceSection(workspace, projectName),
@ -276,7 +273,7 @@ function getProjectConfiguration(
}
function readWorkspaceSection(
workspace: WorkspaceJsonConfiguration,
workspace: ProjectsConfigurations,
projectName: string
) {
return workspace.projects[projectName];
@ -391,7 +388,7 @@ function addProjectToWorkspaceJson(
/**
* Read the workspace configuration, including projects.
*/
export function readWorkspace(tree: Tree): WorkspaceJsonConfiguration {
export function readWorkspace(tree: Tree): ProjectsConfigurations {
const workspaceJson = inlineProjectConfigurationsWithTree(tree);
const originalVersion = workspaceJson.version;
return {
@ -408,7 +405,7 @@ export function readWorkspace(tree: Tree): WorkspaceJsonConfiguration {
*/
function inlineProjectConfigurationsWithTree(
tree: Tree
): WorkspaceJsonConfiguration {
): ProjectsConfigurations {
const workspaceJson = readRawWorkspaceJson(tree);
Object.entries(workspaceJson.projects || {}).forEach(([project, config]) => {
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;
function readRawWorkspaceJson(tree: Tree): RawWorkspaceJsonConfiguration {
let staticFSWorkspace: RawProjectsConfigurations;
function readRawWorkspaceJson(tree: Tree): RawProjectsConfigurations {
const path = getWorkspacePath(tree);
if (path && tree.exists(path)) {
// `workspace.json` exists, use it.
return readJson<RawWorkspaceJsonConfiguration>(tree, path);
return readJson<RawProjectsConfigurations>(tree, path);
} else {
const nxJson = readNxJson(tree);
const createdProjects = buildWorkspaceConfigurationFromGlobs(
@ -513,10 +510,7 @@ function getProjectFileLocation(tree: Tree, project: string): string | null {
function validateProjectConfigurationOperationsGivenWorkspaceJson(
mode: 'create' | 'update' | 'delete',
workspaceJson:
| RawWorkspaceJsonConfiguration
| WorkspaceJsonConfiguration
| null,
workspaceJson: RawProjectsConfigurations | ProjectsConfigurations | null,
projectName: string
) {
if (mode == 'create' && workspaceJson.projects[projectName]) {
@ -569,7 +563,7 @@ export function shouldDefaultToUsingStandaloneConfigs(tree: Tree): boolean {
const workspacePath = getWorkspacePath(tree);
const rawWorkspace =
workspacePath && tree.exists(workspacePath)
? readJson<RawWorkspaceJsonConfiguration>(tree, workspacePath)
? readJson<RawProjectsConfigurations>(tree, workspacePath)
: null;
return !rawWorkspace
? 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 { defaultHashing } from './hashing-impl';
import { FileData } from '../config/project-graph';

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