Skip to content

Commit

Permalink
Merge branch 'master' into tinyglobby
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesHenry authored Dec 4, 2024
2 parents 55b9384 + bba941a commit b0c41a4
Show file tree
Hide file tree
Showing 108 changed files with 2,453 additions and 2,377 deletions.
1 change: 0 additions & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ rust-toolchain @nrwl/nx-native-reviewers
/packages/webpack/** @nrwl/nx-js-reviewers
/e2e/webpack/** @nrwl/nx-js-reviewers
/packages/rspack/** @nrwl/nx-js-reviewers
/packages/rspack/src/utils/module-federation @nrwl/nx-js-reviewers
/e2e/rspack/** @nrwl/nx-js-reviewers
/packages/esbuild/** @nrwl/nx-js-reviewers
/e2e/esbuild/** @nrwl/nx-js-reviewers
Expand Down
86 changes: 86 additions & 0 deletions docs/blog/2024-12-03-define-the-relationship-with-monorepos.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
title: Define the relationship with monorepos
slug: define-the-relationship-with-monorepos
authors: ['Philip Fulcher']
tags: [nx]
cover_image: /blog/images/2024-12-03/header.avif
---

A monorepo might sound like a big, intimidating thing, but we're going to break it down to just the bare essentials. **A monorepo helps you better manage the relationships that already exist between your projects.** Once we understand those relationships, we can use tools to very quickly define them and pull them together into a more cohesive whole.

## So, what is a monorepo?

Let's start with the big question: what even is a monorepo?

> That's like when Google only has one repo for the entire company, right?
Not quite. That scale of monorepo doesn't work for most organizations, and we can still use a monorepo approach for smaller systems.

> So it's when you throw all your code in one repo and figure out how to manage it later?
This is also a pretty bad idea. We need tools and processes to manage this volume of code in a single repo.

The best definition I've seen comes from [monorepo.tools](https://monorepo.tools):

> A monorepo is a single repository containing multiple distinct projects with well-defined relationships.
Let's dig into that last part. What do we mean by **well-defined relationships?** It's useful to stat thinking about relationships between code in terms of distance.

## The shortest distance: importing from another file

We'll start with the smallest possible distance between two pieces of code: importing something from another file.

![Diagram showing a form component depending on a button component](/blog/images/2024-12-03/another-file.avif)

Say you have a button component. You create a form and import that button to use. This is a relationship we take for granted because we do it all the time, but there are some distinct benefits to this.

First, we see the impact of our change immediately. We make a change in the button, and we either see the result rendered in the browser, or we get a failed compilation. Or we have a test suite running that will fail or pass a test. Or lint rule warnings appear in our IDE. We immediately see the result of the change we've made, and the impact on the relationship.

This makes iteration fast: we see the impact of the change and can either refine that change or move on to the next one.

## One step away in distance: importing from a package

Let's take a step further away and think about the relationship when you have imported something from a package.

![Diagram showing a form component depending on a design system package that bundles a button component](/blog/images/2024-12-03/package.avif)

Say you have a design system published for your organization. You import the button from that package to use in your form. This looks very similar to what we did before, but we've introduced a big change in this relationship: seeing change is no longer immediate.

If we make a change in the button, there will be some sort of compilation, bundling, and publishing that will need to happen. And we'll need to consume the latest version of the package to actually see the change.

This is a slow process when you're working alone, but it can be managed with some tools. However, what happens if this change crosses team boundaries? Your design system team makes a change to the button and has to go through a PR review and merge process. Eventually that change is released as a new version and published. At some point later, you upgrade your version of the dependency just to find out the button has changed. But there's a bug! You report back to the design system team, and now they're going through this entire process again to get the fix in and published. This iteration cycle is very slow because understanding the impact of the change in the design system is no longer immediately apparent to consumers.

## Even further away: APIs

Let's step one step further: using APIs. Your frontend (in most cases) requires a backend, and it will be broken without it.

![Diagram showing a frontend sending requests to a backend, and the backends responds to the frontend](/blog/images/2024-12-03/api.avif)

There is an **implicit dependency** between the frontend and backend. You don't import code directly, but you do depend on the backend to function.

Let's say that there's a new API endpoint needed, and you agreed with the team that it would be called `api/v1/contact/create` and would accept a payload with `contactName`.

But, the backend team had a conversation about naming standards during their sprint and made the decision that it could really be `contact/init` with a payload of `fullName`.

Understanding the impact of this change is now far-removed from making the change. Not only is there the PR merge, packaging, and releasing, but also deployment. It may not be until the end of the sprint before the impact of this change is actually understood. This iteration is practically glacial.

## How do monorepos help?

How do monorepos help with these relationships? **They shorten the distance of relationships between code.** Code is **colocated** so that the impact of your change can be understood immediately.

In the example with the design system, the button will be imported directly instead of going through a build and package process. The design system team can immediately see the impact of the change they're making and either adjust their approach or fix the issue directly in the consuming app.

For the API team, we can define that implicit relationship between backend and frontend so that we trigger e2e tests to confirm a change works. Or we can generate models from the backend to be consumed by the frontend. When the models are changed, the frontend code that imported those models will immediately reveal the impact of the change.

You might think that moving projects into a single repository changes the relationship between the projects. But the relationships we've talked about here already exist; the monorepo makes those relationships explicit and well-defined. With good monorepo tooling, we can understand the impact of change along any of these relationships faster in a monorepo.

## Learn more

- [Nx Docs](/getting-started/intro)
- [X/Twitter](https://twitter.com/nxdevtools)
- [LinkedIn](https://www.linkedin.com/company/nrwl/)
- [Bluesky](https://bsky.app/profile/nx.dev)
- [Nx GitHub](https://github.com/nrwl/nx)
- [Nx Official Discord Server](https://go.nx.dev/community)
- [Nx Youtube Channel](https://www.youtube.com/@nxdevtools)
- [Speed up your CI](/nx-cloud)
Binary file added docs/blog/images/2024-12-03/another-file.avif
Binary file not shown.
Binary file added docs/blog/images/2024-12-03/api.avif
Binary file not shown.
Binary file added docs/blog/images/2024-12-03/header.avif
Binary file not shown.
Binary file added docs/blog/images/2024-12-03/header.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/blog/images/2024-12-03/package.avif
Binary file not shown.
20 changes: 2 additions & 18 deletions docs/generated/packages/playwright/documents/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,9 @@ The `targetName` and `ciTargetName` options control the name of the inferred Pla

### Splitting E2E Tests

The `@nx/playwright/plugin` will automatically split your e2e tasks by file if you provide a `ciTargetName`. You can read more about the Atomizer feature [here](/ci/features/split-e2e-tasks). This will create a target with that name which can be used in CI to run the tests for each file in a distributed fashion.
`@nx/playwright/plugin` leverages Nx Atomizer to split your e2e tests into smaller tasks in a fully automated way. This allows for a much more efficient distribution of tasks in CI. You can read more about the Atomizer feature [here](/ci/features/split-e2e-tasks).

```json {% fileName="nx.json" %}
{
"plugins": [
{
"plugin": "@nx/playwright/plugin",
"options": {
"targetName": "e2e",
"ciTargetName": "e2e-ci"
}
}
]
}
```

### Splitting E2E tasks by file

The `@nx/playwright/plugin` will automatically split your e2e tasks by file. You can read more about this feature [here](/ci/features/split-e2e-tasks).
If you would like to disable Atomizer for Playwright tasks, set `ciTargetName` to `false`.

{% /tab %}
{% tab label="Nx < 18" %}
Expand Down
6 changes: 0 additions & 6 deletions docs/nx-cloud/reference/launch-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -360,12 +360,6 @@ If you need to send environment variables to agents, you can use the [--with-env
nx-cloud start-ci-run --distribute-on="8 linux-medium-js" --with-env-vars="VAR1,VAR2"
```

Or pass all the environment variables except OS-specific ones with this `--with-env-vars="auto"`:

```
nx-cloud start-ci-run --distribute-on="8 linux-medium-js" --with-env-vars="auto"
```

## Pass Values Between Steps

If you need to pass a value from one step to another step, such as assigning the value to an existing or new environment variable. You can write to the `NX_CLOUD_ENV` environment file.
Expand Down
7 changes: 0 additions & 7 deletions docs/nx-cloud/reference/nx-cloud-cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,13 +206,6 @@ main CI jobs and the Nx Agent machines.
If you want to pass other environment variables from the main job to Nx Agents, you can do it as follows: `--with-env-vars="VAR1,VAR2"`.
This will set `VAR1` and `VAR2` on Nx Agents to the same values set on the main job before any steps run.

You can also pass `--with-env-vars="auto"` which will filter out all OS-specific environment variables and pass the rest to Nx Agents.

{% callout type="warning" title="Use Caution With 'auto'" %}
Using `--with-env-vars="auto"` will override any existing environment variables on the Nx Agent, some of which might be critical to the
functionality of that machine. In case of unexpected issues on Nx Agents, try fallback to the explicit variable definition using `--with-env-vars="VAR1,VAR2,..."`.
{% /callout %}

Note: none of the values passed to Nx Agents are stored by Nx Cloud.

### Enabling/Disabling Distribution
Expand Down
20 changes: 2 additions & 18 deletions docs/shared/packages/playwright/playwright-plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,25 +67,9 @@ The `targetName` and `ciTargetName` options control the name of the inferred Pla

### Splitting E2E Tests

The `@nx/playwright/plugin` will automatically split your e2e tasks by file if you provide a `ciTargetName`. You can read more about the Atomizer feature [here](/ci/features/split-e2e-tasks). This will create a target with that name which can be used in CI to run the tests for each file in a distributed fashion.
`@nx/playwright/plugin` leverages Nx Atomizer to split your e2e tests into smaller tasks in a fully automated way. This allows for a much more efficient distribution of tasks in CI. You can read more about the Atomizer feature [here](/ci/features/split-e2e-tasks).

```json {% fileName="nx.json" %}
{
"plugins": [
{
"plugin": "@nx/playwright/plugin",
"options": {
"targetName": "e2e",
"ciTargetName": "e2e-ci"
}
}
]
}
```

### Splitting E2E tasks by file

The `@nx/playwright/plugin` will automatically split your e2e tasks by file. You can read more about this feature [here](/ci/features/split-e2e-tasks).
If you would like to disable Atomizer for Playwright tasks, set `ciTargetName` to `false`.

{% /tab %}
{% tab label="Nx < 18" %}
Expand Down
21 changes: 21 additions & 0 deletions e2e/react/src/react.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,27 @@ describe('React Applications', () => {
}
}, 250_000);

it('None buildable libs using (useTsSolution = true) should be excluded from js/ts plugin', async () => {
const appName = uniq('app');
const libName = uniq('lib');

runCLI(
`generate @nx/react:app apps/${appName} --name=${appName} --useTsSolution true --bundler=vite --no-interactive --skipFormat --linter=eslint --unitTestRunner=vitest`
);
runCLI(
`generate @nx/react:lib ${libName} --bundler=none --no-interactive --unit-test-runner=vitest --skipFormat --linter=eslint`
);

const nxJson = JSON.parse(readFile('nx.json'));

const jsTypescriptPlugin = nxJson.plugins.find(
(plugin) => plugin.plugin === '@nx/js/typescript'
);
expect(jsTypescriptPlugin).toBeDefined();

expect(jsTypescriptPlugin.exclude.includes(`${libName}/*`)).toBeTruthy();
}, 250_000);

it('should be able to use Rspack to build and test apps', async () => {
const appName = uniq('app');
const libName = uniq('lib');
Expand Down
5 changes: 0 additions & 5 deletions nx-dev/ui-company/src/lib/the-team.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,6 @@ const teamMembers = [
title: 'Director of Professional Services',
imageUrl: 'joe-johnson.avif',
},
{
name: 'Johanna Pearce',
title: 'Architect',
imageUrl: 'johanna-pearce.avif',
},
{
name: 'Jonathan Cammisuli',
title: 'Architect',
Expand Down
39 changes: 24 additions & 15 deletions packages/angular/migrations.json
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,7 @@
"cli": "nx",
"version": "20.2.0-beta.5",
"requires": {
"@angular/core": ">=19.0.0-rc.1"
"@angular/core": ">=19.0.0"
},
"description": "Add the '@angular/localize/init' polyfill to the 'polyfills' option of targets using esbuild-based executors.",
"factory": "./src/migrations/update-20-2-0/add-localize-polyfill-to-targets"
Expand All @@ -301,10 +301,19 @@
"cli": "nx",
"version": "20.2.0-beta.5",
"requires": {
"@angular/core": ">=19.0.0-rc.1"
"@angular/core": ">=19.0.0"
},
"description": "Update '@angular/ssr' import paths to use the new '/node' entry point when 'CommonEngine' is detected.",
"factory": "./src/migrations/update-20-2-0/update-angular-ssr-imports-to-use-node-entry-point"
},
"disable-angular-eslint-prefer-standalone": {
"cli": "nx",
"version": "20.2.0-beta.6",
"requires": {
"@angular/core": ">=19.0.0"
},
"description": "Disable the Angular ESLint prefer-standalone rule if not set.",
"factory": "./src/migrations/update-20-2-0/disable-angular-eslint-prefer-standalone"
}
},
"packageJsonUpdates": {
Expand Down Expand Up @@ -1284,19 +1293,6 @@
}
}
},
"20.2.0-analog": {
"version": "20.2.0-beta.5",
"packages": {
"@analogjs/vitest-angular": {
"version": "~1.10.0-beta.6",
"alwaysAddToPackageJson": false
},
"@analogjs/vite-plugin-angular": {
"version": "~1.10.0-beta.6",
"alwaysAddToPackageJson": false
}
}
},
"20.2.0-jest": {
"version": "20.2.0-beta.5",
"requires": {
Expand Down Expand Up @@ -1341,6 +1337,19 @@
"alwaysAddToPackageJson": false
}
}
},
"20.2.0-analog": {
"version": "20.2.0-beta.7",
"packages": {
"@analogjs/vitest-angular": {
"version": "~1.10.0",
"alwaysAddToPackageJson": false
},
"@analogjs/vite-plugin-angular": {
"version": "~1.10.0",
"alwaysAddToPackageJson": false
}
}
}
}
}
8 changes: 4 additions & 4 deletions packages/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@
"piscina": "^4.4.0"
},
"peerDependencies": {
"@angular-devkit/build-angular": ">= 16.0.0 < 19.0.0",
"@angular-devkit/core": ">= 16.0.0 < 19.0.0",
"@angular-devkit/schematics": ">= 16.0.0 < 19.0.0",
"@schematics/angular": ">= 16.0.0 < 19.0.0",
"@angular-devkit/build-angular": ">= 17.0.0 < 20.0.0",
"@angular-devkit/core": ">= 17.0.0 < 20.0.0",
"@angular-devkit/schematics": ">= 17.0.0 < 20.0.0",
"@schematics/angular": ">= 17.0.0 < 20.0.0",
"rxjs": "^6.5.3 || ^7.5.0"
},
"publishConfig": {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
export * from './build-static-remotes';
export * from './normalize-options';
export * from './start-dev-remotes';
export * from './start-static-remotes-file-server';
Loading

0 comments on commit b0c41a4

Please sign in to comment.