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.
You can verify that Go is installed correctly by running:
go version
Create the CLI Project
Create a project.json file for your Go CLI.
packages/cli/project.json:
1{
2  "root": "packages/cli",
3  "sourceRoot": "packages/cli/src",
4  "projectType": "application",
5  "targets": {
6    "build": {
7      "executor": "nx:run-commands",
8      "options": {
9        "command": "go build -o='../../dist/packages/cli/' ./src/ascii.go",
10        "cwd": "packages/cli"
11      }
12    },
13    "serve": {
14      "executor": "nx:run-commands",
15      "options": {
16        "command": "go run ./src/ascii.go",
17        "cwd": "packages/cli"
18      }
19    }
20  }
21}
22You could have the exact same functionality with a package.json file with a scripts section like this:
1{
2  "scripts": {
3    "build": "go build -o='../../dist/packages/cli/' ./src/ascii.go",
4    "serve": "go run ./src/ascii.˙go"
5  }
6}
7There are a few reasons to choose project.json for the CLI project.
- The presence of package.jsonmight cause other developers to think there is javascript code in this project.
- As the scripts in the project get more complex, project.jsontends to have a flatter structure - rather than a long horizontal line inpackage.jsonwith all the cli flags.
- The easiest method to run scripts provided in Nx plugins is to use a project.jsonfile.
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 project configuration.
Project.json syntax
- root,- sourceRootand- applicationare properties that help Nx know more about your project.
- targetsis similar to the- scriptsproperty in- package.json.
- Just as in package.json,buildandservecan be any string you pick.
- The executoris the code that runs the target. In this case,run-commandslaunches a terminal process to execute whatever command you pass in.
- optionscontains 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:
1package main
2
3import (
4  "fmt"
5  "os"
6)
7
8func check(e error) {
9  if e != nil {
10      panic(e)
11  }
12}
13
14func main() {
15    fmt.Println("Hello, World!")
16    dat, err := os.ReadFile("src/cow.txt")
17    check(err)
18    fmt.Print(string(dat))
19}
20packages/cli/src/cow.txt:
 _____
< moo >
 -----
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||
Run the CLI
Now if you run nx serve cli, you'll see a friendly message:
❯ 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.
1{
2  //...
3  "cacheableOperations": ["build", "lint", "test", "e2e"]
4}
5If 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.
What's Next
- Continue to Step 3: Share assets