90

Power up Gatsby sites development in a Monorepo Using Nx

 3 years ago
source link: https://blog.nrwl.io/power-up-gatsby-sites-development-in-a-monorepo-using-nx-258cae0fc036
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Power up Gatsby sites development in a Monorepo Using Nx

Image for post
Image for post

Today, the most common way to develop a Gatsby project is to use the official Gatsby CLI. It’s a great tool to use if you’re developing a Gatsby app as a standalone project. However, if you’re working on an application that is part of a monorepo the official CLI may not be the best choice.

In case you are not familiar with the monorepo approach, it’s a pattern for code organization where multiple projects are being developed inside a single repository. An alternative to a monorepo is a set of standalone repositories connected through some VCS mechanism, like submodules in Git. However, making changes across many repositories is messy and difficult to track, and testing across repositories becomes complicated very quickly. To solve these and many other problems, companies such as Facebook and Google, as well as popular open source projects such as Babel and React organize their codebases into multi-package repositories called monorepos.

Developing inside a monorepo entails a number of tedious tasks that need to be automated like linking packages together to enable sharing components, managing dependencies between projects, setting up integration with a unit test or a end-to-end test framework, automatic code generation etc. Naturally, tools have been developed to automate some or all of the above tasks.

In the React world that would usually be Yarn workspaces for simpler projects and Lerna for large enterprise projects. Although widely used, those tools are mostly focused on dependency linking tasks and don’t really help with other tasks.

At Nrwl, we’ve developed a tool called Nx based on our experience working at Google and helping Fortune 500 enterprises build ambitious applications at scale. We believe it’s the ultimate tool to automate tasks inside a monorepo. If you want to learn more, there’s a great article on why you would prefer Nx over Lerna specifically for enterprise applications.

We are happy to announce that we have added official support for Gatsby applications!

You can now generate a Gatsby application inside an Nx monorepo, along with the integration to build, test, and lint the project. Combined with the power of Nx to easily generate shared libraries, integrate with the dependency graph, local caching, and more, your Gatsby applications and websites can work more easily within an Nx workspace.

In this article I’m going to show you how to use Gatsby plugin inside a monorepo.

It’s a common approach to use multiple frontend technologies inside a monorepo to build different parts of a product. Because Gatsby is most often used alongside React apps where both share components and utilities, here’s what I’ll show you in this blog post:

  • how to create a new Nx workspace
  • how to generate a new Gatsby and React applications
  • how to generate and use a shared library of UI components
  • how to run tests and see dependency graph
  • deploy a gatsby blog to netlify?

Here’s the high-level diagram of what we’ll build:

Image for post
Image for post
Image for post
Image for post

Setting this all up inside a monorepo without a good tool is challenging. Companies put a lot of effort in making sure teams can collaborate and use each other’s work. Nx drastically simplifies this.

Please note that this is not “How to get started with Gatsby” article, the official tutorial is really great. In this article I’m assuming you already have the experience of working with Gatsby and React and have the knowledge of tools like Git commonly used in web development.

Also, please check out the working repo if you want to play around with the examples in this post yourself.

Getting Started

Alright, let’s get started. Navigate to an empty folder in the terminal and create a new Nx workspace using create-nx-workspace command:

npx create-nx-workspace my-app --preset=empty --cli=nx

You can see that I’m passing a few extra options:

  • preset empty will generate a workspace without any plugins added
  • nx value used for cli parameter defines the underlying CLI

Instead of empty preset we could choose to create a React workspace with React plugin installed by default. But because when I’m explaining something I usually try to break a whole into smaller pieces and show how they are connected together we’ll install React and Gatsby packages manually.

Once the command finished running, you can observe the directory structure inside the newly created my-app folder:

apps/
libs/
tools/
package.json
workspace.json
nx.json
tsconfig.json
tslint.json
yarn.lock

Two directories that you should pay attention to are apps and libs. In Nx, we separate projects into applications and libraries.

Think of projects as modules that are distinct but may have dependencies on each other. An application is a composition of libraries that can run in the browser or server. They live in the apps folder. A library on the other hand is a group of functionalities with a well-defined API. A library can depend on other libraries, and cannot run on their own. They live in the libs folder.

Once we have our monorepo workspace ready, let’s add the Gatsby plugin.

Installing Gatsby plugin

All Nx plugins are published as npm packages, so to add a Gatsby plugin we simply install it as a dependency:

yarn add --dev @nrwl/gatsby# Or for npm
npm install --save-dev @nrwl/gatsby

Once we’ve installed the plugin, we can use it to generate a new Gatsby application. Run the following command:

npx nx generate @nrwl/gatsby:application myblog

The syntax for running a command for Nx is the following:

nx [command] [plugin:target] <options>

So with the above command we tell Nx to generate an application with the name myblog. Once the command has finished running, you can observe that an application myblog has been added inside the apps folder:

|-- myblog
| |-- README.md
| |-- gatsby-browser.js
| |-- gatsby-config.js
| |-- gatsby-node.js
| |-- gatsby-ssr.js
| |-- jest.config.js
| |-- package.json
| |-- src
| | |-- images
| | | `-- logo.png
| | `-- pages
| | |-- 404.js
| | |-- index.css
| | |-- index.spec.tsx
| | |-- index.tsx
| | |-- logo.svg
| | `-- star.svg
| |-- tsconfig.json
| `-- tsconfig.spec.json
|-- myblog-e2e

Right away you can run this application with yarn start and open http://localhost:4200 to see the result.

You probably noticed that the generated Gatsby application is TypeScript. Since most enterprise projects nowadays are developed with TypeScript, we made a default choice. All TS configuration is setup automatically for you by Nx.

Serving the application

The yarn start command simply runs nx serve command. The full command is:

nx serve myblog

If there’s no name passed to the command, Nx takes it from the defaultProject entry inside the workspace.json. In our case it’s myblog.

To build the application use:

nx build myblog

To build and serve the production website, use the --prod flag.

If you’ve used Gatsby CLI before, here’s the mapping between Nx and Gatsby commands:

+--------------+----------------+
| Nx | Gatsby |
+--------------+----------------+
| serve | develop |
| build | build |
| serve --prod | build && serve |
+--------------+----------------+

Alright, good, let’s take a look next at what we can do with Nx out of the box.

Generating components and pages

As you probably know, a React component defined in src/pages/*.js will automatically become a page. With Nx, you can create new pages by running the generate command. Let’s see it in action, run this command:

# Or just `nx g` for short
npx nx generate page About --project=myblog --style=css

This tells Nx to add a new apps/myblog/pages/About.tsx component to the myblog project that we generated earlier.

You can use the same technique to generate a new component:

npx nx g @nrwl/gatsby:component --name=title --project=myblog

This will generate the component Title under the apps/myblog/components/ folder:

Let’s use this Title component in the About page. Update your code as follows:

And now when you navigate to http://localhost:4200/about you should see the new page with the text Welcome to Title! coming from the Title component.

Running tests

You may have noticed that when we generated a Gatsby application, Nx also create another project myblog-e2e. By default, all apps generated through Nx comes with Cypress tests that is automatically set up for you. You can run them with nx e2e myblog-e2e, and the specs are in the apps/myblog-e2e folder.

All right, so far we’ve seen how we can generate a new Nx workspace with a Gatsby application. We also saw how easy it is to generate new pages and components using the generate command. Testing setup is also automatically done for you inside Nx.

We’re ready now to move to our next task of generating a React project and a library of shared UI components.

Installing React plugin

Let’s navigate into the folder my-app and add React plugin:

yarn add --dev @nrwl/react# Or with npm
npm install --save-dev @nrwl/react

We’ll use this plugin to generate a new React application like this:

npx nx generate @nrwl/react:app reactapp

Once the command has finished running, we have a React app added to our monorepo:

reactapp
|-- babel-jest.config.json
|-- jest.config.js
|-- src
| |-- app
| | |-- app.css
| | |-- app.spec.tsx
| | |-- app.tsx
| | |-- logo.svg
| | `-- star.svg
| |-- assets
| |-- environments
| | |-- environment.prod.ts
| | `-- environment.ts
| |-- favicon.ico
| |-- index.html
| |-- main.tsx
| |-- polyfills.ts
| `-- styles.css
|-- tsconfig.app.json
|-- tsconfig.json
`-- tsconfig.spec.json
reactapp-e2e

You can serve and build it using the same commands serve and build as we used for Gatsby.

Generating shared library

Let’s now generate a library of React components. We will use the same React plugin, but instead of using application schematics used to generate an application, this time we will use the lib schematics:

npx nx generate @nrwl/react:lib my-lib

After the command finished executing, observe contents of the libs folder:

libs/
`-- my-lib
|-- README.md
|-- babel-jest.config.json
|-- jest.config.js
|-- src
| |-- index.ts
| `-- lib
| |-- my-lib.css
| |-- my-lib.spec.tsx
| `-- my-lib.tsx
|-- tsconfig.json
|-- tsconfig.lib.json
`-- tsconfig.spec.json

As you can see, our library library contains one very basic MyLib component:

Using a component from shared library inside Gatsby app

Because Nx automatically sets up path mapping for us when a new library is generated, to use a component inside Gatsby and React projects we simply import it from the @nx-workspace/my-lib. The path mapping is added to tsconfig.json:

{
"compileOnSave": false,
"compilerOptions": {
"rootDir": ".",
"sourceMap": true,
...
"baseUrl": ".",
"paths": {
"@nx-workspace/my-lib": ["libs/my-lib/src/index.ts"]
}
},
"exclude": ["node_modules", "tmp"]
}

So let’s use the component from a shared library in Index page in the Gatsby project. Update the Index component code as follows:

Now if we run Gatsby or React component we will see the Welcome to my-lib phrase rendered alongside Welcome to myblog:

Image for post
Image for post

The MyLibcomponent from the shared library could be used inside a React app in the same way.

Understanding Our Dependencies

As our workspace continues to grow, it is crucial that we understand the dependencies between applications and libraries. This is why Nx provides the dep-graph command to illustrate the dependencies. You can run it like this:

npx nx dep-graph

For the current setup, this command will generate the following graph:

Image for post
Image for post

As you can see, both the myblog and reactapp projects depend on the my-lib library. On the diagram above, application nodes are rectangles, and library nodes are ovals.

In Closing

Let’s recap. We started with an empty Nx workspace and added a new Gatsby application. We then saw how to generate pages and components using Nx and run tests. Using @nrwl/react plugin, we added a new React project and generated a shared library and used a component from the library in both applications. Lastly, we used Nx to figure out dependencies and show a dependency graph.

The material covered in this post scratches only the surface of what Nx provides. There are lots of other useful features, like distributed caching, that you get for free when using Nx. If you’re interested in learning more, please head over to our docs!

We are continuing to work to ensure the support for Gatsby continues to improve. Feel free provide us feedback on GitHub on how to improve the experience.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK