diff --git a/docs/blog/2023-04-19-nx-cloud-3.md b/docs/blog/2023-04-19-nx-cloud-3.md index be1f5d202b..91b00839d1 100644 --- a/docs/blog/2023-04-19-nx-cloud-3.md +++ b/docs/blog/2023-04-19-nx-cloud-3.md @@ -18,6 +18,7 @@ In the last couple of months we have quadrupled the team and have done some amaz - [Enterprise Support](#enterprise-support) - [New, Simplified Plans and Pricing Model](#new-simplified-plans-and-pricing-model) - [Coming Next](#coming-next) +- [Learn more](#learn-more) **Prefer a Video? We’ve got you Covered!** @@ -39,7 +40,7 @@ More UI-related updates and improvements are already underway. ![](/blog/images/2023-04-19/bodyimg3.webp) -At Nx, we are performance addicts! Especially when it comes to local development, every millisecond counts! In the latest update of the Nx CLI, we added the ability to **offload some of the remote cache management to the [Nx Daemon](/concepts/more-concepts/nx-daemon)**. As a result you no longer have to wait for the cache to upload. This saves valuable time, allowing the command to complete instantly and immediately providing you with the necessary link. +At Nx, we are performance addicts! Especially when it comes to local development, every millisecond counts! In the latest update of the Nx CLI, we added the ability to **offload some of the remote cache management to the [Nx Daemon](/concepts/nx-daemon)**. As a result you no longer have to wait for the cache to upload. This saves valuable time, allowing the command to complete instantly and immediately providing you with the necessary link. We also **prefetch cache results in the background** to have them ready when needed. Both optimizations can save seconds. diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 7273a18b8f..db6b5edd3e 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -638,6 +638,30 @@ "children": [], "disableCollapsible": false }, + { + "name": "Nx Daemon", + "path": "/concepts/nx-daemon", + "id": "nx-daemon", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Nx and Turborepo", + "path": "/concepts/turbo-and-nx", + "id": "turbo-and-nx", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Buildable and Publishable Libraries", + "path": "/concepts/buildable-and-publishable-libraries", + "id": "buildable-and-publishable-libraries", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Module Federation", "path": "/concepts/module-federation", @@ -680,14 +704,22 @@ "disableCollapsible": false }, { - "name": "More Concepts", - "path": "/concepts/more-concepts", - "id": "more-concepts", + "name": "Organizational Decisions", + "path": "/concepts/decisions", + "id": "decisions", "isExternal": false, "children": [ + { + "name": "Overview", + "path": "/concepts/decisions/overview", + "id": "overview", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Monorepos", - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "id": "why-monorepos", "isExternal": false, "children": [], @@ -695,72 +727,40 @@ }, { "name": "Dependency Management", - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "id": "dependency-management", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Code Sharing", - "path": "/concepts/more-concepts/code-sharing", - "id": "code-sharing", + "name": "Code Ownership", + "path": "/concepts/decisions/code-ownership", + "id": "code-ownership", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx Daemon", - "path": "/concepts/more-concepts/nx-daemon", - "id": "nx-daemon", + "name": "Project Size", + "path": "/concepts/decisions/project-size", + "id": "project-size", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx and Turborepo", - "path": "/concepts/more-concepts/turbo-and-nx", - "id": "turbo-and-nx", + "name": "Project Dependency Rules", + "path": "/concepts/decisions/project-dependency-rules", + "id": "project-dependency-rules", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Applications and Libraries", - "path": "/concepts/more-concepts/applications-and-libraries", - "id": "applications-and-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "When to Create a New Library", - "path": "/concepts/more-concepts/creating-libraries", - "id": "creating-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Library Types", - "path": "/concepts/more-concepts/library-types", - "id": "library-types", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Grouping Libraries", - "path": "/concepts/more-concepts/grouping-libraries", - "id": "grouping-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Buildable and Publishable Libraries", - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "id": "buildable-and-publishable-libraries", + "name": "Folder Structure", + "path": "/concepts/decisions/folder-structure", + "id": "folder-structure", "isExternal": false, "children": [], "disableCollapsible": false @@ -835,6 +835,30 @@ "children": [], "disableCollapsible": false }, + { + "name": "Nx Daemon", + "path": "/concepts/nx-daemon", + "id": "nx-daemon", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Nx and Turborepo", + "path": "/concepts/turbo-and-nx", + "id": "turbo-and-nx", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, + { + "name": "Buildable and Publishable Libraries", + "path": "/concepts/buildable-and-publishable-libraries", + "id": "buildable-and-publishable-libraries", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Module Federation", "path": "/concepts/module-federation", @@ -909,14 +933,22 @@ "disableCollapsible": false }, { - "name": "More Concepts", - "path": "/concepts/more-concepts", - "id": "more-concepts", + "name": "Organizational Decisions", + "path": "/concepts/decisions", + "id": "decisions", "isExternal": false, "children": [ + { + "name": "Overview", + "path": "/concepts/decisions/overview", + "id": "overview", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Monorepos", - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "id": "why-monorepos", "isExternal": false, "children": [], @@ -924,72 +956,40 @@ }, { "name": "Dependency Management", - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "id": "dependency-management", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Code Sharing", - "path": "/concepts/more-concepts/code-sharing", - "id": "code-sharing", + "name": "Code Ownership", + "path": "/concepts/decisions/code-ownership", + "id": "code-ownership", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx Daemon", - "path": "/concepts/more-concepts/nx-daemon", - "id": "nx-daemon", + "name": "Project Size", + "path": "/concepts/decisions/project-size", + "id": "project-size", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx and Turborepo", - "path": "/concepts/more-concepts/turbo-and-nx", - "id": "turbo-and-nx", + "name": "Project Dependency Rules", + "path": "/concepts/decisions/project-dependency-rules", + "id": "project-dependency-rules", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Applications and Libraries", - "path": "/concepts/more-concepts/applications-and-libraries", - "id": "applications-and-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "When to Create a New Library", - "path": "/concepts/more-concepts/creating-libraries", - "id": "creating-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Library Types", - "path": "/concepts/more-concepts/library-types", - "id": "library-types", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Grouping Libraries", - "path": "/concepts/more-concepts/grouping-libraries", - "id": "grouping-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Buildable and Publishable Libraries", - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "id": "buildable-and-publishable-libraries", + "name": "Folder Structure", + "path": "/concepts/decisions/folder-structure", + "id": "folder-structure", "isExternal": false, "children": [], "disableCollapsible": false @@ -997,9 +997,17 @@ ], "disableCollapsible": false }, + { + "name": "Overview", + "path": "/concepts/decisions/overview", + "id": "overview", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Monorepos", - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "id": "why-monorepos", "isExternal": false, "children": [], @@ -1007,72 +1015,40 @@ }, { "name": "Dependency Management", - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "id": "dependency-management", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Code Sharing", - "path": "/concepts/more-concepts/code-sharing", - "id": "code-sharing", + "name": "Code Ownership", + "path": "/concepts/decisions/code-ownership", + "id": "code-ownership", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx Daemon", - "path": "/concepts/more-concepts/nx-daemon", - "id": "nx-daemon", + "name": "Project Size", + "path": "/concepts/decisions/project-size", + "id": "project-size", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Nx and Turborepo", - "path": "/concepts/more-concepts/turbo-and-nx", - "id": "turbo-and-nx", + "name": "Project Dependency Rules", + "path": "/concepts/decisions/project-dependency-rules", + "id": "project-dependency-rules", "isExternal": false, "children": [], "disableCollapsible": false }, { - "name": "Applications and Libraries", - "path": "/concepts/more-concepts/applications-and-libraries", - "id": "applications-and-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "When to Create a New Library", - "path": "/concepts/more-concepts/creating-libraries", - "id": "creating-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Library Types", - "path": "/concepts/more-concepts/library-types", - "id": "library-types", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Grouping Libraries", - "path": "/concepts/more-concepts/grouping-libraries", - "id": "grouping-libraries", - "isExternal": false, - "children": [], - "disableCollapsible": false - }, - { - "name": "Buildable and Publishable Libraries", - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "id": "buildable-and-publishable-libraries", + "name": "Folder Structure", + "path": "/concepts/decisions/folder-structure", + "id": "folder-structure", "isExternal": false, "children": [], "disableCollapsible": false diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index 44282ae435..3f3f5d5bcb 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -787,7 +787,7 @@ "name": "Mental Model", "description": "", "mediaImage": "", - "file": "shared/mental-model", + "file": "shared/concepts/mental-model", "itemList": [], "isExternal": false, "path": "/concepts/mental-model", @@ -853,7 +853,7 @@ "name": "Executors and Configurations", "description": "", "mediaImage": "", - "file": "shared/recipes/running-tasks/executors-and-configurations", + "file": "shared/concepts/executors-and-configurations", "itemList": [], "isExternal": false, "path": "/concepts/executors-and-configurations", @@ -870,6 +870,39 @@ "path": "/concepts/integrated-vs-package-based", "tags": ["intro", "repository-types"] }, + { + "id": "nx-daemon", + "name": "Nx Daemon", + "description": "", + "mediaImage": "", + "file": "shared/concepts/daemon", + "itemList": [], + "isExternal": false, + "path": "/concepts/nx-daemon", + "tags": [] + }, + { + "id": "turbo-and-nx", + "name": "Nx and Turborepo", + "description": "", + "mediaImage": "./shared/concepts/nx-media-monorepo.jpg", + "file": "shared/concepts/turbo-and-nx", + "itemList": [], + "isExternal": false, + "path": "/concepts/turbo-and-nx", + "tags": [] + }, + { + "id": "buildable-and-publishable-libraries", + "name": "Buildable and Publishable Libraries", + "description": "", + "mediaImage": "", + "file": "shared/concepts/buildable-and-publishable-libraries", + "itemList": [], + "isExternal": false, + "path": "/concepts/buildable-and-publishable-libraries", + "tags": [] + }, { "id": "module-federation", "name": "Module Federation", @@ -882,7 +915,7 @@ "name": "Module Federation and Nx", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/module-federation-and-nx", @@ -893,7 +926,7 @@ "name": "Faster Builds with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/faster-builds-with-module-federation", @@ -904,7 +937,7 @@ "name": "Micro Frontend Architecture", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/micro-frontend-architecture", + "file": "shared/concepts/module-federation/micro-frontend-architecture", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/micro-frontend-architecture", @@ -915,7 +948,7 @@ "name": "Manage Library Versions with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/manage-library-versions-with-module-federation", + "file": "shared/concepts/module-federation/manage-library-versions-with-module-federation", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/manage-library-versions-with-module-federation", @@ -927,21 +960,32 @@ "tags": [] }, { - "id": "more-concepts", - "name": "More Concepts", - "description": "Get deeper into how Nx works and its different aspects.", + "id": "decisions", + "name": "Organizational Decisions", + "description": "Topics that need to be considered when structuring your repository", "mediaImage": "", "file": "", "itemList": [ + { + "id": "overview", + "name": "Overview", + "description": "", + "mediaImage": "", + "file": "shared/concepts/decisions/monorepo-polyrepo", + "itemList": [], + "isExternal": false, + "path": "/concepts/decisions/overview", + "tags": [] + }, { "id": "why-monorepos", "name": "Monorepos", "description": "", "mediaImage": "", - "file": "shared/guides/why-monorepos", + "file": "shared/concepts/decisions/monorepos", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "tags": [] }, { @@ -949,103 +993,59 @@ "name": "Dependency Management", "description": "", "mediaImage": "", - "file": "shared/concepts/dependency-management", + "file": "shared/concepts/decisions/dependency-management", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "tags": [] }, { - "id": "code-sharing", - "name": "Code Sharing", + "id": "code-ownership", + "name": "Code Ownership", "description": "", "mediaImage": "", - "file": "shared/concepts/code-sharing", + "file": "shared/concepts/decisions/code-ownership", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/code-sharing", + "path": "/concepts/decisions/code-ownership", "tags": [] }, { - "id": "nx-daemon", - "name": "Nx Daemon", + "id": "project-size", + "name": "Project Size", "description": "", "mediaImage": "", - "file": "shared/daemon", + "file": "shared/concepts/decisions/project-size", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/nx-daemon", - "tags": [] - }, - { - "id": "turbo-and-nx", - "name": "Nx and Turborepo", - "description": "", - "mediaImage": "./shared/guides/nx-media-monorepo.jpg", - "file": "shared/guides/turbo-and-nx", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/turbo-and-nx", - "tags": [] - }, - { - "id": "applications-and-libraries", - "name": "Applications and Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/applications-and-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/applications-and-libraries", + "path": "/concepts/decisions/project-size", "tags": ["enforce-module-boundaries"] }, { - "id": "creating-libraries", - "name": "When to Create a New Library", + "id": "project-dependency-rules", + "name": "Project Dependency Rules", "description": "", "mediaImage": "", - "file": "shared/workspace/creating-libraries", + "file": "shared/concepts/decisions/project-dependency-rules", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/creating-libraries", + "path": "/concepts/decisions/project-dependency-rules", "tags": ["enforce-module-boundaries"] }, { - "id": "library-types", - "name": "Library Types", + "id": "folder-structure", + "name": "Folder Structure", "description": "", "mediaImage": "", - "file": "shared/workspace/library-types", + "file": "shared/concepts/decisions/folder-structure", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/library-types", + "path": "/concepts/decisions/folder-structure", "tags": ["enforce-module-boundaries"] - }, - { - "id": "grouping-libraries", - "name": "Grouping Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/grouping-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/grouping-libraries", - "tags": ["enforce-module-boundaries"] - }, - { - "id": "buildable-and-publishable-libraries", - "name": "Buildable and Publishable Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/buildable-and-publishable-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "tags": [] } ], "isExternal": false, - "path": "/concepts/more-concepts", + "path": "/concepts/decisions", "tags": [] } ], @@ -1058,7 +1058,7 @@ "name": "Mental Model", "description": "", "mediaImage": "", - "file": "shared/mental-model", + "file": "shared/concepts/mental-model", "itemList": [], "isExternal": false, "path": "/concepts/mental-model", @@ -1124,7 +1124,7 @@ "name": "Executors and Configurations", "description": "", "mediaImage": "", - "file": "shared/recipes/running-tasks/executors-and-configurations", + "file": "shared/concepts/executors-and-configurations", "itemList": [], "isExternal": false, "path": "/concepts/executors-and-configurations", @@ -1141,6 +1141,39 @@ "path": "/concepts/integrated-vs-package-based", "tags": ["intro", "repository-types"] }, + "/concepts/nx-daemon": { + "id": "nx-daemon", + "name": "Nx Daemon", + "description": "", + "mediaImage": "", + "file": "shared/concepts/daemon", + "itemList": [], + "isExternal": false, + "path": "/concepts/nx-daemon", + "tags": [] + }, + "/concepts/turbo-and-nx": { + "id": "turbo-and-nx", + "name": "Nx and Turborepo", + "description": "", + "mediaImage": "./shared/concepts/nx-media-monorepo.jpg", + "file": "shared/concepts/turbo-and-nx", + "itemList": [], + "isExternal": false, + "path": "/concepts/turbo-and-nx", + "tags": [] + }, + "/concepts/buildable-and-publishable-libraries": { + "id": "buildable-and-publishable-libraries", + "name": "Buildable and Publishable Libraries", + "description": "", + "mediaImage": "", + "file": "shared/concepts/buildable-and-publishable-libraries", + "itemList": [], + "isExternal": false, + "path": "/concepts/buildable-and-publishable-libraries", + "tags": [] + }, "/concepts/module-federation": { "id": "module-federation", "name": "Module Federation", @@ -1153,7 +1186,7 @@ "name": "Module Federation and Nx", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/module-federation-and-nx", @@ -1164,7 +1197,7 @@ "name": "Faster Builds with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/faster-builds-with-module-federation", @@ -1175,7 +1208,7 @@ "name": "Micro Frontend Architecture", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/micro-frontend-architecture", + "file": "shared/concepts/module-federation/micro-frontend-architecture", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/micro-frontend-architecture", @@ -1186,7 +1219,7 @@ "name": "Manage Library Versions with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/manage-library-versions-with-module-federation", + "file": "shared/concepts/module-federation/manage-library-versions-with-module-federation", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/manage-library-versions-with-module-federation", @@ -1202,7 +1235,7 @@ "name": "Module Federation and Nx", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/module-federation-and-nx", @@ -1213,7 +1246,7 @@ "name": "Faster Builds with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/faster-builds-with-module-federation", @@ -1224,7 +1257,7 @@ "name": "Micro Frontend Architecture", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/micro-frontend-architecture", + "file": "shared/concepts/module-federation/micro-frontend-architecture", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/micro-frontend-architecture", @@ -1235,28 +1268,39 @@ "name": "Manage Library Versions with Module Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/manage-library-versions-with-module-federation", + "file": "shared/concepts/module-federation/manage-library-versions-with-module-federation", "itemList": [], "isExternal": false, "path": "/concepts/module-federation/manage-library-versions-with-module-federation", "tags": [] }, - "/concepts/more-concepts": { - "id": "more-concepts", - "name": "More Concepts", - "description": "Get deeper into how Nx works and its different aspects.", + "/concepts/decisions": { + "id": "decisions", + "name": "Organizational Decisions", + "description": "Topics that need to be considered when structuring your repository", "mediaImage": "", "file": "", "itemList": [ + { + "id": "overview", + "name": "Overview", + "description": "", + "mediaImage": "", + "file": "shared/concepts/decisions/monorepo-polyrepo", + "itemList": [], + "isExternal": false, + "path": "/concepts/decisions/overview", + "tags": [] + }, { "id": "why-monorepos", "name": "Monorepos", "description": "", "mediaImage": "", - "file": "shared/guides/why-monorepos", + "file": "shared/concepts/decisions/monorepos", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "tags": [] }, { @@ -1264,215 +1308,138 @@ "name": "Dependency Management", "description": "", "mediaImage": "", - "file": "shared/concepts/dependency-management", + "file": "shared/concepts/decisions/dependency-management", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "tags": [] }, { - "id": "code-sharing", - "name": "Code Sharing", + "id": "code-ownership", + "name": "Code Ownership", "description": "", "mediaImage": "", - "file": "shared/concepts/code-sharing", + "file": "shared/concepts/decisions/code-ownership", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/code-sharing", + "path": "/concepts/decisions/code-ownership", "tags": [] }, { - "id": "nx-daemon", - "name": "Nx Daemon", + "id": "project-size", + "name": "Project Size", "description": "", "mediaImage": "", - "file": "shared/daemon", + "file": "shared/concepts/decisions/project-size", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/nx-daemon", - "tags": [] - }, - { - "id": "turbo-and-nx", - "name": "Nx and Turborepo", - "description": "", - "mediaImage": "./shared/guides/nx-media-monorepo.jpg", - "file": "shared/guides/turbo-and-nx", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/turbo-and-nx", - "tags": [] - }, - { - "id": "applications-and-libraries", - "name": "Applications and Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/applications-and-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/applications-and-libraries", + "path": "/concepts/decisions/project-size", "tags": ["enforce-module-boundaries"] }, { - "id": "creating-libraries", - "name": "When to Create a New Library", + "id": "project-dependency-rules", + "name": "Project Dependency Rules", "description": "", "mediaImage": "", - "file": "shared/workspace/creating-libraries", + "file": "shared/concepts/decisions/project-dependency-rules", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/creating-libraries", + "path": "/concepts/decisions/project-dependency-rules", "tags": ["enforce-module-boundaries"] }, { - "id": "library-types", - "name": "Library Types", + "id": "folder-structure", + "name": "Folder Structure", "description": "", "mediaImage": "", - "file": "shared/workspace/library-types", + "file": "shared/concepts/decisions/folder-structure", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/library-types", + "path": "/concepts/decisions/folder-structure", "tags": ["enforce-module-boundaries"] - }, - { - "id": "grouping-libraries", - "name": "Grouping Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/grouping-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/grouping-libraries", - "tags": ["enforce-module-boundaries"] - }, - { - "id": "buildable-and-publishable-libraries", - "name": "Buildable and Publishable Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/buildable-and-publishable-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "tags": [] } ], "isExternal": false, - "path": "/concepts/more-concepts", + "path": "/concepts/decisions", "tags": [] }, - "/concepts/more-concepts/why-monorepos": { + "/concepts/decisions/overview": { + "id": "overview", + "name": "Overview", + "description": "", + "mediaImage": "", + "file": "shared/concepts/decisions/monorepo-polyrepo", + "itemList": [], + "isExternal": false, + "path": "/concepts/decisions/overview", + "tags": [] + }, + "/concepts/decisions/why-monorepos": { "id": "why-monorepos", "name": "Monorepos", "description": "", "mediaImage": "", - "file": "shared/guides/why-monorepos", + "file": "shared/concepts/decisions/monorepos", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/why-monorepos", + "path": "/concepts/decisions/why-monorepos", "tags": [] }, - "/concepts/more-concepts/dependency-management": { + "/concepts/decisions/dependency-management": { "id": "dependency-management", "name": "Dependency Management", "description": "", "mediaImage": "", - "file": "shared/concepts/dependency-management", + "file": "shared/concepts/decisions/dependency-management", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/dependency-management", + "path": "/concepts/decisions/dependency-management", "tags": [] }, - "/concepts/more-concepts/code-sharing": { - "id": "code-sharing", - "name": "Code Sharing", + "/concepts/decisions/code-ownership": { + "id": "code-ownership", + "name": "Code Ownership", "description": "", "mediaImage": "", - "file": "shared/concepts/code-sharing", + "file": "shared/concepts/decisions/code-ownership", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/code-sharing", + "path": "/concepts/decisions/code-ownership", "tags": [] }, - "/concepts/more-concepts/nx-daemon": { - "id": "nx-daemon", - "name": "Nx Daemon", + "/concepts/decisions/project-size": { + "id": "project-size", + "name": "Project Size", "description": "", "mediaImage": "", - "file": "shared/daemon", + "file": "shared/concepts/decisions/project-size", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/nx-daemon", - "tags": [] - }, - "/concepts/more-concepts/turbo-and-nx": { - "id": "turbo-and-nx", - "name": "Nx and Turborepo", - "description": "", - "mediaImage": "./shared/guides/nx-media-monorepo.jpg", - "file": "shared/guides/turbo-and-nx", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/turbo-and-nx", - "tags": [] - }, - "/concepts/more-concepts/applications-and-libraries": { - "id": "applications-and-libraries", - "name": "Applications and Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/applications-and-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/applications-and-libraries", + "path": "/concepts/decisions/project-size", "tags": ["enforce-module-boundaries"] }, - "/concepts/more-concepts/creating-libraries": { - "id": "creating-libraries", - "name": "When to Create a New Library", + "/concepts/decisions/project-dependency-rules": { + "id": "project-dependency-rules", + "name": "Project Dependency Rules", "description": "", "mediaImage": "", - "file": "shared/workspace/creating-libraries", + "file": "shared/concepts/decisions/project-dependency-rules", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/creating-libraries", + "path": "/concepts/decisions/project-dependency-rules", "tags": ["enforce-module-boundaries"] }, - "/concepts/more-concepts/library-types": { - "id": "library-types", - "name": "Library Types", + "/concepts/decisions/folder-structure": { + "id": "folder-structure", + "name": "Folder Structure", "description": "", "mediaImage": "", - "file": "shared/workspace/library-types", + "file": "shared/concepts/decisions/folder-structure", "itemList": [], "isExternal": false, - "path": "/concepts/more-concepts/library-types", + "path": "/concepts/decisions/folder-structure", "tags": ["enforce-module-boundaries"] }, - "/concepts/more-concepts/grouping-libraries": { - "id": "grouping-libraries", - "name": "Grouping Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/grouping-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/grouping-libraries", - "tags": ["enforce-module-boundaries"] - }, - "/concepts/more-concepts/buildable-and-publishable-libraries": { - "id": "buildable-and-publishable-libraries", - "name": "Buildable and Publishable Libraries", - "description": "", - "mediaImage": "", - "file": "shared/workspace/buildable-and-publishable-libraries", - "itemList": [], - "isExternal": false, - "path": "/concepts/more-concepts/buildable-and-publishable-libraries", - "tags": [] - }, "/recipes": { "id": "recipes", "name": "Recipes", @@ -1871,7 +1838,7 @@ "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/dynamic-mfe-angular", + "file": "shared/recipes/module-federation/dynamic-mfe-angular", "itemList": [], "isExternal": false, "path": "/recipes/angular/dynamic-module-federation-with-angular", @@ -3435,7 +3402,7 @@ "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/dynamic-mfe-angular", + "file": "shared/recipes/module-federation/dynamic-mfe-angular", "itemList": [], "isExternal": false, "path": "/recipes/angular/dynamic-module-federation-with-angular", @@ -3551,7 +3518,7 @@ "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "description": "", "mediaImage": "", - "file": "shared/guides/module-federation/dynamic-mfe-angular", + "file": "shared/recipes/module-federation/dynamic-mfe-angular", "itemList": [], "isExternal": false, "path": "/recipes/angular/dynamic-module-federation-with-angular", diff --git a/docs/generated/manifests/tags.json b/docs/generated/manifests/tags.json index 5a52d119ec..cf427d0ac3 100644 --- a/docs/generated/manifests/tags.json +++ b/docs/generated/manifests/tags.json @@ -60,7 +60,7 @@ }, { "description": "", - "file": "shared/recipes/running-tasks/executors-and-configurations", + "file": "shared/concepts/executors-and-configurations", "id": "executors-and-configurations", "name": "Executors and Configurations", "path": "/concepts/executors-and-configurations" @@ -392,31 +392,24 @@ }, { "description": "", - "file": "shared/workspace/applications-and-libraries", - "id": "applications-and-libraries", - "name": "Applications and Libraries", - "path": "/concepts/more-concepts/applications-and-libraries" + "file": "shared/concepts/decisions/project-size", + "id": "project-size", + "name": "Project Size", + "path": "/concepts/decisions/project-size" }, { "description": "", - "file": "shared/workspace/creating-libraries", - "id": "creating-libraries", - "name": "When to Create a New Library", - "path": "/concepts/more-concepts/creating-libraries" + "file": "shared/concepts/decisions/project-dependency-rules", + "id": "project-dependency-rules", + "name": "Project Dependency Rules", + "path": "/concepts/decisions/project-dependency-rules" }, { "description": "", - "file": "shared/workspace/library-types", - "id": "library-types", - "name": "Library Types", - "path": "/concepts/more-concepts/library-types" - }, - { - "description": "", - "file": "shared/workspace/grouping-libraries", - "id": "grouping-libraries", - "name": "Grouping Libraries", - "path": "/concepts/more-concepts/grouping-libraries" + "file": "shared/concepts/decisions/folder-structure", + "id": "folder-structure", + "name": "Folder Structure", + "path": "/concepts/decisions/folder-structure" }, { "description": "", @@ -550,7 +543,7 @@ "intro": [ { "description": "", - "file": "shared/mental-model", + "file": "shared/concepts/mental-model", "id": "mental-model", "name": "Mental Model", "path": "/concepts/mental-model" @@ -566,7 +559,7 @@ "inferred-tasks": [ { "description": "", - "file": "shared/mental-model", + "file": "shared/concepts/mental-model", "id": "mental-model", "name": "Mental Model", "path": "/concepts/mental-model" @@ -670,14 +663,14 @@ "module-federation": [ { "description": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "id": "module-federation-and-nx", "name": "Module Federation and Nx", "path": "/concepts/module-federation/module-federation-and-nx" }, { "description": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "id": "faster-builds-with-module-federation", "name": "Faster Builds with Module Federation", "path": "/concepts/module-federation/faster-builds-with-module-federation" @@ -698,7 +691,7 @@ }, { "description": "", - "file": "shared/guides/module-federation/dynamic-mfe-angular", + "file": "shared/recipes/module-federation/dynamic-mfe-angular", "id": "dynamic-module-federation-with-angular", "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "path": "/recipes/angular/dynamic-module-federation-with-angular" @@ -707,14 +700,14 @@ "angular": [ { "description": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "id": "module-federation-and-nx", "name": "Module Federation and Nx", "path": "/concepts/module-federation/module-federation-and-nx" }, { "description": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "id": "faster-builds-with-module-federation", "name": "Faster Builds with Module Federation", "path": "/concepts/module-federation/faster-builds-with-module-federation" @@ -728,7 +721,7 @@ }, { "description": "", - "file": "shared/guides/module-federation/dynamic-mfe-angular", + "file": "shared/recipes/module-federation/dynamic-mfe-angular", "id": "dynamic-module-federation-with-angular", "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "path": "/recipes/angular/dynamic-module-federation-with-angular" @@ -737,14 +730,14 @@ "react": [ { "description": "", - "file": "shared/guides/module-federation/module-federation-and-nx", + "file": "shared/concepts/module-federation/module-federation-and-nx", "id": "module-federation-and-nx", "name": "Module Federation and Nx", "path": "/concepts/module-federation/module-federation-and-nx" }, { "description": "", - "file": "shared/guides/module-federation/faster-builds", + "file": "shared/concepts/module-federation/faster-builds", "id": "faster-builds-with-module-federation", "name": "Faster Builds with Module Federation", "path": "/concepts/module-federation/faster-builds-with-module-federation" diff --git a/docs/generated/packages/angular/documents/overview.md b/docs/generated/packages/angular/documents/overview.md index 4af5191ba9..8d0c13e2a3 100644 --- a/docs/generated/packages/angular/documents/overview.md +++ b/docs/generated/packages/angular/documents/overview.md @@ -111,9 +111,9 @@ nx lint libName Read more about: -- [Creating Libraries](/concepts/more-concepts/creating-libraries) -- [Library Types](/concepts/more-concepts/library-types) -- [Buildable and Publishable Libraries](/concepts/more-concepts/buildable-and-publishable-libraries) +- [Creating Libraries](/concepts/decisions/project-size) +- [Library Types](/concepts/decisions/project-dependency-rules) +- [Buildable and Publishable Libraries](/concepts/buildable-and-publishable-libraries) ### Fallback to `@schematics/angular` diff --git a/docs/generated/packages/nest/documents/overview.md b/docs/generated/packages/nest/documents/overview.md index bcf3bef876..faee847595 100644 --- a/docs/generated/packages/nest/documents/overview.md +++ b/docs/generated/packages/nest/documents/overview.md @@ -88,7 +88,7 @@ To make the library `publishable`, use the following command: nx g @nx/nest:lib my-nest-lib --publishable --importPath=@my-workspace/my-nest-lib ``` -> Read more about [building and publishing libraries here](/concepts/more-concepts/buildable-and-publishable-libraries). +> Read more about [building and publishing libraries here](/concepts/buildable-and-publishable-libraries). ### Nest Generators diff --git a/docs/generated/packages/next/documents/overview.md b/docs/generated/packages/next/documents/overview.md index 503b56d975..61b85b540a 100644 --- a/docs/generated/packages/next/documents/overview.md +++ b/docs/generated/packages/next/documents/overview.md @@ -108,9 +108,6 @@ Nx allows you to create libraries with just one command. Some reasons you might - Publish a package to be used outside the monorepo - Better visualize the architecture using `nx graph` -For more information on Nx libraries, see our documentation on [Creating Libraries](/concepts/more-concepts/creating-libraries) -and [Library Types](/concepts/more-concepts/library-types). - To generate a new library run: ```shell diff --git a/docs/generated/packages/react/documents/overview.md b/docs/generated/packages/react/documents/overview.md index 947c67178a..a6cc780093 100644 --- a/docs/generated/packages/react/documents/overview.md +++ b/docs/generated/packages/react/documents/overview.md @@ -70,7 +70,7 @@ nx g @nx/react:lib my-new-lib \ --importPath=@myorg/my-new-lib ``` -Read more about [building and publishing libraries here](/concepts/more-concepts/buildable-and-publishable-libraries). +Read more about [building and publishing libraries here](/concepts/buildable-and-publishable-libraries). ### Creating Components diff --git a/docs/generated/packages/storybook/documents/best-practices.md b/docs/generated/packages/storybook/documents/best-practices.md index 2fec8281b1..976893d7d5 100644 --- a/docs/generated/packages/storybook/documents/best-practices.md +++ b/docs/generated/packages/storybook/documents/best-practices.md @@ -87,7 +87,7 @@ In the following section, we are going to see how to set up Storybook in these c ### Philosophy -Setting up Storybook on Nx reflects - and takes advantage of - the [mental model](/concepts/mental-model) of Nx, and especially the architecture of [Applications and Libraries](/concepts/more-concepts/applications-and-libraries). What that means, in essence, is that you still maintain the individual Storybook instances (per project) which you use for testing and local development, but you also keep one extra “container” for publishing, that serves as a single entry point. Let’s see this in more detail. +Setting up Storybook on Nx reflects - and takes advantage of - the [mental model](/concepts/mental-model) of Nx. What that means, in essence, is that you still maintain the individual Storybook instances (per project) which you use for testing and local development, but you also keep one extra “container” for publishing, that serves as a single entry point. Let’s see this in more detail. #### Local development and testing @@ -119,7 +119,7 @@ Since each Storybook, in this case, is attached to a project, so is the serving #### Publishing -When you are publishing your Storybook, you can follow the same principles described in the [Applications and Libraries Mental Model](/concepts/more-concepts/applications-and-libraries#mental-model) documentation page. The general idea is to have one central Storybook container, into which you are going to gather your stories from multiple libraries. +When you are publishing your Storybook, you can follow the same principles described in the [Applications and Libraries Mental Model](/concepts/decisions/project-size#mental-model) documentation page. The general idea is to have one central Storybook container, into which you are going to gather your stories from multiple libraries. You can think of the central Storybook container as a grouping of similar-concept or same-scope UI parts of your workspace. In the same way you are scoping libraries, you can group your stories as well. @@ -129,7 +129,7 @@ Then, according to your use-case, you can have one central Storybook for your wh In order to achieve some things mentioned above, you may use [Storybook Composition](/recipes/storybook/storybook-composition-setup). However, in this case, you would still need to build each project’s Storybook individually, and also deploy it individually. So in the cases where you have multiple projects, Storybook Composition would not be very efficient. {% /callout %} -Before moving on to the examples section, it could be useful to read the [Library Types](/concepts/more-concepts/library-types) documentation page and the [Grouping libraries](/concepts/more-concepts/grouping-libraries) documentation page. These could help you decide which way fits your use case better. +Before moving on to the examples section, it could be useful to read the [Library Types](/concepts/decisions/project-dependency-rules) documentation page and the [Grouping libraries](/concepts/decisions/folder-structure) documentation page. These could help you decide which way fits your use case better. ## Examples / Use cases diff --git a/docs/map.json b/docs/map.json index 1f565171a9..947e8d4b79 100644 --- a/docs/map.json +++ b/docs/map.json @@ -201,7 +201,7 @@ "name": "Mental Model", "tags": ["intro", "inferred-tasks"], "id": "mental-model", - "file": "shared/mental-model" + "file": "shared/concepts/mental-model" }, { "name": "How Caching Works", @@ -241,7 +241,7 @@ "name": "Executors and Configurations", "id": "executors-and-configurations", "tags": ["run-tasks"], - "file": "shared/recipes/running-tasks/executors-and-configurations" + "file": "shared/concepts/executors-and-configurations" }, { "name": "Integrated Repos vs. Package-Based Repos vs. Standalone Apps", @@ -249,6 +249,22 @@ "id": "integrated-vs-package-based", "file": "shared/concepts/integrated-vs-package-based" }, + { + "name": "Nx Daemon", + "id": "nx-daemon", + "file": "shared/concepts/daemon" + }, + { + "name": "Nx and Turborepo", + "id": "turbo-and-nx", + "mediaImage": "./shared/concepts/nx-media-monorepo.jpg", + "file": "shared/concepts/turbo-and-nx" + }, + { + "name": "Buildable and Publishable Libraries", + "id": "buildable-and-publishable-libraries", + "file": "shared/concepts/buildable-and-publishable-libraries" + }, { "name": "Module Federation", "id": "module-federation", @@ -258,85 +274,68 @@ "name": "Module Federation and Nx", "id": "module-federation-and-nx", "tags": ["module-federation", "angular", "react"], - "file": "shared/guides/module-federation/module-federation-and-nx" + "file": "shared/concepts/module-federation/module-federation-and-nx" }, { "name": "Faster Builds with Module Federation", "id": "faster-builds-with-module-federation", "tags": ["module-federation", "angular", "react"], - "file": "shared/guides/module-federation/faster-builds" + "file": "shared/concepts/module-federation/faster-builds" }, { "name": "Micro Frontend Architecture", "id": "micro-frontend-architecture", - "file": "shared/guides/module-federation/micro-frontend-architecture" + "file": "shared/concepts/module-federation/micro-frontend-architecture" }, { "name": "Manage Library Versions with Module Federation", "id": "manage-library-versions-with-module-federation", - "file": "shared/guides/module-federation/manage-library-versions-with-module-federation" + "file": "shared/concepts/module-federation/manage-library-versions-with-module-federation" } ] }, { - "name": "More Concepts", - "id": "more-concepts", - "description": "Get deeper into how Nx works and its different aspects.", + "name": "Organizational Decisions", + "id": "decisions", + "description": "Topics that need to be considered when structuring your repository", "itemList": [ + { + "name": "Overview", + "id": "overview", + "file": "shared/concepts/decisions/monorepo-polyrepo" + }, { "name": "Monorepos", "id": "why-monorepos", - "file": "shared/guides/why-monorepos" + "file": "shared/concepts/decisions/monorepos" }, { "name": "Dependency Management", "id": "dependency-management", - "file": "shared/concepts/dependency-management" + "file": "shared/concepts/decisions/dependency-management" }, { - "name": "Code Sharing", - "id": "code-sharing", - "file": "shared/concepts/code-sharing" + "name": "Code Ownership", + "id": "code-ownership", + "file": "shared/concepts/decisions/code-ownership" }, { - "name": "Nx Daemon", - "id": "nx-daemon", - "file": "shared/daemon" - }, - { - "name": "Nx and Turborepo", - "id": "turbo-and-nx", - "mediaImage": "./shared/guides/nx-media-monorepo.jpg", - "file": "shared/guides/turbo-and-nx" - }, - { - "name": "Applications and Libraries", - "id": "applications-and-libraries", + "name": "Project Size", + "id": "project-size", "tags": ["enforce-module-boundaries"], - "file": "shared/workspace/applications-and-libraries" + "file": "shared/concepts/decisions/project-size" }, { - "name": "When to Create a New Library", - "id": "creating-libraries", + "name": "Project Dependency Rules", + "id": "project-dependency-rules", "tags": ["enforce-module-boundaries"], - "file": "shared/workspace/creating-libraries" + "file": "shared/concepts/decisions/project-dependency-rules" }, { - "name": "Library Types", - "id": "library-types", + "name": "Folder Structure", + "id": "folder-structure", "tags": ["enforce-module-boundaries"], - "file": "shared/workspace/library-types" - }, - { - "name": "Grouping Libraries", - "id": "grouping-libraries", - "tags": ["enforce-module-boundaries"], - "file": "shared/workspace/grouping-libraries" - }, - { - "name": "Buildable and Publishable Libraries", - "id": "buildable-and-publishable-libraries", - "file": "shared/workspace/buildable-and-publishable-libraries" + "file": "shared/concepts/decisions/folder-structure" } ] } @@ -550,7 +549,7 @@ "name": "Advanced Micro Frontends with Angular using Dynamic Federation", "id": "dynamic-module-federation-with-angular", "tags": ["module-federation", "angular"], - "file": "shared/guides/module-federation/dynamic-mfe-angular" + "file": "shared/recipes/module-federation/dynamic-mfe-angular" }, { "name": "Setup incremental builds for Angular applications", diff --git a/docs/shared/workspace/buildable-and-publishable-libraries.md b/docs/shared/concepts/buildable-and-publishable-libraries.md similarity index 100% rename from docs/shared/workspace/buildable-and-publishable-libraries.md rename to docs/shared/concepts/buildable-and-publishable-libraries.md diff --git a/docs/shared/daemon.md b/docs/shared/concepts/daemon.md similarity index 100% rename from docs/shared/daemon.md rename to docs/shared/concepts/daemon.md diff --git a/docs/shared/concepts/code-sharing.md b/docs/shared/concepts/decisions/code-ownership.md similarity index 69% rename from docs/shared/concepts/code-sharing.md rename to docs/shared/concepts/decisions/code-ownership.md index 01be83f361..4bbafeda2e 100644 --- a/docs/shared/concepts/code-sharing.md +++ b/docs/shared/concepts/decisions/code-ownership.md @@ -1,4 +1,4 @@ -# Code Sharing +# Code Ownership One of the most obvious benefits of having a monorepo is that you can easily share code across projects. This enables you to apply the Don't Repeat Yourself principle across the whole codebase. Code sharing could mean using a function or a component in multiple projects. Or code sharing could mean using a typescript interface to define the network API interface for both the front end and back end applications. @@ -19,3 +19,21 @@ Another team can use a piece of code that is intended to be internal to your pro ### Projects Depending on the Wrong Libraries Libraries with presentational components can accidentally use code from a library that holds a data store. Projects with Angular code can accidentally use code from a React project. Projects from team A could accidentally use code in projects that are intended to be only for team B. These kinds of rules will vary based on the organisation, but they can all be enforced automatically using tags and the `enforce-module-boundaries` lint rule. + +## Defining Code Ownership + +As more teams are contributing to the same repository, it becomes crucial to establish clear code ownership. + +Since Nx allows us to place projects in any directory structure, those directories can become code-ownership boundaries. That's +why the structure of an Nx workspace often reflects the structure of an organization. GitHub users can use +the `CODEOWNERS` file for that. + +```plaintext +/libs/happynrwlapp julie-happynrwlapp-lead +/apps/happynrwlapp julie-happynrwlapp-lead +/libs/shared/ui hank-the-ui-guy +/libs/shared/utils-testing julie,hank +``` + +If you want to know more about code ownership on GitHub, please +check [the documentation on the `CODEOWNERS` file](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners). diff --git a/docs/shared/concepts/dependency-management.md b/docs/shared/concepts/decisions/dependency-management.md similarity index 100% rename from docs/shared/concepts/dependency-management.md rename to docs/shared/concepts/decisions/dependency-management.md diff --git a/docs/shared/concepts/decisions/folder-structure.md b/docs/shared/concepts/decisions/folder-structure.md new file mode 100644 index 0000000000..475f6d1dfc --- /dev/null +++ b/docs/shared/concepts/decisions/folder-structure.md @@ -0,0 +1,67 @@ +# Folder Structure + +Nx can work with any folder structure you choose, but it is good to have a plan in place for the folder structure of your monorepo. + +Projects are often grouped by _scope_. A project's scope is either the application to which it belongs or (for larger applications) a section within that application. + +## Move Generator + +Don't be too anxious about choosing the exact right folder structure from the beginning. Projects can be moved or renamed using the [`@nx/workspace:move` generator](/nx-api/workspace/generators/move). + +For instance, if a project under the `booking` folder is now being shared by multiple apps, you can move it to the shared folder like this: + +```shell +nx g move --project booking-some-project shared/some-project +``` + +## Remove Generator + +Similarly, if you no longer need a project, you can remove it with the [`@nx/workspace:remove` generator](/nx-api/workspace/generators/remove). + +```shell +nx g remove booking-some-project +``` + +## Example Workspace + +Let's use Nrwl Airlines as an example organization. This organization has two apps, `booking` and `check-in`. In the Nx workspace, projects related to `booking` are grouped under a `libs/booking` folder, projects related to `check-in` are grouped under a `libs/check-in` folder and projects used in both applications are placed in `libs/shared`. You can also have nested grouping folders, (i.e. `libs/shared/seatmap`). + +The purpose of these folders is to help with organizing by scope. We recommend grouping projects together which are (usually) updated together. It helps minimize the amount of time a developer spends navigating the folder tree to find the right file. + +```text +apps/ + booking/ + check-in/ +libs/ + booking/ <---- grouping folder + feature-shell/ <---- project + + check-in/ + feature-shell/ + + shared/ <---- grouping folder + data-access/ <---- project + + seatmap/ <---- grouping folder + data-access/ <---- project + feature-seatmap/ <---- project +``` + +## Sharing Projects + +One of the main advantages of using a monorepo is that there is more visibility into code that can be reused across many different applications. Shared projects are a great way to save developers time and effort by reusing a solution to a common problem. + +Let’s consider our reference monorepo. The `shared-data-access` project contains the code needed to communicate with the back-end (for example, the URL prefix). We know that this would be the same for all libs; therefore, we should place this in the shared lib and properly document it so that all projects can use it instead of writing their own versions. + +```text + libs/ + booking/ + data-access/ <---- app-specific project + + shared/ + data-access/ <---- shared project + + seatmap/ + data-access/ <---- shared project + feature-seatmap/ <---- shared project +``` diff --git a/docs/shared/concepts/decisions/monorepo-polyrepo.md b/docs/shared/concepts/decisions/monorepo-polyrepo.md new file mode 100644 index 0000000000..6c4fb0ee33 --- /dev/null +++ b/docs/shared/concepts/decisions/monorepo-polyrepo.md @@ -0,0 +1,38 @@ +# Monorepo or Polyrepo + +Monorepos have a lot of benefits, but there are also some costs involved. We feel strongly that the [technical challenges](/concepts/decisions/why-monorepos) involved in maintaining large monorepos are fully addressed through the efficient use of Nx and Nx Cloud. Rather, the limiting factors in how large your monorepo grows are interpersonal. + +In order for teams to work together in a monorepo, they need to agree on how that repository is going to be managed. These questions can be answered in many different ways, but if the developers in the repository can't agree on the answers, then they'll need to work in separate repositories. + +**Organizational Decisions:** + +- [Dependency Management](/concepts/decisions/dependency-management) - Should there be an enforced single version policy or should each project maintain their own dependency versions independently? +- [Code Ownership](/concepts/decisions/code-ownership) - What is the code review process? Who is responsible for reviewing changes to each portion of the repository? +- [Project Dependency Rules](/concepts/decisions/project-dependency-rules) - What are the restrictions on dependencies between projects? Which projects can depend on which other projects? +- [Folder Structure](/concepts/decisions/folder-structure) - What is the folder structure and naming convention for projects in the repository? +- [Project Size](/concepts/decisions/project-size) - What size should projects be before they need to be split into separate projects? +- Git Workflow - What Git workflow should be used? Will you use trunk-based development or long running feature branches? +- CI Pipeline - How is the CI pipeline managed? Who is responsible for maintaining it? +- Deployment - How are deployments managed? Does each project deploy independently or do they all deploy at once? + +## How Many Repositories? + +Once you have a good understanding of where people stand on these questions, you'll need to choose between one of the following setups: + +### One Monorepo to Rule Them All + +If everyone can agree on how to run the repository, having [a single monorepo will provide a lot of benefits](/concepts/decisions/why-monorepos). Every project can share code and maintenance tasks can be performed in one PR for the entire organization. Any task that involves coordination becomes much easier. + +Once the repository scales to hundreds of developers, you need to take proactive steps to ensure that your decisions about [code review](/concepts/decisions/code-ownership) and [project dependency restrictions](/features/enforce-module-boundaries) do not inhibit the velocity of your teams. Also, any shared code and tooling (like the CI pipeline or a shared component library) need to be maintained by a dedicated team to help everyone in the monorepo. + +### Polyrepos - A Repository for Each Project + +If every project is placed in its own repository, each team can make their own organizational decisions without the need to consult with other teams. Unfortunately, this also means that each team has to make their own organizational decisions instead of focusing on feature work that provides business value. Sharing code is difficult with this set up and every maintenance task needs to be repeated across all the repositories in the organization. + +Nx can still be useful with this organizational structure. Tooling and maintenance tasks can be centralized through shared [Nx plugins](/concepts/nx-plugins) that each repository can opt-in to using. Since creating repositories is a frequent occurrence in this scenario, Nx [generators](/features/generate-code) can be used to quickly scaffold out the repository with reasonable tooling defaults. + +### Multiple Monorepos + +Somewhere between the single monorepo and the full polyrepo solutions exists the multiple monorepo setup. Typically when there are disagreements about organizational decisions, there are two or three factions that form. These factions can naturally be allocated to separate monorepos that have been configured in a way that best suits the teams that will be working in them. + +Compared to the single monorepo setup, this setup requires some extra overhead cost - maintaining multiple CI pipelines and performing the same tooling maintenance tasks on multiple repositories, but this cost could be offset by the extra productivity boost provided by the fact that each team can work in a repository that is optimized for the way that they work. diff --git a/docs/shared/guides/why-monorepos.md b/docs/shared/concepts/decisions/monorepos.md similarity index 91% rename from docs/shared/guides/why-monorepos.md rename to docs/shared/concepts/decisions/monorepos.md index d853aa269a..6b1c79da07 100644 --- a/docs/shared/guides/why-monorepos.md +++ b/docs/shared/concepts/decisions/monorepos.md @@ -4,13 +4,13 @@ A monorepo is a single git repository that holds the source code for multiple ap ## What are the benefits of a monorepo? -- **Shared code and visibility** - [Keeps your code DRY across your entire organization.](/concepts/more-concepts/code-sharing) Reuse validation code, UI components, and types across the codebase. Reuse code between the backend, the frontend, and utility libraries. +- **Shared code and visibility** - [Keeps your code DRY across your entire organization.](/concepts/decisions/code-ownership) Reuse validation code, UI components, and types across the codebase. Reuse code between the backend, the frontend, and utility libraries. - **Atomic changes** - Change a server API and modify the downstream applications that consume that API in the same commit. You can change a button component in a shared library and the applications that use that component in the same commit. A monorepo saves the pain of trying to coordinate commits across multiple repositories. - **Developer mobility** - Get a consistent way of building and testing applications written using different tools and technologies. Developers can confidently contribute to other teams’ applications and verify that their changes are safe. -- **Single set of dependencies** - [Use a single version of all third-party dependencies](/concepts/more-concepts/dependency-management), reducing inconsistencies between applications. Less actively developed applications are still kept up-to-date with the latest version of a framework, library, or build tool. +- **Single set of dependencies** - [Use a single version of all third-party dependencies](/concepts/decisions/dependency-management), reducing inconsistencies between applications. Less actively developed applications are still kept up-to-date with the latest version of a framework, library, or build tool. ## Why not just code collocation? diff --git a/docs/shared/workspace/library-types.md b/docs/shared/concepts/decisions/project-dependency-rules.md similarity index 64% rename from docs/shared/workspace/library-types.md rename to docs/shared/concepts/decisions/project-dependency-rules.md index 5127a5d02f..ae4c8b311b 100644 --- a/docs/shared/workspace/library-types.md +++ b/docs/shared/concepts/decisions/project-dependency-rules.md @@ -1,6 +1,8 @@ -# Library Types +# Project Dependency Rules -There are many types of libraries in a workspace. In order to maintain a certain sense of order, we recommend having a small number of types, such as the below four (4) types of libraries. +There are many types of libraries in a workspace. You can identify the type of a library through a naming convention and/or by using the project tagging system. With explicitly defined types, you can also use Nx to enforce project dependency rules based on the types of each project. This article explains one possible way to organize your repository projects by type. Every repository is different and yours may need a different set of types. + +In order to maintain a certain sense of order, we recommend having a small number of types, such as the below four (4) types of libraries. **Feature libraries:** @@ -102,6 +104,49 @@ export { formatDate, formatTime } from './src/format-date-fns'; export { formatCurrency } from './src/format-currency'; ``` +## Enforce Project Dependency Rules + +In order to enforce the dependency constraints that were listed for each type, you can add the following rule in the root `.eslintrc.json` file: + +```json {% fileName="/.eslintrc.json" %} +{ + "root": true, + "ignorePatterns": ["**/*"], + "plugins": ["@nx"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": { + "@nx/enforce-module-boundaries": [ + "error", + { + "allow": [], + "depConstraints": [ + { + "sourceTag": "type:feature", + "onlyDependOnLibsWithTags": [ + "type:feature", + "type:ui", + "type:util" + ] + }, + { + "sourceTag": "type:ui", + "onlyDependOnLibsWithTags": ["type:ui", "type:util"] + }, + { + "sourceTag": "type:util", + "onlyDependOnLibsWithTags": ["type:util"] + } + ] + } + ] + } + } + ] +} +``` + ## Other Types You will probably come up with other library types that make sense for your organization. That's fine. Just keep a few things in mind: diff --git a/docs/shared/concepts/decisions/project-size.md b/docs/shared/concepts/decisions/project-size.md new file mode 100644 index 0000000000..5595ddb3da --- /dev/null +++ b/docs/shared/concepts/decisions/project-size.md @@ -0,0 +1,43 @@ +# Project Size + +Like a lot of decisions in programming, deciding to make a new Nx project or not is all about trade-offs. Each organization will decide on their own conventions, but here are some trade-offs to bear in mind as you have the conversation. + +## What is a Project For? + +> Developers new to Nx can be initially hesitant to move their logic into separate projects, because they assume it implies that those projects need to be general purpose and shareable across applications. + +**This is a common misconception, moving code into projects can be done from a pure code organization perspective.** + +Ease of re-use might emerge as a positive side effect of refactoring code into projects by applying an _"API thinking"_ approach. It is not the main driver though. + +In fact when organizing projects you should think about your business domains. + +## Should I Make a New Project? + +There are three main benefits to breaking your code up into more projects. + +### 1. Faster Commands + +The more granular your projects are, the more effective `nx affected` and Nx's computation cache will be. For example, if `projectA` contains 10 tests, but only 5 of them were affected by a particular code change, all 10 tests will be run by `nx affected -t test`. If you can predict which 5 tests are usually run together, you can split all the related code into a separate project to allow the two groups of 5 tests to be executed independently. + +### 2. Visualizing Architecture + +The `nx graph` command generates a graph of how apps and projects depend on each other. If most of your code lives in a few giant projects, this visualization doesn't provide much value. Adding the `--watch` flag to the command will update the visualization in-browser as you make changes. + +### 3. Enforcing Constraints + +You can enforce constraints on how different types of projects depend on each other [using tags](/features/enforce-module-boundaries). Following pre-determined conventions on what kind of code can go in different types of projects allows your tagging system to enforce good architectural patterns. + +Also, each project defines its own API, which allows for encapsulating logic that other parts of codebase can not access. You can even use a [CODEOWNERS file](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners) to assign ownership of a certain project to a user or team. + +## Should I Add to an Existing Project? + +Limiting the number of projects by keeping code in an existing project also has benefits. + +### 1. Consolidating Code + +Related code should be close together. If a developer can accomplish a task without moving between multiple different folders, it helps them work faster and make less mistakes. Every new project adds some folders and configuration files that are not directly contributing to business value. Nx helps reduce the cost of adding a new project, but it isn't zero. + +### 2. Removing Constraints + +Especially for rapidly evolving code, the standard architectural constraints may just get in the way of experimentation and exploration. It may be worthwhile to develop for a while in a single project in order to allow a real architecture to emerge and then refactoring into multiple projects once the pace of change has slowed down. diff --git a/docs/shared/recipes/running-tasks/executors-and-configurations.md b/docs/shared/concepts/executors-and-configurations.md similarity index 100% rename from docs/shared/recipes/running-tasks/executors-and-configurations.md rename to docs/shared/concepts/executors-and-configurations.md diff --git a/docs/shared/concepts/integrated-vs-package-based.md b/docs/shared/concepts/integrated-vs-package-based.md index 91224ba25d..fb1cad7c68 100644 --- a/docs/shared/concepts/integrated-vs-package-based.md +++ b/docs/shared/concepts/integrated-vs-package-based.md @@ -16,9 +16,9 @@ Nx's features can be enabled in each of these types of repositories. Just as eac ## Package-Based Repos -A package-based repo is a collection of packages that depend on each other via `package.json` files and nested `node_modules`. With this setup, you typically have [different dependencies for each project](/concepts/more-concepts/dependency-management). Build tools like Jest and Webpack work as usual, since everything is resolved as if each package was in a separate repo and all of its dependencies were published to npm. Moving an existing package into a package-based repo is very easy since you generally leave that package's existing build tooling untouched. Creating a new package inside the repo is just as difficult as spinning up a new repo since you have to create all the build tooling from scratch. +A package-based repo is a collection of packages that depend on each other via `package.json` files and nested `node_modules`. With this setup, you typically have [different dependencies for each project](/concepts/decisions/dependency-management). Build tools like Jest and Webpack work as usual, since everything is resolved as if each package was in a separate repo and all of its dependencies were published to npm. Moving an existing package into a package-based repo is very easy since you generally leave that package's existing build tooling untouched. Creating a new package inside the repo is just as difficult as spinning up a new repo since you have to create all the build tooling from scratch. -Lerna, Yarn, Lage, [Turborepo](/concepts/more-concepts/turbo-and-nx) and Nx support this style. +Lerna, Yarn, Lage, [Turborepo](/concepts/turbo-and-nx) and Nx support this style. Someone who appreciates the flexibility of a package-based repository will be most interested in the following features of Nx: @@ -32,7 +32,7 @@ Someone who appreciates the flexibility of a package-based repository will be mo ## Integrated Repos -An integrated repo contains projects that depend on each other through standard import statements. There is typically a [single version of every dependency](/concepts/more-concepts/dependency-management) defined at the root. Sometimes build tools like Jest and Webpack need to be wrapped to work correctly. It's harder to add an existing package to this repo style because the build tooling for that package may need to be modified. It's straightforward to add a brand-new project to the repo because all the tooling decisions have already been made. +An integrated repo contains projects that depend on each other through standard import statements. There is typically a [single version of every dependency](/concepts/decisions/dependency-management) defined at the root. Sometimes build tools like Jest and Webpack need to be wrapped to work correctly. It's harder to add an existing package to this repo style because the build tooling for that package may need to be modified. It's straightforward to add a brand-new project to the repo because all the tooling decisions have already been made. Bazel and Nx support this style. diff --git a/docs/shared/mental-model.md b/docs/shared/concepts/mental-model.md similarity index 100% rename from docs/shared/mental-model.md rename to docs/shared/concepts/mental-model.md diff --git a/docs/shared/guides/module-federation/dep-graph-2.png b/docs/shared/concepts/module-federation/dep-graph-2.png similarity index 100% rename from docs/shared/guides/module-federation/dep-graph-2.png rename to docs/shared/concepts/module-federation/dep-graph-2.png diff --git a/docs/shared/guides/module-federation/faster-builds.md b/docs/shared/concepts/module-federation/faster-builds.md similarity index 98% rename from docs/shared/guides/module-federation/faster-builds.md rename to docs/shared/concepts/module-federation/faster-builds.md index 054c110b43..74b745f097 100644 --- a/docs/shared/guides/module-federation/faster-builds.md +++ b/docs/shared/concepts/module-federation/faster-builds.md @@ -48,7 +48,7 @@ In the next section, we will see an example with a host app (`host`) and three r Although all the applications are independently built, thus have no dependency between them, conceptually you can think of them in the following hierarchy. -![Host with implicit dependencies to remotes](/shared/guides/module-federation/dep-graph-2.png) +![Host with implicit dependencies to remotes](/shared/concepts/module-federation/dep-graph-2.png) ## Creating an example workspace @@ -72,7 +72,7 @@ that are simple to set up. You can see what the CI does by viewing the sample pu the [Nx Cloud](https://nx.app) integration, which gives you insight into each pipeline. We'll touch on this [later in this guide](#remote-computation-caching-with-nx-cloud). -![Nx Cloud integration for GitHub](/shared/guides/module-federation/pull-request.png) +![Nx Cloud integration for GitHub](/shared/concepts/module-federation/pull-request.png) Now, let's continue by creating an empty Nx workspace. @@ -350,7 +350,7 @@ In addition to computation caching, Nx Cloud also comes with: - GitHub integration, so you can easily access important information without digging through a bunch of CI/CD logs. - Actionable insights, which improve caching and task distribution. -![Nx Cloud run details](/shared/guides/module-federation/nx-cloud.png) +![Nx Cloud run details](/shared/concepts/module-federation/nx-cloud.png) ## Production build and deployment with Nx Cloud diff --git a/docs/shared/guides/module-federation/manage-library-versions-with-module-federation.md b/docs/shared/concepts/module-federation/manage-library-versions-with-module-federation.md similarity index 96% rename from docs/shared/guides/module-federation/manage-library-versions-with-module-federation.md rename to docs/shared/concepts/module-federation/manage-library-versions-with-module-federation.md index 4af16e7397..144ae3b9fb 100644 --- a/docs/shared/guides/module-federation/manage-library-versions-with-module-federation.md +++ b/docs/shared/concepts/module-federation/manage-library-versions-with-module-federation.md @@ -13,10 +13,10 @@ To mitigate these issues, Module Federation has a shared API. Its primary functi The Shared API maintains a registry of all the downloaded dependencies. When a federated module requests a dependency, the Shared API checks the registry. If the dependency already exists, the module is directed to use the existing copy. If not, the dependency is downloaded and added to the registry. -![How Shared API works](/shared/guides/module-federation/shared-api.png) +![How Shared API works](/shared/concepts/module-federation/shared-api.png) {% callout type="info" title="Lost?" %} -If you are not familiar with the concepts of federated modules, remotes, and hosts, please read the [Faster builds with module federation](https://nx.dev/concepts/more-concepts/faster-builds-with-module-federation) for an introduction. +If you are not familiar with the concepts of federated modules, remotes, and hosts, please read the [Faster builds with module federation](/concepts/module-federation/faster-builds-with-module-federation) for an introduction. {% /callout %} ## Our Approach @@ -60,7 +60,7 @@ A common use-case for this is if you want to enable tree-shaking for a library l **Nx** determines the version of a library by looking at a `package.json`. If the library is an npm package, the version is determined by the version declared in the workspace `package.json`. If the library is a workspace library, the version is determined by the version in the `package.json` of the project that consumes the shared library. RemoteA consumes Counter, which is a workspace library exposed and shared by RemoteB. The version of Counter is determined by the version in RemoteB's `package.json`. If the `package.json` does not exist or the library is not declared, Nx will use the version in the `package.json` of the workspace library. -![How Nx determines library versions](/shared/guides/module-federation/nx-library-version.png) +![How Nx determines library versions](/shared/concepts/module-federation/nx-library-version.png) There are twos ways to manage library versions with **Nx**: diff --git a/docs/shared/guides/module-federation/mfe-dep-graph.png b/docs/shared/concepts/module-federation/mfe-dep-graph.png similarity index 100% rename from docs/shared/guides/module-federation/mfe-dep-graph.png rename to docs/shared/concepts/module-federation/mfe-dep-graph.png diff --git a/docs/shared/guides/module-federation/micro-frontend-architecture.md b/docs/shared/concepts/module-federation/micro-frontend-architecture.md similarity index 98% rename from docs/shared/guides/module-federation/micro-frontend-architecture.md rename to docs/shared/concepts/module-federation/micro-frontend-architecture.md index ead876f3e4..1a29b86b66 100644 --- a/docs/shared/guides/module-federation/micro-frontend-architecture.md +++ b/docs/shared/concepts/module-federation/micro-frontend-architecture.md @@ -40,7 +40,7 @@ to exist between host and remotes. For example, if you have a `shell` host application, with three remotes -- `about`, `cart`, `shop` -- and a shared `ui-button` library, then your project graph might look something like this. -![MFE setup with independent projects](/shared/guides/module-federation/mfe-dep-graph.png) +![MFE setup with independent projects](/shared/concepts/module-federation/mfe-dep-graph.png) Keeping the applications independent allows them to be deployed on different cadences, which is the whole point of MFEs. diff --git a/docs/shared/guides/module-federation/module-federation-and-nx.md b/docs/shared/concepts/module-federation/module-federation-and-nx.md similarity index 100% rename from docs/shared/guides/module-federation/module-federation-and-nx.md rename to docs/shared/concepts/module-federation/module-federation-and-nx.md diff --git a/docs/shared/guides/module-federation/nx-cloud.png b/docs/shared/concepts/module-federation/nx-cloud.png similarity index 100% rename from docs/shared/guides/module-federation/nx-cloud.png rename to docs/shared/concepts/module-federation/nx-cloud.png diff --git a/docs/shared/guides/module-federation/nx-library-version.png b/docs/shared/concepts/module-federation/nx-library-version.png similarity index 100% rename from docs/shared/guides/module-federation/nx-library-version.png rename to docs/shared/concepts/module-federation/nx-library-version.png diff --git a/docs/shared/guides/module-federation/pull-request.png b/docs/shared/concepts/module-federation/pull-request.png similarity index 100% rename from docs/shared/guides/module-federation/pull-request.png rename to docs/shared/concepts/module-federation/pull-request.png diff --git a/docs/shared/guides/module-federation/shared-api.png b/docs/shared/concepts/module-federation/shared-api.png similarity index 100% rename from docs/shared/guides/module-federation/shared-api.png rename to docs/shared/concepts/module-federation/shared-api.png diff --git a/docs/shared/guides/nx-media-monorepo.jpg b/docs/shared/concepts/nx-media-monorepo.jpg similarity index 100% rename from docs/shared/guides/nx-media-monorepo.jpg rename to docs/shared/concepts/nx-media-monorepo.jpg diff --git a/docs/shared/guides/turbo-and-nx.md b/docs/shared/concepts/turbo-and-nx.md similarity index 99% rename from docs/shared/guides/turbo-and-nx.md rename to docs/shared/concepts/turbo-and-nx.md index 12c16e1bf6..b15576f1b2 100644 --- a/docs/shared/guides/turbo-and-nx.md +++ b/docs/shared/concepts/turbo-and-nx.md @@ -111,7 +111,7 @@ Getting started quickly is very easy. Check out some of the examples below: Nx core make things faster but doesn't change how your commands run or how the terminal output looks. Compare Nx's and Turbo's terminal outputs: -![nx and turbo terminal output](/shared/turbo-nx-terminal.gif) +![nx and turbo terminal output](/shared/concepts/turbo-nx-terminal.gif) Nx doesn't change your terminal output. Spinners, animations, colors are the same whether you use Nx or not (we instrument Node.js to get this result). What is also important is that when you restore things from cache, Nx will replay the terminal output identical to the one you would have had you run the command. Examine Turbo's output: no spinners, no animations, no colors. Pretty much anything you run with Turbo looks different (and in our opinion worse) from running the same command without Turbo. @@ -146,7 +146,7 @@ Turborepo is mostly written in Golang and Rust. Nx is mostly written in TypeScri Benchmarking is hard because a lot depends on what you are trying to run, in what environment, etc. This is one benchmark we use when measuring Nx perf: [Nx and Turbo benchmark](https://github.com/vsavkin/large-monorepo/). It is a repo with 5 Next.js apps. We are measuring how quickly Nx and Turbo can figure out what needs to be restored from cache, and how quickly they can do it. This is the result: -![nx and turbo benchmark](/shared/turbo-nx-perf.gif) +![nx and turbo benchmark](/shared/concepts/turbo-nx-perf.gif) Nx is 9.4 times faster on the latest MBP. We have made several changes to [the benchmark](https://github.com/vsavkin/large-monorepo/) since it was released (removed the usage `npx` and addressed other concerns folks had), but the result remained roughly the same. Please check out the benchmark. diff --git a/docs/shared/turbo-nx-perf.gif b/docs/shared/concepts/turbo-nx-perf.gif similarity index 100% rename from docs/shared/turbo-nx-perf.gif rename to docs/shared/concepts/turbo-nx-perf.gif diff --git a/docs/shared/turbo-nx-terminal.gif b/docs/shared/concepts/turbo-nx-terminal.gif similarity index 100% rename from docs/shared/turbo-nx-terminal.gif rename to docs/shared/concepts/turbo-nx-terminal.gif diff --git a/docs/shared/guides/react-native.md b/docs/shared/guides/react-native.md index 01694d8ef4..272d7f24c2 100644 --- a/docs/shared/guides/react-native.md +++ b/docs/shared/guides/react-native.md @@ -182,9 +182,6 @@ Nx allows you to create libraries with just one command. Some reasons you might - Publish a package to be used outside the monorepo - Better visualize the architecture using `npx nx graph` -For more information on Nx libraries, see our documentation on [Creating Libraries](/concepts/more-concepts/creating-libraries) -and [Library Types](/concepts/more-concepts/library-types). - To generate a new library run: ```shell diff --git a/docs/shared/migration/adding-to-monorepo.md b/docs/shared/migration/adding-to-monorepo.md index 0295d272e4..4054bf345e 100644 --- a/docs/shared/migration/adding-to-monorepo.md +++ b/docs/shared/migration/adding-to-monorepo.md @@ -321,7 +321,7 @@ documentation" url="/concepts/task-pipeline-configuration" /%} url="/reference/nxignore" /%} {% card title="Nx and Turbo" description="Read about how Nx compares to Turborepo" url=" -/concepts/more-concepts/turbo-and-nx" /%} +/concepts/turbo-and-nx" /%} {% card title="Integrated Repos vs Package-Based Repos" description="Learn about two styles of monorepos." url=" /concepts/integrated-vs-package-based" /%} diff --git a/docs/shared/migration/from-turborepo.md b/docs/shared/migration/from-turborepo.md index 92b14289d3..1df3736d33 100644 --- a/docs/shared/migration/from-turborepo.md +++ b/docs/shared/migration/from-turborepo.md @@ -2,7 +2,7 @@ If you have an existing monorepo that uses Turborepo, switching to use Nx is a straight-forward process. After switching, you'll have cleaner CLI output, a better graph view and IDE support with the option to incorporate Nx plugins and take advantage of the features of an integrated repository. All this without increasing the complexity of your configuration files. -For more details, read our [comparison of Nx and Turborepo](/concepts/more-concepts/turbo-and-nx) +For more details, read our [comparison of Nx and Turborepo](/concepts/turbo-and-nx) ## Initialize Nx @@ -139,7 +139,7 @@ For each `turbo.json` configuration property, the equivalent Nx property is list | `--ignore` | Use an [`.nxignore` file](/reference/nxignore) (or `.gitignore`) | | `--log-order` | Use [`--output-style`](/nx-api/nx/documents/run-many#output-style) | | `--no-cache` | Use [`--skip-nx-cache`](/nx-api/nx/documents/run-many#skip-nx-cache) | -| `--no-daemon` | Use [`NX_DAEMON=false` or set `useDaemonProcess: false`](/concepts/more-concepts/nx-daemon#turning-it-off) in `nx.json` | +| `--no-daemon` | Use [`NX_DAEMON=false` or set `useDaemonProcess: false`](/concepts/nx-daemon#turning-it-off) in `nx.json` | | `--output-logs` | Use [`--output-style`](/nx-api/nx/documents/run-many#output-style) | | `--only` | N/A | | `--parallel` | N/A | diff --git a/docs/shared/packages/angular/angular-plugin.md b/docs/shared/packages/angular/angular-plugin.md index 4af5191ba9..8d0c13e2a3 100644 --- a/docs/shared/packages/angular/angular-plugin.md +++ b/docs/shared/packages/angular/angular-plugin.md @@ -111,9 +111,9 @@ nx lint libName Read more about: -- [Creating Libraries](/concepts/more-concepts/creating-libraries) -- [Library Types](/concepts/more-concepts/library-types) -- [Buildable and Publishable Libraries](/concepts/more-concepts/buildable-and-publishable-libraries) +- [Creating Libraries](/concepts/decisions/project-size) +- [Library Types](/concepts/decisions/project-dependency-rules) +- [Buildable and Publishable Libraries](/concepts/buildable-and-publishable-libraries) ### Fallback to `@schematics/angular` diff --git a/docs/shared/packages/nest/nest-plugin.md b/docs/shared/packages/nest/nest-plugin.md index bcf3bef876..faee847595 100644 --- a/docs/shared/packages/nest/nest-plugin.md +++ b/docs/shared/packages/nest/nest-plugin.md @@ -88,7 +88,7 @@ To make the library `publishable`, use the following command: nx g @nx/nest:lib my-nest-lib --publishable --importPath=@my-workspace/my-nest-lib ``` -> Read more about [building and publishing libraries here](/concepts/more-concepts/buildable-and-publishable-libraries). +> Read more about [building and publishing libraries here](/concepts/buildable-and-publishable-libraries). ### Nest Generators diff --git a/docs/shared/packages/next/plugin-overview.md b/docs/shared/packages/next/plugin-overview.md index 503b56d975..61b85b540a 100644 --- a/docs/shared/packages/next/plugin-overview.md +++ b/docs/shared/packages/next/plugin-overview.md @@ -108,9 +108,6 @@ Nx allows you to create libraries with just one command. Some reasons you might - Publish a package to be used outside the monorepo - Better visualize the architecture using `nx graph` -For more information on Nx libraries, see our documentation on [Creating Libraries](/concepts/more-concepts/creating-libraries) -and [Library Types](/concepts/more-concepts/library-types). - To generate a new library run: ```shell diff --git a/docs/shared/packages/react/react-plugin.md b/docs/shared/packages/react/react-plugin.md index 947c67178a..a6cc780093 100644 --- a/docs/shared/packages/react/react-plugin.md +++ b/docs/shared/packages/react/react-plugin.md @@ -70,7 +70,7 @@ nx g @nx/react:lib my-new-lib \ --importPath=@myorg/my-new-lib ``` -Read more about [building and publishing libraries here](/concepts/more-concepts/buildable-and-publishable-libraries). +Read more about [building and publishing libraries here](/concepts/buildable-and-publishable-libraries). ### Creating Components diff --git a/docs/shared/packages/storybook/best-practices.md b/docs/shared/packages/storybook/best-practices.md index 2fec8281b1..976893d7d5 100644 --- a/docs/shared/packages/storybook/best-practices.md +++ b/docs/shared/packages/storybook/best-practices.md @@ -87,7 +87,7 @@ In the following section, we are going to see how to set up Storybook in these c ### Philosophy -Setting up Storybook on Nx reflects - and takes advantage of - the [mental model](/concepts/mental-model) of Nx, and especially the architecture of [Applications and Libraries](/concepts/more-concepts/applications-and-libraries). What that means, in essence, is that you still maintain the individual Storybook instances (per project) which you use for testing and local development, but you also keep one extra “container” for publishing, that serves as a single entry point. Let’s see this in more detail. +Setting up Storybook on Nx reflects - and takes advantage of - the [mental model](/concepts/mental-model) of Nx. What that means, in essence, is that you still maintain the individual Storybook instances (per project) which you use for testing and local development, but you also keep one extra “container” for publishing, that serves as a single entry point. Let’s see this in more detail. #### Local development and testing @@ -119,7 +119,7 @@ Since each Storybook, in this case, is attached to a project, so is the serving #### Publishing -When you are publishing your Storybook, you can follow the same principles described in the [Applications and Libraries Mental Model](/concepts/more-concepts/applications-and-libraries#mental-model) documentation page. The general idea is to have one central Storybook container, into which you are going to gather your stories from multiple libraries. +When you are publishing your Storybook, you can follow the same principles described in the [Applications and Libraries Mental Model](/concepts/decisions/project-size#mental-model) documentation page. The general idea is to have one central Storybook container, into which you are going to gather your stories from multiple libraries. You can think of the central Storybook container as a grouping of similar-concept or same-scope UI parts of your workspace. In the same way you are scoping libraries, you can group your stories as well. @@ -129,7 +129,7 @@ Then, according to your use-case, you can have one central Storybook for your wh In order to achieve some things mentioned above, you may use [Storybook Composition](/recipes/storybook/storybook-composition-setup). However, in this case, you would still need to build each project’s Storybook individually, and also deploy it individually. So in the cases where you have multiple projects, Storybook Composition would not be very efficient. {% /callout %} -Before moving on to the examples section, it could be useful to read the [Library Types](/concepts/more-concepts/library-types) documentation page and the [Grouping libraries](/concepts/more-concepts/grouping-libraries) documentation page. These could help you decide which way fits your use case better. +Before moving on to the examples section, it could be useful to read the [Library Types](/concepts/decisions/project-dependency-rules) documentation page and the [Grouping libraries](/concepts/decisions/folder-structure) documentation page. These could help you decide which way fits your use case better. ## Examples / Use cases diff --git a/docs/shared/guides/module-federation/dynamic-mfe-angular.md b/docs/shared/recipes/module-federation/dynamic-mfe-angular.md similarity index 100% rename from docs/shared/guides/module-federation/dynamic-mfe-angular.md rename to docs/shared/recipes/module-federation/dynamic-mfe-angular.md diff --git a/docs/shared/recipes/repo-types/integrated-in-package-based.md b/docs/shared/recipes/repo-types/integrated-in-package-based.md index 4782fae49d..f20c3c5d1b 100644 --- a/docs/shared/recipes/repo-types/integrated-in-package-based.md +++ b/docs/shared/recipes/repo-types/integrated-in-package-based.md @@ -11,7 +11,7 @@ The integrated project is now ready to use. Next, we'll discuss some of the chan ## package.json dependencies -All the dependencies that are required for an integrated project are maintained in the root `package.json` file. In order to use the plugin's [Automate Updating Framework Dependencies](/features/automate-updating-dependencies) feature, we recommend using a [Single Version Policy](/concepts/more-concepts/dependency-management#single-version-policy) for integrated projects. +All the dependencies that are required for an integrated project are maintained in the root `package.json` file. In order to use the plugin's [Automate Updating Framework Dependencies](/features/automate-updating-dependencies) feature, we recommend using a [Single Version Policy](/concepts/decisions/dependency-management#single-version-policy) for integrated projects. ## tsconfig.base.json diff --git a/docs/shared/recipes/repo-types/package-based-in-integrated.md b/docs/shared/recipes/repo-types/package-based-in-integrated.md index 9cd741b487..7bf9f78735 100644 --- a/docs/shared/recipes/repo-types/package-based-in-integrated.md +++ b/docs/shared/recipes/repo-types/package-based-in-integrated.md @@ -27,7 +27,7 @@ With [npm](https://docs.npmjs.com/cli/v7/using-npm/workspaces)/[yarn](https://cl When you manage dependencies this way, you can still hoist dependencies to the root-level `package.json` file, but you have to make the explicit decision for each dependency. -There are difficulties with code sharing when you maintain separate dependencies. See the [Dependency Management Strategies](/concepts/more-concepts/dependency-management) guide for more information. +There are difficulties with code sharing when you maintain separate dependencies. See the [Dependency Management Strategies](/concepts/decisions/dependency-management) guide for more information. ## Run Tasks Without the Use of an Nx Plugin diff --git a/docs/shared/recipes/storybook/one-storybook-per-scope.md b/docs/shared/recipes/storybook/one-storybook-per-scope.md index 38cf9fe16f..ce14e83304 100644 --- a/docs/shared/recipes/storybook/one-storybook-per-scope.md +++ b/docs/shared/recipes/storybook/one-storybook-per-scope.md @@ -8,7 +8,7 @@ description: Learn how to set up individual Storybook instances for each scope w This guide extends the [Using Storybook in a Nx workspace - Best practices](/nx-api/storybook/documents/best-practices) guide. In that guide, we discussed the best practices of using Storybook in a Nx workspace. We explained the main concepts and the mental model of how to best set up Storybook. In this guide, we are going to see how to put that into practice, by looking at a real-world example. We are going to see how you can publish one Storybook per scope (eg. theme, app, framework) for your workspace. -Sometimes, you have multiple apps and libraries, and each of these is associated with a specific scope. You can read more about grouping libraries and scoping them in the [Library Types](/concepts/more-concepts/library-types) documentation page. +Sometimes, you have multiple apps and libraries, and each of these is associated with a specific scope. You can read more about grouping libraries and scoping them in the [Library Types](/concepts/decisions/project-dependency-rules) documentation page. In this case, you can have one Storybook instance per scope. If you follow the folder organization convention described above, it is easy to configure Storybook to import all the stories under a specific folder, for example, which are associated with a specific app or scope. diff --git a/docs/shared/reference/glossary.md b/docs/shared/reference/glossary.md index fcb4f2def3..2d68fc1de4 100644 --- a/docs/shared/reference/glossary.md +++ b/docs/shared/reference/glossary.md @@ -8,8 +8,6 @@ This is a short list of Nx-specific terms that will help you understand the rest A [project](#project) that can run on its own. Generally uses [libraries](#library). -> See: [Applications and Libraries](/concepts/more-concepts/applications-and-libraries) - ### Atomizer The Atomizer is an Nx Cloud feature that automatically splits tasks so that they can be executed in parallel. @@ -22,7 +20,7 @@ Atomizer automatically splits tasks on [Nx Agents](#nx-agents), providing you de A [library](#library) that has a `build` [target](#target). Some libraries can be generated with a `build` target using the `--buildable` flag. -> See: [Publishable and Buildable Nx Libraries](/concepts/more-concepts/buildable-and-publishable-libraries) +> See: [Publishable and Buildable Nx Libraries](/concepts/buildable-and-publishable-libraries) ### Cache @@ -120,14 +118,10 @@ Launch Templates are used to set up an agent machine. They specify a resource cl A [project](#project) that is used by [applications](#application) or other [libraries](#library). -> See: [Applications and Libraries](/concepts/more-concepts/applications-and-libraries) - ### Monolith A large [application](#application) that is difficult to separate into smaller pieces. -> See: [Applications and Libraries](/concepts/more-concepts/applications-and-libraries) - ### Monorepo A repository with multiple [projects](#project). @@ -180,13 +174,11 @@ Related [projects](#project) spread across multiple repositories. The unit of code on which a [task](#task) can be run. A project can be an [application](#application) or a [library](#library). -> See: [Applications and Libraries](/concepts/more-concepts/applications-and-libraries) - ### Publishable Library A [library](#library) that has a `publish` [target](#target). Some libraries can be generated with a `publish` target using the `--publishable` flag. -> See: [Publishable and Buildable Nx Libraries](/concepts/more-concepts/buildable-and-publishable-libraries) +> See: [Publishable and Buildable Nx Libraries](/concepts/buildable-and-publishable-libraries) ### Remote Cache diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index 781a8cc95f..fac68d3394 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -31,22 +31,22 @@ - [Types of Configuration](/concepts/types-of-configuration) - [Executors and Configurations](/concepts/executors-and-configurations) - [Integrated Repos vs. Package-Based Repos vs. Standalone Apps](/concepts/integrated-vs-package-based) + - [Nx Daemon](/concepts/nx-daemon) + - [Nx and Turborepo](/concepts/turbo-and-nx) + - [Buildable and Publishable Libraries](/concepts/buildable-and-publishable-libraries) - [Module Federation](/concepts/module-federation) - [Module Federation and Nx](/concepts/module-federation/module-federation-and-nx) - [Faster Builds with Module Federation](/concepts/module-federation/faster-builds-with-module-federation) - [Micro Frontend Architecture](/concepts/module-federation/micro-frontend-architecture) - [Manage Library Versions with Module Federation](/concepts/module-federation/manage-library-versions-with-module-federation) - - [More Concepts](/concepts/more-concepts) - - [Monorepos](/concepts/more-concepts/why-monorepos) - - [Dependency Management](/concepts/more-concepts/dependency-management) - - [Code Sharing](/concepts/more-concepts/code-sharing) - - [Nx Daemon](/concepts/more-concepts/nx-daemon) - - [Nx and Turborepo](/concepts/more-concepts/turbo-and-nx) - - [Applications and Libraries](/concepts/more-concepts/applications-and-libraries) - - [When to Create a New Library](/concepts/more-concepts/creating-libraries) - - [Library Types](/concepts/more-concepts/library-types) - - [Grouping Libraries](/concepts/more-concepts/grouping-libraries) - - [Buildable and Publishable Libraries](/concepts/more-concepts/buildable-and-publishable-libraries) + - [Organizational Decisions](/concepts/decisions) + - [Overview](/concepts/decisions/overview) + - [Monorepos](/concepts/decisions/why-monorepos) + - [Dependency Management](/concepts/decisions/dependency-management) + - [Code Ownership](/concepts/decisions/code-ownership) + - [Project Size](/concepts/decisions/project-size) + - [Project Dependency Rules](/concepts/decisions/project-dependency-rules) + - [Folder Structure](/concepts/decisions/folder-structure) - [Recipes](/recipes) - [Installation](/recipes/installation) - [Install Nx in a Non-Javascript Repo](/recipes/installation/install-non-javascript) diff --git a/docs/shared/tutorials/angular-monorepo.md b/docs/shared/tutorials/angular-monorepo.md index 3ce320e1e2..da717bc47a 100644 --- a/docs/shared/tutorials/angular-monorepo.md +++ b/docs/shared/tutorials/angular-monorepo.md @@ -106,7 +106,7 @@ The setup includes: - ESLint preconfigured - Jest preconfigured -Typically, an integrated Nx workspace places application projects in the `apps` folder and library projects in the `libs` folder. [Applications are encouraged to be as light-weight as possible](/concepts/more-concepts/applications-and-libraries) so that more code is pushed into libraries and can be reused in other projects. This folder structure is just a suggestion and can be modified to suit your organization's needs. +Typically, an integrated Nx workspace places application projects in the `apps` folder and library projects in the `libs` folder. Applications are encouraged to be as light-weight as possible so that more code is pushed into libraries and can be reused in other projects. This folder structure is just a suggestion and can be modified to suit your organization's needs. The [`nx.json` file](/reference/nx-json) contains configuration settings for Nx itself and global default settings that individual projects inherit. The `apps/angular-store/project.json` file contains [settings that are specific to the `angular-store` project](/reference/project-configuration). We'll examine that file more in the next section. diff --git a/docs/shared/tutorials/angular-standalone.md b/docs/shared/tutorials/angular-standalone.md index 5bcf996c2b..f2ba2c8b9f 100644 --- a/docs/shared/tutorials/angular-standalone.md +++ b/docs/shared/tutorials/angular-standalone.md @@ -886,7 +886,7 @@ Once you modularize your codebase you want to make sure that the modules are not When building these kinds of constraints you usually have two dimensions: -- **type of project:** what is the type of your library. Example: "feature" library, "utility" library, "data-access" library, "ui" library (see [library types](/concepts/more-concepts/library-types)) +- **type of project:** what is the type of your library. Example: "feature" library, "utility" library, "data-access" library, "ui" library (see [library types](/concepts/decisions/project-dependency-rules)) - **scope (domain) of the project:** what domain area is covered by the project. Example: "orders", "products", "shared" ... this really depends on the type of product you're developing Nx comes with a generic mechanism that allows you to assign "tags" to projects. "tags" are arbitrary strings you can assign to a project that can be used later when defining boundaries between projects. For example, go to the `project.json` of your `orders` library and assign the tags `type:feature` and `scope:orders` to it. diff --git a/docs/shared/tutorials/react-monorepo.md b/docs/shared/tutorials/react-monorepo.md index b5ef3757cb..bea07224c6 100644 --- a/docs/shared/tutorials/react-monorepo.md +++ b/docs/shared/tutorials/react-monorepo.md @@ -28,7 +28,7 @@ Nx Plugins are optional packages that extend the capabilities of Nx, catering to Features of an integrated monorepo: -- [Install dependencies at the root by default](/concepts/more-concepts/dependency-management#single-version-policy) +- [Install dependencies at the root by default](/concepts/decisions/dependency-management#single-version-policy) - [Scaffold new code with generators](/features/generate-code) - [Updates dependencies with automated migrations](/features/automate-updating-dependencies) @@ -103,7 +103,7 @@ The setup includes.. - ESLint preconfigured - Jest preconfigured -Typically, an integrated Nx workspace places application projects in the `apps` folder and library projects in the `libs` folder. [Applications are encouraged to be as light-weight as possible](/concepts/more-concepts/applications-and-libraries) so that more code is pushed into libraries and can be reused in other projects. This folder structure is just a suggestion and can be modified to suit your organization's needs. +Typically, an integrated Nx workspace places application projects in the `apps` folder and library projects in the `libs` folder. Applications are encouraged to be as light-weight as possible so that more code is pushed into libraries and can be reused in other projects. This folder structure is just a suggestion and can be modified to suit your organization's needs. The [`nx.json` file](/reference/nx-json) contains configuration settings for Nx itself and global default settings that individual projects inherit. The `apps/react-store/project.json` file contains [settings that are specific to the `react-store` project](/reference/project-configuration). We'll examine that file more in the next section. diff --git a/docs/shared/tutorials/vue-standalone.md b/docs/shared/tutorials/vue-standalone.md index f416d9963f..4fc001c179 100644 --- a/docs/shared/tutorials/vue-standalone.md +++ b/docs/shared/tutorials/vue-standalone.md @@ -714,7 +714,7 @@ Once you modularize your codebase you want to make sure that the modules are not When building these kinds of constraints you usually have two dimensions: -- **type of project:** what is the type of your library. Example: "feature" library, "utility" library, "data-access" library, "ui" library (see [library types](/concepts/more-concepts/library-types)) +- **type of project:** what is the type of your library. Example: "feature" library, "utility" library, "data-access" library, "ui" library (see [library types](/concepts/decisions/project-dependency-rules)) - **scope (domain) of the project:** what domain area is covered by the project. Example: "orders", "products", "shared" ... this really depends on the type of product you're developing Nx comes with a generic mechanism that allows you to assign "tags" to projects. "tags" are arbitrary strings you can assign to a project that can be used later when defining boundaries between projects. For example, go to the `project.json` of your `orders` library and assign the tags `type:feature` and `scope:orders` to it. diff --git a/docs/shared/workspace/applications-and-libraries.md b/docs/shared/workspace/applications-and-libraries.md deleted file mode 100644 index a1cbd48390..0000000000 --- a/docs/shared/workspace/applications-and-libraries.md +++ /dev/null @@ -1,50 +0,0 @@ -# Applications and libraries - -A typical Nx workspace is structured into _"apps"_ and _"libs"_. This distinction allows us to have a more modular architecture by following a separation of concerns methodology, incentivizing the organization of our source code and logic into smaller, more focused and highly cohesive units. - -Nx automatically creates TypeScript path mappings in the `tsconfig.base.json` file, such that they can be easily consumed by other apps or libs. - -```typescript -// example of importing from another workspace library -import { Button } from '@my-organization/ui'; -... -``` - -Therefore, consuming libraries is very straightforward, and similar to what you might already be accustomed to in previous projects. - -Having a dedicated library project is a much stronger boundary compared to just separating code into folders, though. Each Nx library has a so-called _"public API"_, represented by an `index.ts` barrel file. This forces developers into an _"API thinking"_ of what should be exposed and thus be made available for others to consume, and what on the others side should remain private within the library itself. - -{% callout type="caution" title="Library !== published artifact" %} -[This is a common misconception, moving code into libraries can be done from a pure code organization perspective](#misconception). -{% /callout %} - -## Mental model - -A common mental model is to **see the application as "containers"** that link, bundle and compile functionality implemented in libraries for being deployed. -As such, if we follow a _80/20 approach_: - -- place 80% of your logic into the `libs/` folder -- and 20% into `apps/` - -Note, these libraries don’t necessarily need to be built separately, but are rather consumed and built by the application itself directly. Hence, nothing changes from a pure deployment point of view. - -That said, it is totally possible to create so-called _"[buildable libraries](/concepts/more-concepts/buildable-and-publishable-libraries#buildable-libraries)"_ for enabling incremental builds as -well as _"[publishable libraries](/concepts/more-concepts/buildable-and-publishable-libraries#publishable-libraries)"_ for those scenarios where not only you want to -use a specific library within the current Nx workspace, but also to publish it -to some package repository (e.g. NPM). - -### Misconception - -> Developers new to Nx are initially often hesitant to move their logic into libraries, because they assume it implies that those libraries need to be general purpose and shareable across applications. - -**This is a common misconception, moving code into libraries can be done from a pure code organization perspective.** - -Ease of re-use might emerge as a positive side effect of refactoring code into libraries by applying an _"API thinking"_ approach. It is not the main driver though. - -In fact when organizing libraries you should think about your business domains. - -Most often teams are aligned with those domains and thus a similar organization of the libraries in the `libs/` folder might be most appropriate. Nx allows to nest libraries into sub-folders which makes it easy to reflect such structuring. - -- [Learn more about when you need to create a new library or using an existing one](/concepts/more-concepts/creating-libraries) -- [Learn more about the different types of libraries we think you should follow](/concepts/more-concepts/library-types) -- [Learn more about how to group libraries between each other](/concepts/more-concepts/grouping-libraries) diff --git a/docs/shared/workspace/creating-libraries.md b/docs/shared/workspace/creating-libraries.md deleted file mode 100644 index d6c2ebbddf..0000000000 --- a/docs/shared/workspace/creating-libraries.md +++ /dev/null @@ -1,33 +0,0 @@ -# Creating Libraries - -Like a lot of decisions in programming, deciding to make a new Nx library or not is all about trade-offs. Each organization will decide on their own conventions, but here are some trade-offs to bear in mind as you have the conversation. - -## Should I Make a New Library? - -There are three main benefits to breaking your code up into more libraries. - -### 1. Faster Commands - -The more granular your libraries are, the more effective `nx affected` and Nx's computation cache will be. For example, if `libraryA` contains 10 tests, but only 5 of them were affected by a particular code change, all 10 tests will be run by `nx affected -t test`. If you can predict which 5 tests are usually run together, you can split all the related code into a separate library to allow the two groups of 5 tests to be executed independently. - -### 2. Visualizing Architecture - -The `nx graph` command generates a graph of how apps and libraries depend on each other. If most of your code lives in a few giant libraries, this visualization doesn't provide much value. Adding the `--watch` flag to the command will update the visualization in-browser as you make changes. - -### 3. Enforcing Constraints - -You can enforce constraints on how different types of libraries depend on each other [using tags](/features/enforce-module-boundaries). Following pre-determined conventions on what kind of code can go in different types of libraries allows your tagging system to enforce good architectural patterns. - -Also, each library defines its own API, which allows for encapsulating logic that other parts of codebase can not access. You can even use a [CODEOWNERS file](https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners) to assign ownership of a certain library to a user or team. - -## Should I Add to an Existing Library? - -Limiting the number of libraries by keeping code in an existing library also has benefits. - -### 1. Consolidating Code - -Related code should be close together. If a developer can accomplish a task without moving between multiple different folders, it helps them work faster and make less mistakes. Every new library adds some folders and configuration files that are not directly contributing to business value. Nx helps reduce the cost of adding a new library, but it isn't zero. - -### 2. Removing Constraints - -Especially for rapidly evolving code, the standard architectural constraints may just get in the way of experimentation and exploration. It may be worthwhile to develop for a while in a single library in order to allow a real architecture to emerge and then refactoring into multiple libraries once the pace of change has slowed down. diff --git a/docs/shared/workspace/grouping-libraries.md b/docs/shared/workspace/grouping-libraries.md deleted file mode 100644 index e92b4d0607..0000000000 --- a/docs/shared/workspace/grouping-libraries.md +++ /dev/null @@ -1,65 +0,0 @@ -# Grouping Libraries - -Libraries should be grouped by _scope_. A library's scope is either application to which it belongs or (for larger applications) a section within that application. - -## Move Generator - -Don't be too anxious about choosing the exact right folder structure from the beginning. Libraries can be moved or renamed using the [`@nx/workspace:move` generator](/nx-api/workspace/generators/move). - -For instance, if a library under the `booking` folder is now being shared by multiple apps, you can move it to the shared folder like this: - -```shell -nx g move --project booking-some-library shared/some-library -``` - -## Remove Generator - -Similarly, if you no longer need a library, you can remove it with the [`@nx/workspace:remove` generator](/nx-api/workspace/generators/remove). - -```shell -nx g remove booking-some-library -``` - -## Example Workspace - -Let's use Nrwl Airlines as an example organization. This organization has two apps, `booking` and `check-in`. In the Nx workspace, libraries related to `booking` are grouped under a `libs/booking` folder, libraries related to `check-in` are grouped under a `libs/check-in` folder and libraries used in both applications are placed in `libs/shared`. You can also have nested grouping folders, (i.e. `libs/shared/seatmap`). - -The purpose of these folders is to help with organizing by scope. We recommend grouping libraries together which are (usually) updated together. It helps minimize the amount of time a developer spends navigating the folder tree to find the right file. - -```text -apps/ - booking/ - check-in/ -libs/ - booking/ <---- grouping folder - feature-shell/ <---- library - - check-in/ - feature-shell/ - - shared/ <---- grouping folder - data-access/ <---- library - - seatmap/ <---- grouping folder - data-access/ <---- library - feature-seatmap/ <---- library -``` - -## Sharing Libraries - -One of the main advantages of using a monorepo is that there is more visibility into code that can be reused across many different applications. Shared libraries are a great way to save developers time and effort by reusing a solution to a common problem. - -Let’s consider our reference monorepo. The `shared-data-access` library contains the code needed to communicate with the back-end (for example, the URL prefix). We know that this would be the same for all libs; therefore, we should place this in the shared lib and properly document it so that all projects can use it instead of writing their own versions. - -```text - libs/ - booking/ - data-access/ <---- app-specific library - - shared/ - data-access/ <---- shared library - - seatmap/ - data-access/ <---- shared library - feature-seatmap/ <---- shared library -``` diff --git a/nx-dev/models-document/src/lib/related-documents.utils.ts b/nx-dev/models-document/src/lib/related-documents.utils.ts index 68786e3231..a4f87cbbe1 100644 --- a/nx-dev/models-document/src/lib/related-documents.utils.ts +++ b/nx-dev/models-document/src/lib/related-documents.utils.ts @@ -17,7 +17,11 @@ export function categorizeRelatedDocuments( { id: 'concepts', name: 'Concepts', - matchers: ['/concepts/', '/concepts/more-concepts/'], + matchers: [ + '/concepts/', + '/concepts/module-federation/', + '/concepts/decisions/', + ], relatedDocuments: [], }, { diff --git a/nx-dev/nx-dev/redirect-rules.js b/nx-dev/nx-dev/redirect-rules.js index 3113976477..2bc7050ed2 100644 --- a/nx-dev/nx-dev/redirect-rules.js +++ b/nx-dev/nx-dev/redirect-rules.js @@ -1060,6 +1060,24 @@ const removedDeprecatedUrls = { '/recipes/storybook/overview-react', // 80 views }; +const decisionsSection = { + '/concepts/more-concepts/why-monorepos': '/concepts/decisions/why-monorepos', + '/concepts/more-concepts/dependency-management': + '/concepts/decisions/dependency-management', + '/concepts/more-concepts/code-sharing': '/concepts/decisions/code-ownership', + '/concepts/more-concepts/applications-and-libraries': + '/concepts/decisions/project-size', + '/concepts/more-concepts/creating-libraries': + '/concepts/decisions/project-size', + '/concepts/more-concepts/library-types': + '/concepts/decisions/project-dependency-rules', + '/concepts/more-concepts/grouping-libraries': + '/concepts/decisions/folder-structure', + '/concepts/more-concepts/turbo-and-nx': '/concepts/turbo-and-nx', + '/concepts/more-concepts/nx-daemon': '/concepts/nx-daemon', + '/concepts/more-concepts/buildable-and-publishable-libraries': + '/concepts/buildable-and-publishable-libraries', +}; // Blog post redirects const blogPosts = { '/blog/2024-05-07-nx-19-release': '/blog/2024-05-08-nx-19-release', @@ -1095,4 +1113,5 @@ module.exports = { removedDeprecatedUrls, troubleshootingOutOfRecipes, blogPosts, + decisionsSection, };