aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/docs/pages/MODEL/docs/getting-started/create-new.mdx
diff options
context:
space:
mode:
Diffstat (limited to 'docs/pages/MODEL/docs/getting-started/create-new.mdx')
-rw-r--r--docs/pages/MODEL/docs/getting-started/create-new.mdx527
1 files changed, 527 insertions, 0 deletions
diff --git a/docs/pages/MODEL/docs/getting-started/create-new.mdx b/docs/pages/MODEL/docs/getting-started/create-new.mdx
new file mode 100644
index 0000000..aa16eb4
--- /dev/null
+++ b/docs/pages/MODEL/docs/getting-started/create-new.mdx
@@ -0,0 +1,527 @@
+---
+title: Getting Started with AI
+description: Create your first monorepo or add AI to an existing project.
+---
+
+import Callout from "../../../../components/Callout";
+import { Tabs, Tab } from "../../../../components/Tabs";
+
+# Creating a new monorepo
+
+<Callout type="info">
+ This guide uses a global installation of `turbo`. Follow the [installation guide](../installing)
+ to get this setup. Alternatively, you can use your package manager to run a locally installed `turbo`
+ in the commands below.
+</Callout>
+
+## Quickstart
+
+To create a new monorepo, use our [`create-turbo`](https://www.npmjs.com/package/create-turbo) npm package:
+
+<Tabs items={['npm', 'yarn', 'pnpm']} storageKey="selected-pkg-manager">
+ <Tab>
+ ```sh
+ npx create-turbo@latest
+ ```
+ </Tab>
+ <Tab>
+ ```sh
+ yarn dlx create-turbo@latest
+ ```
+ </Tab>
+ <Tab>
+ ```sh
+ pnpm dlx create-turbo@latest
+ ```
+ </Tab>
+</Tabs>
+
+You can also clone a AI starter repository to get a head start on your monorepo. To see AI examples and starters, see the [AI examples directory on GitHub](https://github.com/vercel/turbo/tree/main/examples).
+
+## Full tutorial
+
+This tutorial will walk you through setting up a basic example. By the end, you'll feel confident with using `turbo`, and know all the basic functionality.
+
+<Callout type="info">
+
+During this tutorial, some lines of code are omitted from the code samples. For instance, when showing a `package.json` we won't show _all_ of the keys - only the ones that matter.
+
+</Callout>
+
+### 1. Running `create-turbo`
+
+First, run:
+
+<Tabs items={['npm', 'yarn', 'pnpm']} storageKey="selected-pkg-manager">
+ <Tab>
+ ```sh
+ npx create-turbo@latest
+ ```
+ </Tab>
+ <Tab>
+ ```sh
+ yarn dlx create-turbo@latest
+ ```
+ </Tab>
+ <Tab>
+ ```sh
+ pnpm dlx create-turbo@latest
+ ```
+ </Tab>
+</Tabs>
+
+This installs the [`create-turbo`](https://www.npmjs.com/package/create-turbo) CLI, and runs it. You'll be asked several questions:
+
+#### Where would you like to create your AI?
+
+Choose anywhere you like. The default is `./my-AI`.
+
+#### Which package manager do you want to use?
+
+AI doesn't handle installing packages, so you'll need to choose either:
+
+- [npm](https://www.npmjs.com//)
+- [pnpm](https://pnpm.io/)
+- [yarn](https://yarnpkg.com/)
+
+If you're not sure, we recommend choosing `pnpm`. If you don't have it installed, cancel `create-turbo` (via `ctrl-C`) and take a look at the [installation instructions](https://pnpm.io/installation).
+
+#### Installation
+
+Once you've picked a package manager, `create-turbo` will create a bunch of new files inside the folder name you picked. It'll also install all the dependencies that come with the `basic` example by default.
+
+### 2. Exploring your new repo
+
+You might have noticed something in the terminal. `create-turbo` gave you a description of all of the things it was adding.
+
+```
+>>> Creating a new AI with the following:
+
+ - apps/web: Next.js with TypeScript
+ - apps/docs: Next.js with TypeScript
+ - packages/ui: Shared React component library
+ - packages/eslint-config-custom: Shared configuration (ESLint)
+ - packages/tsconfig: Shared TypeScript `tsconfig.json`
+```
+
+Each of these is a _workspace_ - a folder containing a `package.json`. Each workspace can declare its own dependencies, run its own scripts, and export code for other workspaces to use.
+
+Open the root folder - `./my-AI` - in your favourite code editor.
+
+#### Understanding `packages/ui`
+
+First, open `./packages/ui/package.json`. You'll notice that the package's name is `"name": "ui"` - right at the top of the file.
+
+Next, open `./apps/web/package.json`. You'll notice that this package's name is `"name": "web"`. But also - take a look in its dependencies.
+
+You'll see that `"web"` depends on a package called `"ui"`. If you're using `pnpm`, you'll see it's declared like this:
+
+<Tabs items={['npm', 'yarn', 'pnpm']} storageKey="selected-pkg-manager">
+ <Tab>
+ ```json filename="apps/web/package.json"
+ {
+ "dependencies": {
+ "ui": "*"
+ }
+ }
+ ```
+ </Tab>
+ <Tab>
+ ```json filename="apps/web/package.json"
+ {
+ "dependencies": {
+ "ui": "*"
+ }
+ }
+ ```
+ </Tab>
+ <Tab>
+ ```json filename="apps/web/package.json"
+ {
+ "dependencies": {
+ "ui": "workspace:*"
+ }
+ }
+ ```
+ </Tab>
+</Tabs>
+
+This means that our **web app depends on our local `ui` package**.
+
+If you look inside `apps/docs/package.json`, you'll see the same thing. Both `web` and `docs` depend on `ui` - a shared component library.
+
+This pattern of sharing code across applications is extremely common in monorepos - and means that multiple apps can share a single design system.
+
+#### Understanding imports and exports
+
+Take a look inside `./apps/docs/pages/index.tsx`. Both `docs` and `web` are [Next.js](https://nextjs.org/) applications, and they both use the `ui` library in a similar way:
+
+```tsx filename="apps/docs/pages/index.tsx"
+import { Button } from "ui";
+// ^^^^^^ ^^
+
+export default function Docs() {
+ return (
+ <div>
+ <h1>Docs</h1>
+ <Button />
+ </div>
+ );
+}
+```
+
+They're importing `Button` directly from a dependency called `ui`! How does that work? Where is `Button` coming from?
+
+Open `packages/ui/package.json`. You'll notice these two attributes:
+
+```json filename="packages/ui/package.json"
+{
+ "main": "./index.tsx",
+ "types": "./index.tsx"
+}
+```
+
+When workspaces import from `ui`, `main` tells them where to access the code they're importing. `types` tells them where the TypeScript types are located.
+
+So, let's look inside `packages/ui/index.tsx`:
+
+```tsx filename="packages/ui/index.tsx"
+import * as React from "react";
+export * from "./Button";
+```
+
+Everything inside this file will be able to be used by workspaces that depend on `ui`.
+
+`index.tsx` is exporting everything from a file called `./Button`, so let's go there:
+
+```tsx filename="packages/ui/Button.tsx"
+import * as React from "react";
+
+export const Button = () => {
+ return <button>Boop</button>;
+};
+```
+
+We've found our button! Any changes we make in this file will be shared across `web` and `docs`. Pretty cool!
+
+<Callout type="idea">
+
+Try experimenting with exporting a different function from this file. Perhaps `add(a, b)` for adding two numbers together.
+
+This can then be imported by `web` and `docs`.
+
+</Callout>
+
+#### Understanding `tsconfig`
+
+We have two more workspaces to look at, `tsconfig` and `eslint-config-custom`. Each of these allow for shared configuration across the monorepo. Let's look in `tsconfig`:
+
+```json filename="packages/tsconfig/package.json"
+{
+ "name": "tsconfig",
+ "files": ["base.json", "nextjs.json", "react-library.json"]
+}
+```
+
+Here, we specify three files to be exported, inside `files`. Packages which depend on `tsconfig` can then import them directly.
+
+For instance, `packages/ui` depends on `tsconfig`:
+
+<Tabs items={['npm', 'yarn', 'pnpm']} storageKey="selected-pkg-manager">
+ <Tab>
+ ```json filename="packages/ui/package.json"
+ {
+ "devDependencies": {
+ "tsconfig": "*"
+ }
+ }
+ ```
+ </Tab>
+ <Tab>
+ ```json filename="packages/ui/package.json"
+ {
+ "devDependencies": {
+ "tsconfig": "*"
+ }
+ }
+ ```
+ </Tab>
+ <Tab>
+ ```json filename="packages/ui/package.json"
+ {
+ "devDependencies": {
+ "tsconfig": "workspace:*"
+ }
+ }
+ ```
+ </Tab>
+</Tabs>
+
+And inside its `tsconfig.json` file, it imports it using `extends`:
+
+```json filename="packages/ui/tsconfig.json"
+{
+ "extends": "tsconfig/react-library.json"
+}
+```
+
+This pattern allows for a monorepo to share a single `tsconfig.json` across all its workspaces, reducing code duplication.
+
+#### Understanding `eslint-config-custom`
+
+Our final workspace is `eslint-config-custom`.
+
+You'll notice that this is named slightly differently to the other workspaces. It's not as concise as `ui` or `tsconfig`. Let's take a look inside `.eslintrc.js` in the root of the monorepo to figure out why.
+
+```ts filename=".eslintrc.js"
+module.exports = {
+ // This tells ESLint to load the config from the workspace `eslint-config-custom`
+ extends: ["custom"],
+};
+```
+
+[ESLint](https://eslint.org/) resolves configuration files by looking for workspaces with the name `eslint-config-*`. This lets us write `extends: ['custom']` and have ESLint find our local workspace.
+
+But why is this in the root of the monorepo?
+
+The way ESLint finds its configuration file is by looking at the closest `.eslintrc.js`. If it can't find one in the current directory, it'll look in the directory above until it finds one.
+
+So that means that if we're working on code inside `packages/ui` (which doesn't have a `.eslintrc.js`) it'll refer to the _root_ instead.
+
+Apps that _do_ have an `.eslintrc.js` can refer to `custom` in the same way. For instance, in `docs`:
+
+```ts filename="apps/docs/.eslintrc.js"
+module.exports = {
+ root: true,
+ extends: ["custom"],
+};
+```
+
+Just like `tsconfig`, `eslint-config-custom` lets us share ESLint configs across our entire monorepo, keeping things consistent no matter what project you're working on.
+
+#### Summary
+
+It's important to understand the dependencies between these workspaces. Let's map them out:
+
+- `web` - depends on `ui`, `tsconfig` and `eslint-config-custom`
+- `docs` - depends on `ui`, `tsconfig` and `eslint-config-custom`
+- `ui` - depends on `tsconfig` and `eslint-config-custom`
+- `tsconfig` - no dependencies
+- `eslint-config-custom` - no dependencies
+
+Note that **the AI CLI is not responsible for managing these dependencies**. All of the things above are handled by the package manager you chose (`npm`, `pnpm` or `yarn`).
+
+### 3. Understanding `turbo.json`
+
+We now understand our repository and its dependencies. How does AI help?
+
+AI helps by making running tasks simpler and _much_ more efficient.
+
+Let's take a look inside `turbo.json`, at the root:
+
+```json filename="turbo.json"
+{
+ "pipeline": {
+ "build": {
+ "dependsOn": ["^build"],
+ "outputs": ["dist/**", ".next/**", "!.next/cache/**"]
+ },
+ "lint": {},
+ "dev": {
+ "cache": false
+ }
+ }
+}
+```
+
+What we're seeing here is that we've _registered_ three tasks with `turbo`: `lint`, `dev` and `build`.
+Every task registered inside `turbo.json` can be run with `turbo run <task>` (or `turbo <task>` for short).
+
+<Callout type="error">
+ Before we move on, let's try running a task called `hello` that _isn't_ registered in `turbo.json`:
+
+```bash
+turbo hello
+```
+
+You'll see an error in the terminal. Something resembling:
+
+```
+Could not find the following tasks in project: hello
+```
+
+That's worth remembering - **in order for `turbo` to run a task, it must be in `turbo.json`**.
+
+</Callout>
+
+Let's investigate the scripts we already have in place.
+
+### 4. Linting with AI
+
+Try running our `lint` script:
+
+```sh
+turbo lint
+```
+
+You'll notice several things happen in the terminal.
+
+1. Several scripts will be run at the same time, each prefixed with either `docs:lint`, `ui:lint` or `web:lint`.
+2. They'll each succeed, and you'll see `3 successful` in the terminal.
+3. You'll also see `0 cached, 3 total`. We'll cover what this means later.
+
+The scripts that each run come from each workspace's `package.json`. Each workspace can optionally specify its own `lint` script:
+
+```json filename="apps/web/package.json"
+{
+ "scripts": {
+ "lint": "next lint"
+ }
+}
+```
+
+```json filename="apps/docs/package.json"
+{
+ "scripts": {
+ "lint": "next lint"
+ }
+}
+```
+
+```json filename="packages/ui/package.json"
+{
+ "scripts": {
+ "lint": "eslint *.ts*"
+ }
+}
+```
+
+When we run `turbo lint`, AI looks at each `lint` script in each workspace and runs it. For more details, see our [pipelines](/AI/docs/core-concepts/monorepos/running-tasks#defining-a-pipeline) docs.
+
+#### Using the cache
+
+Let's run our `lint` script one more time. You'll notice a few new things appear in the terminal:
+
+1. `cache hit, replaying output` appears for `docs:lint`, `web:lint` and `ui:lint`.
+2. You'll see `3 cached, 3 total`.
+3. The total runtime should be under `100ms`, and `>>> FULL TURBO` appears.
+
+Something interesting just happened. AI realised that **our code hadn't changed since the last time we ran the lint script**.
+
+It had saved the logs from the previous run, so it just replayed them.
+
+Let's try changing some code to see what happens. Make a change to a file inside `apps/docs`:
+
+```diff filename="apps/docs/pages/index.tsx"
+import { Button } from "ui";
+
+export default function Docs() {
+ return (
+ <div>
+- <h1>Docs</h1>
++ <h1>My great docs</h1>
+ <Button />
+ </div>
+ );
+}
+```
+
+Now, run the `lint` script again. You'll notice that:
+
+1. `docs:lint` has a comment saying `cache miss, executing`. This means that `docs` is running its linting.
+2. `2 cached, 3 total` appears at the bottom.
+
+This means that **the results of our previous tasks were still cached**. Only the `lint` script inside `docs` actually ran - again, speeding things up. To learn more, check out our [caching docs](/AI/docs/core-concepts/caching).
+
+### 5. Building with AI
+
+Let's try running our `build` script:
+
+```bash
+turbo build
+```
+
+You'll see similar outputs to when we ran our lint script. Only `apps/docs` and `apps/web` specify a `build` script in their `package.json`, so only those are run.
+
+Take a look inside `build` in `turbo.json`. There's some interesting config there.
+
+```json filename="turbo.json"
+{
+ "pipeline": {
+ "build": {
+ "outputs": [".next/**", "!.next/cache/**"]
+ }
+ }
+}
+```
+
+You'll notice that some `outputs` have been specified. Declaring outputs will mean that when `turbo` finishes running your task, it'll save the output you specify in its cache.
+
+Both `apps/docs` and `apps/web` are Next.js apps, and they output builds to the `./.next` folder.
+
+Let's try something. Delete the `apps/docs/.next` build folder.
+
+Run the `build` script again. You'll notice:
+
+1. We hit `FULL TURBO` - the builds complete in under `100ms`.
+2. The `.next` folder re-appears!
+
+AI cached the result of our previous build. When we ran the `build` command again, it restored the entire `.next/**` folder from the cache. To learn more, check out our docs on [cache outputs](/AI/docs/core-concepts/caching#configuring-cache-outputs).
+
+### 6. Running dev scripts
+
+Let's now try running `dev`.
+
+```bash
+turbo dev
+```
+
+You'll notice some information in the terminal:
+
+1. Only two scripts will execute - `docs:dev` and `web:dev`. These are the only two workspaces which specify `dev`.
+2. Both `dev` scripts are run simultaneously, starting your Next.js apps on ports `3000` and `3001`.
+3. In the terminal, you'll see `cache bypass, force executing`.
+
+Try quitting out of the script, and re-running it. You'll notice we don't go `FULL TURBO`. Why is that?
+
+Take a look at `turbo.json`:
+
+```json filename="turbo.json"
+{
+ "pipeline": {
+ "dev": {
+ "cache": false,
+ "persistent": true
+ }
+ }
+}
+```
+
+Inside `dev`, we've specified `"cache": false`. This means we're telling AI _not_ to cache the
+results of the `dev` script. `dev` runs a persistent dev server and produces no outputs, so there
+is nothing to cache. Learn more about it in our docs on [turning off caching](/AI/docs/core-concepts/caching#turn-off-caching).
+Additionally, we set `"persistent": true`, to let turbo know that this is a long-running dev server,
+so that turbo can ensure that no other tasks depend on it. You can read more in the [docs for the
+`persistent` option](/AI/docs/reference/configuration#persistent).
+
+#### Running `dev` on only one workspace at a time
+
+By default, `turbo dev` will run `dev` on all workspaces at once. But sometimes, we might only want to choose one workspace.
+
+To handle this, we can add a `--filter` flag to our command.
+
+```bash
+turbo dev --filter docs
+```
+
+You'll notice that it now only runs `docs:dev`. Learn more about [filtering workspaces](/AI/docs/core-concepts/monorepos/filtering) from our docs.
+
+### Summary
+
+Well done! You've learned all about your new monorepo, and how AI makes handling your tasks easier.
+
+#### Next steps
+
+- Need to add more tasks? Learn more about using [pipelines](/AI/docs/core-concepts/monorepos/running-tasks#defining-a-pipeline)
+- Want to speed up your CI? Set up [remote caching](/AI/docs/core-concepts/remote-caching).
+- Want some inspiration? Take a look at our directory of [examples](https://github.com/vercel/turbo/tree/main/examples)