Skip to content

Commit

Permalink
docs(core): core nx tutorial (#9220)
Browse files Browse the repository at this point in the history
* docs(core): core nx tutorial

* docs(core): cleanup core tutorial

Co-authored-by: Isaac Mann <isaacplmann+git@gmail.com>
  • Loading branch information
isaacplmann and Isaac Mann committed Mar 11, 2022
1 parent fabee46 commit 5470b30
Show file tree
Hide file tree
Showing 9 changed files with 808 additions and 1 deletion.
36 changes: 36 additions & 0 deletions docs/map.json
Expand Up @@ -142,6 +142,42 @@
}
]
},
{
"name": "Core Tutorial",
"id": "core-tutorial",
"itemList": [
{
"name": "1 - Create Blog",
"id": "01-create-blog",
"file": "shared/core-tutorial/01-create-blog"
},
{
"name": "2 - Create CLI",
"id": "02-create-cli",
"file": "shared/core-tutorial/02-create-cli"
},
{
"name": "3 - Share Assets",
"id": "03-share-assets",
"file": "shared/core-tutorial/03-share-assets"
},
{
"name": "4 - Build Affected Projects",
"id": "04-build-affected-projects",
"file": "shared/core-tutorial/04-build-affected-projects"
},
{
"name": "5 - Automatically Detect Dependencies",
"id": "05-auto-detect-dependencies",
"file": "shared/core-tutorial/05-auto-detect-dependencies"
},
{
"name": "6 - Summary",
"id": "06-summary",
"file": "shared/core-tutorial/06-summary"
}
]
},
{
"name": "React Tutorial",
"id": "react-tutorial",
Expand Down
175 changes: 175 additions & 0 deletions docs/shared/core-tutorial/01-create-blog.md
@@ -0,0 +1,175 @@
# Core Nx Tutorial - Step 1: Create Eleventy Blog

In this tutorial you create multiple projects in a monorepo and take advantage of the core Nx features with a minimum of configuration.

## Create a New Workspace

**Start by creating a new workspace.**

```bash
npx create-nx-workspace@latest
```

You then receive the following prompts in your command line:

```bash
Workspace name (e.g., org name) myorg
What to create in the new workspace core
```

> You can also choose to add [Nx Cloud](https://nx.app), but its not required for the tutorial.
```treeview
myorg/
├── packages/
├── tools/
├── nx.json
├── package.json
├── README.md
└── tsconfig.base.json
```

## Yarn workspaces

The `package.json` file contains this property:

```json
"workspaces": [
"packages/**"
]
```

Which tells yarn (or npm) and Nx to look in the `packages` folder for projects that will each be identified by a `package.json` file.

## Adding Eleventy

**Install Eleventy**

To install Eleventy run:

```bash
yarn add -D -W @11ty/eleventy@1.0.0
```

or

```bash
npm add -D @11ty/eleventy@1.0.0
```

Note: We are intentionally installing the package at the root of the workspace because this forces the organization to have the upfront cost of agreeing on the same versions of dependencies rather than the delayed cost of having projects using multiple different incompatible versions of dependencies. Yarn needs the `-W` flag so that you can install dependencies at the root. This is not a requirement of Nx, just a suggestion to help you maintain a growing repo.

**Eleventy Hello World**

Create a file at `packages/blog/package.json` with these contents:

```json
{
"name": "blog",
"description": "eleventy blog",
"version": "1.0.0",
"scripts": {
"build": "eleventy --input=./src --output=../../dist/packages/blog",
"serve": "eleventy --serve --input=./src --output=../../dist/packages/blog"
}
}
```

These scripts tell Eleventy to read from the `src` folder we'll create next and output to Nx's default location under `dist`.

Next, add `packages/blog/src/index.html`:

```html
<p>Hello, Eleventy</p>
```

## Running Eleventy with Nx

Now that we have the bare minimum set up for Eleventy, you can run:

```bash
nx serve blog
```

And you can see `Hello, Eleventy` at `http://localhost:8080`.

Also, if you run:

```bash
nx build blog
```

The build output will be created under `dist/packages/blog`. So far, Nx isn't doing anything special. If you run `nx build blog` again, though, you'll see it finish in less than 100 ms (instead of 1s). The caching doesn't matter yet, but as build times grow, it will become far more useful.

The main value of Nx at this stage of the project is that it doesn't require any custom configuration on your project. The blog could have been built with any of a dozen different platforms and Nx would cache the output just the same.

## Build a Basic Blog

To actually create a blog, we'll have to change a few more files. This is all Eleventy specific configuration, so if you have questions consult [their documentation](https://www.11ty.dev/docs/config/) or [this tutorial](https://www.filamentgroup.com/lab/build-a-blog/).

Update `index.html`:

```html
---
layout: layout.liquid
pageTitle: Welcome to my blog
---

{% for post in collections.posts %}
<h2><a href="{{ post.url }}">{{ post.data.pageTitle }}</a></h2>
<em>{{ post.date | date: "%Y-%m-%d" }}</em>
{% endfor %}
```

Create the following files:

`packages/blog/src/_includes/layout.liquid`:

```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>My Blog</title>
</head>
<body>
<h1>{{ pageTitle }}</h1>

{{ content }}
</body>
</html>
```

`packages/blog/src/posts/ascii.md`:

```markdown
---
pageTitle: Some ASCII Art
---

Welcome to [The Restaurant at the End of the Universe](https://hitchhikers.fandom.com/wiki/Ameglian_Major_Cow)

<pre>
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
</pre>

Art courtesy of [cowsay](https://www.npmjs.com/package/cowsay).
```

`packages/blog/src/posts/posts.json`:

```json
{
"layout": "layout.liquid",
"tags": ["posts"]
}
```

Once these files are in place, run `nx serve blog` again. Navigate to `http://localhost:8080/posts/ascii/` in a browser and you should see the blog post.
155 changes: 155 additions & 0 deletions docs/shared/core-tutorial/02-create-cli.md
@@ -0,0 +1,155 @@
# Core Nx Tutorial - Step 2: Create Go CLI

Great! you now have a simple blog set up.

Next, you're going to create a CLI written in Go.

## Install Go Locally

Make sure you have Go installed locally by following [these instructions](https://go.dev/doc/install).

You can verify that Go is installed correctly by running:

```bash
go version
```

## Create the CLI Project

Create a `project.json` file for your Go CLI.

`packages/cli/project.json`:

```json
{
"root": "packages/cli",
"sourceRoot": "packages/cli/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "go build -o='../../dist/packages/cli/' ./src/ascii.go",
"cwd": "packages/cli"
}
},
"serve": {
"executor": "@nrwl/workspace:run-commands",
"options": {
"command": "go run ./src/ascii.go",
"cwd": "packages/cli"
}
}
}
}
```

You could have the exact same functionality with a `package.json` file with a `scripts` section like this:

```json
{
"scripts": {
"build": "go build -o='../../dist/packages/cli/' ./src/ascii.go",
"serve": "go run ./src/ascii.˙go"
}
}
```

There are a few reasons to choose `project.json` for the CLI project.

1. The presence of `package.json` might cause other developers to think there is javascript code in this project.
2. As the scripts in the project get more complex, `project.json` tends to have a flatter structure - rather than a long horizontal line in `package.json` with all the cli flags.
3. The easiest method to run scripts provided in Nx plugins is to use a `project.json` file.

All of these reasons are matters of preference. After this tutorial, you should have enough of a taste of both styles to make an informed decision about which format you prefer. Read more about [package.json configuration](/configuration/packagejson) and [project.json configuration](configuration/projectjson) in their respective guides.

### Project.json syntax

- `root`, `sourceRoot` and `application` are properties that help Nx know more about your project.
- `targets` is similar to the `scripts` property in `package.json`.
- Just as in `package.json`, `build` and `serve` can be any string you pick.
- The `executor` is the code that runs the target. In this case, [`@nrwl/workspace:run-commands`](https://nx.dev/workspace/run-commands-executor) launches a terminal process to execute whatever command you pass in.
- `options` contains whatever configuration properties the executor needs to run.

## Create the CLI

This CLI will display some ASCII art in the terminal. Create the following files:

`packages/cli/src/ascii.go`:

```go
package main

import (
"fmt"
"os"
)

func check(e error) {
if e != nil {
panic(e)
}
}

func main() {
fmt.Println("Hello, World!")
dat, err := os.ReadFile("src/cow.txt")
check(err)
fmt.Print(string(dat))
}
```

`packages/cli/src/cow.txt`:

```bash
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||
```

## Run the CLI

Now if you run `nx serve cli`, you'll see a friendly message:

```bash
❯ nx serve cli

> nx run cli:serve


> cli@ serve /Users/isaac/Documents/code/myorg/packages/cli
> go run ./src/ascii.go

Hello, World!
_____
< moo >
-----
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||

—————————————————————————————————————————————————————————————————————————————————————————

> NX Successfully ran target serve for project cli (2s)

See Nx Cloud run details at https://nx.app/runs/THRW7SDRL9S

```

Nx only caches the targets that you tell it to cache. `serve` is not in the default list of cached targets, so running this command a second time will take the same amount of time. You can see the current list of `cacheableOperations` in `nx.json`.

```json
{
//...
"cacheableOperations": ["build", "lint", "test", "e2e"]
}
```

If you run `nx build cli` twice, you'll see that Nx is able to cache the commands even though they're entirely written in Go.

1 comment on commit 5470b30

@vercel
Copy link

@vercel vercel bot commented on 5470b30 Mar 11, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.