Skip to content

Commit

Permalink
docs(repo): typo fix on nx enterprise (#17022)
Browse files Browse the repository at this point in the history
  • Loading branch information
Coly010 authored May 15, 2023
1 parent f104d25 commit ee269b9
Showing 1 changed file with 58 additions and 26 deletions.
84 changes: 58 additions & 26 deletions docs/shared/monorepo-nx-enterprise.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Using Nx at Enterprises

Nx is a great tool for companies of all sizes. These days even small products have several microservices and several frontends (say desktop and mobile) which are often built by distributed teams. Being able to do this type of development holistically, using modern tools, is as important for a startup as it is for a well-established organization.
Nx is a great tool for companies of all sizes. These days even small products have several microservices and several
frontends (say desktop and mobile) which are often built by distributed teams. Being able to do this type of development
holistically, using modern tools, is as important for a startup as it is for a well-established organization.

Some things, however, are much more important for large companies:

Expand All @@ -11,21 +13,25 @@ Some things, however, are much more important for large companies:
- Deployment flexibility

{% callout type="note" title="Do what is best for you" %}
Everything below are just recommendations. Every large organization has unique needs, so treat this document as a starting point not the definite list of what you must and must not do.
Everything below are just recommendations. Every large organization has unique needs, so treat this document as a
starting point not the definite list of what you must and must not do.
{% /callout %}

## Code Organization & Naming Conventions

### Apps and Libs

- Apps configure dependency injection and wire up libraries. They should not contain any components, services, or business logic.
- Libs contain services, components, utilities, etc. They have well-defined public API.
- Apps configure dependency injection and wire up libraries. They should not contain any components, services, or
business logic.
- Libs contain services, components, utilities, etc. They have well-≠defined public API.

A typical Nx workspace has many more libs than apps, so pay especially careful attention to the organization of the libs directory.
A typical Nx workspace has many more libs than apps, so pay especially careful attention to the organization of the libs
directory.

### Scope (Where a library lives, who owns it)

It's a good convention to put applications-specific libraries into the directory matching the application name. This provides enough organization for small to mid-size applications.
It's a good convention to put applications-specific libraries into the directory matching the application name. This
provides enough organization for small to mid-size applications.

```treeview
happynrwl/
Expand Down Expand Up @@ -88,7 +94,8 @@ Here we have:

**Portal**

Many enterprise applications are portals: slim shells loading different modules at runtime. If this is what you are building, the following might be a better starting point:
Many enterprise applications are portals: slim shells loading different modules at runtime. If this is what you are
building, the following might be a better starting point:

```treeview
happynrwl/
Expand Down Expand Up @@ -117,7 +124,8 @@ happynrwl/

### Type (What is in the library)

With Nx, we can partition our code into small libraries with well-defined public API. So we can categorize our libraries based on what they contain.
With Nx, we can partition our code into small libraries with well-defined public API. So we can categorize our libraries
based on what they contain.

**These are some common library types:**

Expand All @@ -126,22 +134,30 @@ With Nx, we can partition our code into small libraries with well-defined public
- Component libraries should contain presentational components and directives.
- Feature libraries contain business logic, application screens, etc.

This categorization is a good starting point, but other library types are quite common too (e.g., mock libraries). It's a good idea to establish naming conventions (e.g., `utilities-testing`, `components-buttons`). Having them helps developers explore the code and feel comfortable no matter where they are in the repository.
This categorization is a good starting point, but other library types are quite common too (e.g., mock libraries). It's
a good idea to establish naming conventions (e.g., `utilities-testing`, `components-buttons`). Having them helps
developers explore the code and feel comfortable no matter where they are in the repository.

### Managing Dependencies

For a large organization it's crucial to establish how projects can depend on each other. For instance:

- Libraries with a broader scope (e.g., `shared/ui`) should not depend on the libraries with narrower scope (e.g., `happynrwlapp/search/utils-testing`).
- Component libraries should only depend on other component libraries and utility libraries, but should not depend feature libraries.
- Libraries with a broader scope (e.g., `shared/ui`) should not depend on the libraries with narrower scope (
e.g., `happynrwlapp/search/utils-testing`).
- Component libraries should only depend on other component libraries and utility libraries, but should not depend on
feature libraries.

Nx provides a feature called tags that can be used to codify and statically-enforce these rules. Read more about tags [here](/core-features/enforce-project-boundaries).
Nx provides a feature called tags that can be used to codify and statically-enforce these rules. Read more about
tags [here](/core-features/enforce-project-boundaries).

## Code Ownership

It's crucial for a large company with multiple teams contributing to the same repository to establish clear code ownership.
It's crucial for a large company with multiple teams contributing to the same repository to establish clear code
ownership.

Since Nx allows us to group apps and libs in directories, those directories can become code-ownership boundaries. That's why the structure of an Nx workspace often reflects the structure of an organization. GitHub users can use the `CODEOWNERS` file for that.
Since Nx allows us to group apps and libs in directories, those directories can become code-ownership boundaries. That's
why the structure of an Nx workspace often reflects the structure of an organization. GitHub users can use
the `CODEOWNERS` file for that.

```shell
/libs/happynrwlapp julie-happynrwlapp-lead
Expand All @@ -150,25 +166,32 @@ Since Nx allows us to group apps and libs in directories, those directories can
/libs/shared/utils-testing julie,hank
```

If you want to know more about code ownership on GitHub, please check [the documentation on the `CODEOWNERS` file](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners).
If you want to know more about code ownership on GitHub, please
check [the documentation on the `CODEOWNERS` file](https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners).

## Enforcing Best Practices

When we have 10 people working on an app in the same room, we can agree on best practices over lunch. We can also make sure the team follows them by reviewing each other's PRs. For a team of a hundred located in different cities, this no longer works.
When we have 10 people working on an app in the same room, we can agree on best practices over lunch. We can also make
sure the team follows them by reviewing each other's PRs. For a team of a hundred located in different cities, this no
longer works.

With Nx, we can help teams adopt best practices by using workspace generators and workspace lint checks.

### Workspace Generators

Generators is a library used by Nx to do code generation. `nx g lib mylib` invokes the lib generator from the default collection. Generators are a great way to codify conventions and best practices. Unfortunately, creating a custom generators collection is not very straightforward, so few do it.
Generators is a library used by Nx to do code generation. `nx g lib mylib` invokes the lib generator from the default
collection. Generators are a great way to codify conventions and best practices. Unfortunately, creating a custom
generators collection is not very straightforward, so few do it.

Nx simplifies it. With Nx, we can create custom generators in the `tools/generators` folder and invoke them without having to do compile, build, deploy anything.
Nx simplifies it. With Nx, we can create custom generators in the `tools/generators` folder and invoke them without
having to do compile, build, deploy anything.

Read more about workspace generators in the Workspace Generators guide.

### Workspace Lint Checks

Custom lint checks is another great way to enforce best practices. We can create custom lint checks in the `tools/lint` directory and then register them in `tslint.json` or `.eslintrc.json`.
Custom lint checks is another great way to enforce best practices. We can create custom lint checks in the `tools/lint`
directory and then register them in `tslint.json` or `.eslintrc.json`.

## Developer Workflow

Expand All @@ -182,18 +205,27 @@ Embracing the monorepo-style development often requires some changes to the deve
- It runs e2e tests for all the apps affected by a PR/commit.
- It rebuilds all the apps affected by a PR/commit.

Note `all the projects affected by a PR/commit`. This is very important. Monorepo-style development only works if we rebuild, retest, and relint only the projects that can be affected by our changes. If we instead retest everything, we will get the the following problems:
Note `all the projects affected by a PR/commit`. This is very important. Monorepo-style development only works if we
rebuild, retest, and relint only the projects that can be affected by our changes. If we instead retest everything, we
will get the following problems:

- The performance of CI checks will degrade over time. The time it takes to run the CI checks should be proportional to the impact of the change, not the size of the repo.
- We will be affected by the code your change didn’t touch
- The performance of CI checks will degrade over time. The time it takes to run the CI checks should be proportional to
the impact of the change, not the size of the repo.
- We will be affected by the code your change didn't touch

We should utilize `affected:*` commands to build and test projects. Read more about them [here](/packages/nx/documents/affected).
We should utilize `affected:*` commands to build and test projects. Read more about
them [here](/packages/nx/documents/affected).

### Trunk-based development

Monorepo-style development works best when used with trunk-based development.

When using trunk-based development, we have a single main branch (say `main`) where every team submits their code. And
they do it as soon as possible. So if someone works on a large feature, they split it into a few small changes that can be integrated into main in a week. In other words, when using trunk-based development, teams can create branches, but they are short-lived and focus on a specific user story.

One issue folks often raise in regard to trunk-based development is "things change under you while you are trying to create a release". This can definitely happen, especially when manual testing is involved. To mitigate we can create a release branch where we would cherry-pick commits from `main` to. With this, we can still frequently merge code into `main` and have our release isolated from changes made by other teams.
they do it as soon as possible. So if someone works on a large feature, they split it into a few small changes that can
be integrated into main in a week. In other words, when using trunk-based development, teams can create branches, but
they are short-lived and focus on a specific user story.

One issue folks often raise in regard to trunk-based development is "things change under you while you are trying to
create a release". This can definitely happen, especially when manual testing is involved. To mitigate we can create a
release branch where we would cherry-pick commits from `main` to. With this, we can still frequently merge code
into `main` and have our release isolated from changes made by other teams.

1 comment on commit ee269b9

@vercel
Copy link

@vercel vercel bot commented on ee269b9 May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

nx-dev – ./

nx-dev-git-master-nrwl.vercel.app
nx-five.vercel.app
nx-dev-nrwl.vercel.app
nx.dev

Please sign in to comment.