Core Nx Tutorial - Step 3: Share Assets

You probably noticed that you're using the same friendly cow ASCII art in the blog and CLI. Since both projects are in the same repo, it would be good to share that asset across both projects.

Create an Asset Library

You can make a library project just for holding the ASCII asset files. Let Nx know about the project by creating a project.json file like this:

packages/ascii/project.json:

1{
2  "root": "packages/ascii",
3  "sourceRoot": "packages/ascii/assets",
4  "projectType": "library"
5}

Note: You could choose to make a package.json file here instead, if you prefer.

Then move cow.txt out of the cli project to:

packages/ascii/assets/cow.txt:

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

Use the Shared Assets Library in the Blog

In the eleventy blog, you need to add some configuration so that Eleventy knows how to read .txt files.

packages/blog/.eleventy.js:

1const { EleventyRenderPlugin } = require('@11ty/eleventy');
2
3module.exports = function (eleventyConfig) {
4  eleventyConfig.addPlugin(EleventyRenderPlugin);
5  eleventyConfig.extensionMap = [
6    {
7      key: 'txt',
8      extension: 'txt',
9      compile: function compile(str, inputPath, preTemplateEngine, bypass) {
10        return function render(data) {
11          return str;
12        };
13      },
14    },
15  ];
16};

Then you can reference that shared asset file in a blog post.

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

1---
2pageTitle: Some ASCII Art
3---
4
5Welcome to [The Restaurant at the End of the Universe](https://hitchhikers.fandom.com/wiki/Ameglian_Major_Cow)
6
7<pre>
8{% renderFile "../ascii/assets/cow.txt" %}
9</pre>
10
11Art courtesy of [cowsay](https://www.npmjs.com/package/cowsay).

Use the Shared Assets Library in the CLI

For the Go CLI, you only need to update the Go code.

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("../ascii/assets/cow.txt")
17    check(err)
18    fmt.Print(string(dat))
19}

Tell Nx About the Dependencies

Nx without plugins is unable to automatically detect dependencies in Go code or markdown, so you'll have to tell Nx about the dependencies manually. (For Go code, there is @nx-go/nx-go which will automatically detect dependencies between Go projects.)

For the blog project, you'll need to add ascii as a dependency (or devDependency) in the package.json file.

packages/blog/package.json:

1{
2  "name": "blog",
3  "description": "eleventy blog",
4  "version": "1.0.0",
5  "dependency": {
6    "ascii": "*"
7  },
8  "scripts": {
9    "build": "eleventy --input=./src --output=../../dist/packages/blog",
10    "serve": "eleventy --serve --input=./src --output=../../dist/packages/blog"
11  }
12}

For the cli project, you add the implicit dependencies in the project.json file.

packages/cli/project.json:

1{
2  "root": "packages/cli",
3  "sourceRoot": "packages/cli/src",
4  "projectType": "application",
5  "implicitDependencies": ["ascii"],
6  "targets": {
7    "build": {
8      "executor": "@nrwl/workspace:run-commands",
9      "options": {
10        "command": "go build -o='../../dist/packages/cli/' ./src/ascii.go",
11        "cwd": "packages/cli"
12      }
13    },
14    "serve": {
15      "executor": "@nrwl/workspace:run-commands",
16      "options": {
17        "command": "go run ./src/ascii.go",
18        "cwd": "packages/cli"
19      }
20    }
21  }
22}

Test the Changes

You should now be able to run

nx serve blog

and

nx serve cli

and get the same results as before.

View the Project Graph

You can view a visual representation of the project graph by running:

nx graph

When the graph opens in your browser, click the Show all projects button in the left sidebar. You should see dependency lines drawn from blog and cli to ascii.