-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(docs): add code gen page (#4978)
Co-authored-by: Anthony Shew <anthony.shew@vercel.com>
- Loading branch information
1 parent
1ffade9
commit 29284c8
Showing
5 changed files
with
287 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
218 changes: 218 additions & 0 deletions
218
docs/pages/repo/docs/core-concepts/monorepos/code-generation.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,218 @@ | ||
--- | ||
title: Code Generation | ||
description: Extend your Turborepo with new apps, and packages. Create new empty workspaces, copy existing workspaces, add workspaces from remote sources (just like `create-turbo`!) or run custom generators defined using Plop configurations. | ||
--- | ||
|
||
import Callout from "../../../../../components/Callout"; | ||
|
||
# Code Generation | ||
|
||
Splitting your monorepo into individual workspaces is a great way to organize your code, speed up tasks, and improve the local development | ||
experience. With Turborepo's code generation, it's easy to generate new source code for packages, modules, | ||
and even individual UI components in a structured way that integrates with the rest of your repository. | ||
|
||
## Add an Empty Workspace | ||
|
||
Add a new, empty app or package to your monorepo. | ||
|
||
```sh | ||
turbo gen workspace | ||
``` | ||
|
||
View all available [options](/repo/docs/reference/command-line-reference#workspace) for `gen workspace`. | ||
|
||
![Extend your Turborepo by adding a new package or application](/images/docs/turborepo-generators-empty.png) | ||
|
||
## Copy an Existing Workspace | ||
|
||
You can use an existing workspace as a template for your new app or package. This works for both workspaces within your existing monorepo, | ||
and remote workspaces from other repositories (specified via GitHub URL). | ||
|
||
### Examples | ||
|
||
Create a new workspace in your monorepo by copying from an existing workspace in your repo. | ||
|
||
```sh | ||
turbo gen workspace --copy | ||
``` | ||
|
||
Create a new workspace in your monorepo by copying from a remote workspace. | ||
|
||
```sh | ||
turbo gen workspace -e https://github.com/vercel/turbo/tree/main/examples/with-tailwind/packages/tailwind-config | ||
``` | ||
|
||
<Callout> | ||
**Note**: When adding from a remote source, Turborepo is unable to verify that your repo has all of the required dependencies, and is using the correct package manager. In this case, some manual modifications may be required to get the new workspace working as expected within your repository. | ||
|
||
</Callout> | ||
|
||
View all available [options](/repo/docs/reference/command-line-reference#workspace) for `gen workspace --copy`. | ||
|
||
![Extend your Turborepo by copying an existing package or application](/images/docs/turborepo-generators-copy.png) | ||
|
||
## Custom Generators | ||
|
||
If a built-in generator does not fit your needs, you can create your own custom generator using [Plop](https://plopjs.com/) configurations. | ||
Turborepo will automatically detect any generator configurations within your repo, and make them available to run from the command line. | ||
|
||
<Callout type="info"> | ||
**Note**: While Turborepo Generators are built on top of Plop, they _do not_ require `plop` to be installed as a dependency in your repo. | ||
</Callout> | ||
|
||
While Turborepo understands all Plop configuration options and features, it provides a few additional features to improve the experience of writing | ||
generators within a repo configured with Turborepo. | ||
|
||
1. Generators are automatically discovered, loaded, and organized per workspace (no need to manually `load` them within a single configuration file) | ||
2. Generators are automatically run from the root of the workspace where they are defined | ||
3. Generators can be invoked from anywhere within your repo (or outside out it via the [`--root`](/repo/docs/reference/command-line-reference#--root-1) flag) | ||
4. Typescript generators are supported with zero configuration | ||
5. `plop` is not required to be installed as a depenendency of your repo | ||
|
||
<Callout> | ||
**Note:** ESM dependencies are not currently supported within custom generators | ||
</Callout> | ||
|
||
### Getting Started | ||
|
||
To build and run a custom generator, run the following command from anywhere within your monorepo using Turborepo. | ||
|
||
```sh | ||
turbo gen | ||
``` | ||
|
||
You'll be prompted to select an existing generator or to create one if you don't have any yet. You can also create your configuration | ||
manually at `turbo/generators/config.ts` (or `config.js`) at the root of your repo - or within _any_ workspace. | ||
|
||
<Callout type="info"> | ||
**Note**: If you are using Typescript, you will need to install the [`@turbo/gen`](https://github.com/vercel/turbo/tree/main/packages/turbo-gen) package as a `devDependency` to access the required TS types. | ||
</Callout> | ||
|
||
For example, the following illustrates a monorepo with three generator configurations: | ||
|
||
``` | ||
- root | ||
- apps/web | ||
- packages/ui | ||
``` | ||
|
||
```bash | ||
├── package.json | ||
├── turbo.json | ||
├── README.md | ||
├── apps | ||
│ └── web | ||
│ ├── package.json | ||
│ └── turbo | ||
│ └── generators | ||
│ ├── config.ts | ||
│ └── templates | ||
├── packages | ||
│ └── ui | ||
│ ├── package.json | ||
│ └── turbo | ||
│ └── generators | ||
│ ├── config.ts | ||
│ └── templates | ||
├── turbo | ||
│ └── generators | ||
│ ├── config.ts | ||
│ └── templates | ||
├── pnpm-lock.yaml | ||
└── pnpm-workspace.yaml | ||
``` | ||
|
||
Generators created within workspaces are automatically run from the workspace root, **not** the repo root, nor the location of the generator configuration. | ||
|
||
This makes your generators more simple to write. Creating a file at `[workspace-root]` only needs to be specified as `<file>` rather than `../../<file>`. | ||
|
||
Learn more about [creating custom generators using Plop](https://plopjs.com/documentation/#creating-a-generator). | ||
|
||
### Writing Generators | ||
|
||
A generator configuration file is a function that returns a [Plop](https://plopjs.com/) configuration object. The configuration object is | ||
used to define the generator's prompts, and actions. | ||
|
||
In its simplest form, a generator configuration file looks like: | ||
|
||
```ts filename="turbo/generators/config.ts" | ||
import type { PlopTypes } from "@turbo/gen"; | ||
|
||
export default function generator(plop: PlopTypes.NodePlopAPI): void { | ||
// create a generator | ||
plop.setGenerator("Generator name", { | ||
description: "Generator description", | ||
// gather information from the user | ||
prompts: [ | ||
... | ||
], | ||
// perform actions based on the prompts | ||
actions: [ | ||
... | ||
], | ||
}); | ||
} | ||
``` | ||
|
||
#### Prompts | ||
|
||
Promps are written using [Plop prompts](https://plopjs.com/documentation/#using-prompts) and are used to gather information from the user. | ||
|
||
#### Actions | ||
|
||
Actions can use [built-in Plop actions](https://plopjs.com/documentation/#built-in-actions), or [custom action functions](https://plopjs.com/documentation/#functionsignature-custom-action) that you define yourself: | ||
|
||
```ts filename="turbo/generators/config.ts" | ||
import type { PlopTypes } from "@turbo/gen"; | ||
|
||
const customAction: PlopTypes.CustomActionFunction = async (answers) => { | ||
// fetch data from a remote API | ||
const results = await fetchRemoteData(); | ||
// add the response to the answers, making this data available to actions | ||
answers.results = results; | ||
// return a status string | ||
return 'Finished data fetching!'; | ||
} | ||
|
||
export default function generator(plop: PlopTypes.NodePlopAPI): void { | ||
// create a generator | ||
plop.setGenerator("Generator name", { | ||
description: "Generator description", | ||
prompts: [ | ||
... | ||
], | ||
actions: [ | ||
customAction | ||
{/* actions now have access to `answers.results` */} | ||
... | ||
], | ||
}); | ||
} | ||
``` | ||
|
||
### Running Generators | ||
|
||
Once you have created your generator configuration file, you can skip the selection prompt and directly run a specified generator with: | ||
|
||
```sh | ||
turbo gen [generator-name] | ||
``` | ||
|
||
Arguments can also be passed directly to the generator prompts using `--args` | ||
|
||
```sh | ||
turbo gen [generator-name] --args answer1 answer2 ... | ||
``` | ||
|
||
See [bypassing prompts](https://plopjs.com/documentation/#bypassing-prompts) in the Plop documentation for more information. | ||
|
||
View all available [options](/repo/docs/reference/command-line-reference#run-generator-name) for `gen`. | ||
|
||
## Examples | ||
|
||
The [vercel/turbo](https://github.com/vercel/turbo) monorepo contains several custom Turborepo generators that are used for our own development. | ||
|
||
- [Create a new blog post](https://github.com/vercel/turbo/blob/main/docs/turbo/generators/config.ts) - Creates a new release [blog post](/blog) with | ||
live stats fetched from the NPM and Github API's. | ||
- [Create a new code transform](https://github.com/vercel/turbo/blob/main/packages/turbo-codemod/turbo/generators/config.ts) - Creates a new code transform | ||
for [`@turbo/codemod`](https://github.com/vercel/turbo/tree/main/packages/turbo-codemod) complete with all boilerplate and tests. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29284c8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
turbo-site – ./docs
turbo.vercel.app
turbo.build
turbo.vercel.sh
www.turborepo.com
turbopack.org
turbo-site.vercel.sh
www.turbo.build
turborepo.org
www.turborepo.org
www.turbopack.org
turbo-site-git-main.vercel.sh