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}
22
You 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}
7
There are a few reasons to choose project.json
for the CLI project.
- The presence of
package.json
might cause other developers to think there is javascript code in this project. - As the scripts in the project get more complex,
project.json
tends to have a flatter structure - rather than a long horizontal line inpackage.json
with all the cli flags. - 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 project configuration.
Project.json syntax
root
,sourceRoot
andapplication
are properties that help Nx know more about your project.targets
is similar to thescripts
property inpackage.json
.- Just as in
package.json
,build
andserve
can be any string you pick. - The
executor
is the code that runs the target. In this case,run-commands
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
:
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}
20
packages/cli/src/cow.txt
:
1 _____
2< moo >
3 -----
4 \ ^__^
5 \ (oo)\_______
6 (__)\ )\/\
7 ||----w |
8 || ||
9
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}
5
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.
What's Next
- Continue to Step 3: Share assets