Power up Gatsby sites development in a Monorepo Using Nx
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
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:
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 forcli
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
:
The MyLib
component 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:
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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK