diff --git a/docs/generated/cli/import.md b/docs/generated/cli/import.md new file mode 100644 index 0000000000000..54cd7d88279c8 --- /dev/null +++ b/docs/generated/cli/import.md @@ -0,0 +1,30 @@ +--- +title: 'import - CLI command' +description: 'Import code and git history from another repository into this repository.' +--- + +# import + +Import code and git history from another repository into this repository. + +## Usage + +```shell +nx import [sourceRepository] [destinationDirectory] +``` + +Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`. + +## Options + +| Option | Type | Description | +| ------------------------ | ------- | --------------------------------------------------------------------------- | +| `--depth` | number | The depth to clone the source repository (limit this for faster git clone). | +| `--destinationDirectory` | string | The directory in the current workspace to import into. | +| `--help` | boolean | Show help. | +| `--interactive` | boolean | Interactive mode. (Default: `true`) | +| `--ref` | string | The branch from the source repository to import. | +| `--sourceDirectory` | string | The directory in the source repository to import from. | +| `--sourceRepository` | string | The remote URL of the source to import. | +| `--verbose` | boolean | Prints additional information about the commands (e.g., stack traces). | +| `--version` | boolean | Show version number. | diff --git a/docs/generated/manifests/menus.json b/docs/generated/manifests/menus.json index 655cd2bb1968f..a4358f9dd1ca4 100644 --- a/docs/generated/manifests/menus.json +++ b/docs/generated/manifests/menus.json @@ -1235,6 +1235,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Import an Existing Project into an Nx Workspace", + "path": "/recipes/adopting-nx/import-project", + "id": "import-project", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Preserving Git Histories", "path": "/recipes/adopting-nx/preserving-git-histories", @@ -2353,6 +2361,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Import an Existing Project into an Nx Workspace", + "path": "/recipes/adopting-nx/import-project", + "id": "import-project", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Preserving Git Histories", "path": "/recipes/adopting-nx/preserving-git-histories", @@ -2396,6 +2412,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "Import an Existing Project into an Nx Workspace", + "path": "/recipes/adopting-nx/import-project", + "id": "import-project", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "Preserving Git Histories", "path": "/recipes/adopting-nx/preserving-git-histories", @@ -8761,6 +8785,14 @@ "children": [], "disableCollapsible": false }, + { + "name": "import", + "path": "/nx-api/nx/documents/import", + "id": "import", + "isExternal": false, + "children": [], + "disableCollapsible": false + }, { "name": "exec", "path": "/nx-api/nx/documents/exec", diff --git a/docs/generated/manifests/nx-api.json b/docs/generated/manifests/nx-api.json index a01f4a7384103..5d1d45836fc5c 100644 --- a/docs/generated/manifests/nx-api.json +++ b/docs/generated/manifests/nx-api.json @@ -1924,6 +1924,17 @@ "tags": [], "originalFilePath": "generated/cli/sync-check" }, + "/nx-api/nx/documents/import": { + "id": "import", + "name": "import", + "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.", + "file": "generated/packages/nx/documents/import", + "itemList": [], + "isExternal": false, + "path": "/nx-api/nx/documents/import", + "tags": [], + "originalFilePath": "generated/cli/import" + }, "/nx-api/nx/documents/exec": { "id": "exec", "name": "exec", diff --git a/docs/generated/manifests/nx.json b/docs/generated/manifests/nx.json index 8182367932960..c986b8b24e52e 100644 --- a/docs/generated/manifests/nx.json +++ b/docs/generated/manifests/nx.json @@ -1687,6 +1687,17 @@ "path": "/recipes/adopting-nx/adding-to-existing-project", "tags": [] }, + { + "id": "import-project", + "name": "Import an Existing Project into an Nx Workspace", + "description": "", + "mediaImage": "", + "file": "shared/migration/import-project", + "itemList": [], + "isExternal": false, + "path": "/recipes/adopting-nx/import-project", + "tags": [] + }, { "id": "preserving-git-histories", "name": "Preserving Git Histories", @@ -3218,6 +3229,17 @@ "path": "/recipes/adopting-nx/adding-to-existing-project", "tags": [] }, + { + "id": "import-project", + "name": "Import an Existing Project into an Nx Workspace", + "description": "", + "mediaImage": "", + "file": "shared/migration/import-project", + "itemList": [], + "isExternal": false, + "path": "/recipes/adopting-nx/import-project", + "tags": [] + }, { "id": "preserving-git-histories", "name": "Preserving Git Histories", @@ -3278,6 +3300,17 @@ "path": "/recipes/adopting-nx/adding-to-existing-project", "tags": [] }, + "/recipes/adopting-nx/import-project": { + "id": "import-project", + "name": "Import an Existing Project into an Nx Workspace", + "description": "", + "mediaImage": "", + "file": "shared/migration/import-project", + "itemList": [], + "isExternal": false, + "path": "/recipes/adopting-nx/import-project", + "tags": [] + }, "/recipes/adopting-nx/preserving-git-histories": { "id": "preserving-git-histories", "name": "Preserving Git Histories", diff --git a/docs/generated/packages-metadata.json b/docs/generated/packages-metadata.json index 55893bfef2479..ce80b4d541742 100644 --- a/docs/generated/packages-metadata.json +++ b/docs/generated/packages-metadata.json @@ -1903,6 +1903,17 @@ "tags": [], "originalFilePath": "generated/cli/sync-check" }, + { + "id": "import", + "name": "import", + "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.", + "file": "generated/packages/nx/documents/import", + "itemList": [], + "isExternal": false, + "path": "nx/documents/import", + "tags": [], + "originalFilePath": "generated/cli/import" + }, { "id": "exec", "name": "exec", diff --git a/docs/generated/packages/nx/documents/import.md b/docs/generated/packages/nx/documents/import.md new file mode 100644 index 0000000000000..54cd7d88279c8 --- /dev/null +++ b/docs/generated/packages/nx/documents/import.md @@ -0,0 +1,30 @@ +--- +title: 'import - CLI command' +description: 'Import code and git history from another repository into this repository.' +--- + +# import + +Import code and git history from another repository into this repository. + +## Usage + +```shell +nx import [sourceRepository] [destinationDirectory] +``` + +Install `nx` globally to invoke the command directly using `nx`, or use `npx nx`, `yarn nx`, or `pnpm nx`. + +## Options + +| Option | Type | Description | +| ------------------------ | ------- | --------------------------------------------------------------------------- | +| `--depth` | number | The depth to clone the source repository (limit this for faster git clone). | +| `--destinationDirectory` | string | The directory in the current workspace to import into. | +| `--help` | boolean | Show help. | +| `--interactive` | boolean | Interactive mode. (Default: `true`) | +| `--ref` | string | The branch from the source repository to import. | +| `--sourceDirectory` | string | The directory in the source repository to import from. | +| `--sourceRepository` | string | The remote URL of the source to import. | +| `--verbose` | boolean | Prints additional information about the commands (e.g., stack traces). | +| `--version` | boolean | Show version number. | diff --git a/docs/map.json b/docs/map.json index 7c98716f21cd1..4fe5012ac0ca6 100644 --- a/docs/map.json +++ b/docs/map.json @@ -465,6 +465,11 @@ "id": "adding-to-existing-project", "file": "shared/migration/adding-to-existing-project" }, + { + "name": "Import an Existing Project into an Nx Workspace", + "id": "import-project", + "file": "shared/migration/import-project" + }, { "name": "Preserving Git Histories", "id": "preserving-git-histories", @@ -2111,6 +2116,11 @@ "id": "sync-check", "file": "generated/cli/sync-check" }, + { + "name": "import", + "id": "import", + "file": "generated/cli/import" + }, { "name": "exec", "id": "exec", diff --git a/docs/shared/migration/import-project.md b/docs/shared/migration/import-project.md new file mode 100644 index 0000000000000..40a6460725ab3 --- /dev/null +++ b/docs/shared/migration/import-project.md @@ -0,0 +1,95 @@ +# Import an Existing Project into an Nx Workspace + +Nx can help with the process of moving an existing project from another repository into an Nx workspace. In order to communicate clearly about this process, we'll call the repository we're moving the project out of the "source repository" and the repository we're moving the project into the "destination repository". Here's an example of what those repositories might look like. + +{% side-by-side %} + +```{% fileName="Source Repository" %} +└─ inventory-app + ├─ ... + ├─ public + │ └─ ... + ├─ src + │ ├─ assets + │ ├─ App.css + │ ├─ App.tsx + │ ├─ index.css + │ └─ main.tsx + ├─ .eslintrc.cjs + ├─ index.html + ├─ package.json + ├─ README.md + ├─ tsconfig.json + ├─ tsconfig.node.json + └─ vite.config.ts +``` + +```{% fileName="Destination Repository" %} +└─ myorg + ├─ ... + ├─ packages + │ └─ ... + ├─ apps + │ ├─ account + │ │ └─ ... + │ ├─ cart + │ │ └─ ... + │ └─ users + │ └─ ... + ├─ .eslintrc.json + ├─ .gitignore + ├─ nx.json + ├─ package.json + ├─ README.md + └─ tsconfig.base.json +``` + +{% /side-by-side %} + +In this example, the source repository contains a single application while the destination repository is already a monorepo. You can also import a project from a sub-directory of the source repository (if the source repository is a monorepo, for instance). The `nx import` command can be run with no arguments and you will be prompted to for the required arguments: + +```shell +nx import +``` + +Make sure to run `nx import` from within the **destination repository**. + +You can also directly specify arguments from the terminal, like one of these commands: + +```shell {% path="~/myorg" %} +nx import [sourceRepository] [destinationDirectory] +nx import ../inventory-app apps/inventory +nx import https://github.com/myorg/inventory-app.git apps/inventory +``` + +{% callout type="note" title="Source Repository Local or Remote" %} +The sourceRepository argument for `nx import` can be either a local file path to the source git repository on your local machine or a git URL to the hosted git repository. +{% /callout %} + +The `nx import` command will: + +- Maintain the git history from the source repository +- Suggest adding plugins to the destination repository based on the newly added project code + +Every code base is different, so you will still need to manually: + +- Manage any dependency conflicts between the two code bases +- Migrate over code outside the source project's root folder that the source project depends on + +## Manage Dependencies + +If both repositories are managed with npm workspaces, the imported project will have all its required dependencies defined in its `package.json` file that is moved over. You'll need to make sure that the destination repository includes the `destinationDirectory` in the `workspaces` defined in the root `package.json`. + +If the destination repository does not use npm workspaces, it will ease the import process to temporarily enable it. With npm workspaces enabled, you can easily import a self-contained project and gain the benefits of code sharing, atomic commits and shared infrastructure. Once the import process is complete, you can make a follow-up PR that merges the dependencies into the root `package.json` and disables npm workspaces again. + +## Migrate External Code and Configuration + +Few projects are completely isolated from the rest of the repository where they are located. After `nx import` has run, here are a few types of external code references that you should account for: + +- Project configuration files that extend root configuration files +- Scripts outside the project folder that are required by the project +- Local project dependencies that are not present or have a different name in the destination repository + +{% callout type="note" title="Importing Multiple Projects" %} +If multiple projects need to be imported into the destination repository, try to import as many of the projects together as possible. If projects need to be imported with separate `nx import` commands, start with the leaf projects in the dependency graph (the projects without any dependencies) and then work your way up to the top level applications. This way every project that is imported into the destination repository will have its required dependencies available. +{% /callout %} diff --git a/docs/shared/reference/commands.md b/docs/shared/reference/commands.md index 1882385e6dddb..f408903b522a8 100644 --- a/docs/shared/reference/commands.md +++ b/docs/shared/reference/commands.md @@ -82,6 +82,20 @@ nx migrate --run-migrations {% link-card title="Automate Updating Dependencies" type="Feature" url="/features/automate-updating-dependencies" /%} {% /cards %} +### import + +Import code and git history from another repository into this repository. + +```shell +nx import https://github.com/myorg/inventory-app.git apps/inventory +nx import ../inventory-app apps/inventory +``` + +{% cards %} +{% link-card title="nx import" type="API Reference" url="/nx-api/nx/documents/import" /%} +{% link-card title="Import an Existing Project into an Nx Workspace" type="Recipe" url="/recipes/adopting-nx/import-project" /%} +{% /cards %} + ### repair Repair any configuration that is no longer supported by Nx. diff --git a/docs/shared/reference/sitemap.md b/docs/shared/reference/sitemap.md index cb2a1edca130a..746a4a1779b4b 100644 --- a/docs/shared/reference/sitemap.md +++ b/docs/shared/reference/sitemap.md @@ -70,6 +70,7 @@ - [NPM/Yarn/PNPM workspaces](/recipes/adopting-nx/adding-to-monorepo) - [Migrate From Turborepo](/recipes/adopting-nx/from-turborepo) - [Add to any Project](/recipes/adopting-nx/adding-to-existing-project) + - [Import an Existing Project into an Nx Workspace](/recipes/adopting-nx/import-project) - [Preserving Git Histories](/recipes/adopting-nx/preserving-git-histories) - [Manual migration](/recipes/adopting-nx/manual) - [React](/recipes/react) @@ -559,6 +560,7 @@ - [repair](/nx-api/nx/documents/repair) - [sync](/nx-api/nx/documents/sync) - [sync:check](/nx-api/nx/documents/sync-check) + - [import](/nx-api/nx/documents/import) - [exec](/nx-api/nx/documents/exec) - [watch](/nx-api/nx/documents/watch) - [show](/nx-api/nx/documents/show) diff --git a/nx-dev/ui-fence/src/lib/fence.tsx b/nx-dev/ui-fence/src/lib/fence.tsx index 43cdc7e07928d..71e66c0f7c0d9 100644 --- a/nx-dev/ui-fence/src/lib/fence.tsx +++ b/nx-dev/ui-fence/src/lib/fence.tsx @@ -39,7 +39,7 @@ function CodeWrapper(options: { options.language === 'shell' ? ( diff --git a/packages/nx/src/command-line/import/command-object.ts b/packages/nx/src/command-line/import/command-object.ts index 6a7310c377e5f..10e3395fab347 100644 --- a/packages/nx/src/command-line/import/command-object.ts +++ b/packages/nx/src/command-line/import/command-object.ts @@ -5,7 +5,8 @@ import { handleErrors } from '../../utils/params'; export const yargsImportCommand: CommandModule = { command: 'import [sourceRepository] [destinationDirectory]', - describe: false, + describe: + 'Import code and git history from another repository into this repository.', builder: (yargs) => linkToNxDevAndExamples( withVerbose(