Skip to content

Commit

Permalink
docs(nx): 📝 update examples with createNodesV2
Browse files Browse the repository at this point in the history
  • Loading branch information
yjaaidi committed Jun 7, 2024
1 parent 8b82833 commit 2b8759f
Showing 1 changed file with 181 additions and 147 deletions.
328 changes: 181 additions & 147 deletions apps/cookbook/docs/nx/03-scaling/04-implicit-libs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -249,25 +249,32 @@ libs/web
Now, you can create a workspace plugin that will add the libraries to the Nx graph.

```ts title="tools/plugins/implicit-libs.ts"
import { CreateNodes } from '@nx/devkit';
import { CreateNodesV2 } from '@nx/devkit';

export const createNodes: CreateNodes = [
export const createNodesV2: CreateNodesV2 = [
/* This will look for all `index.ts` files that follow your file structure convention. */
'libs/*/*/*/index.ts',
(indexPath: string) => {
const [libs, platform, scope, name] = indexPath.split('/');
const projectRoot = `${libs}/${platform}/${scope}/${name}`;
const projectName = `${platform}-${scope}-${name}`;

return {
projects: {
/* This will add a project to the Nx graph for the detected library. */
[projectRoot]: {
name: projectName,
projectType: 'library',
(indexPathList) => {
return indexPathList.map((indexPath) => {
const [libs, platform, scope, name] = indexPath.split('/');
const projectRoot = `${libs}/${platform}/${scope}/${name}`;
const projectName = `${platform}-${scope}-${name}`;

return [
/* This is used by Nx to track which matching file was used by the plugin
* It is shown in the project detail web view. */
indexPath,
{
projects: {
/* This will add a project to the Nx graph for the detected library. */
[projectRoot]: {
name: projectName,
projectType: 'library',
},
},
},
},
};
];
});
},
];
```
Expand All @@ -281,7 +288,7 @@ NX_DAEMON=false NX_PERF_LOGGING=true nx show projects

:::

Once you enable the plugin by adding it to your plugins in the `nx.json` file, you should see the libraries in the Nx graph.
Once you enable the plugin by adding it to your plugins in the `nx.json` file, you should see the libraries in the Nx graph _(`nx graph`)_.

```json title="nx.json"
{
Expand All @@ -301,35 +308,41 @@ web-cart-ui
As we removed the `project.json` files, Nx plugins will not add any targets to the libraries. We have to adapt our plugin to add the targets we need.

```ts title="tools/plugins/implicit-libs.ts"
export const createNodes: CreateNodes = [
export const createNodesV2: CreateNodesV2 = [
/* This will look for all `index.ts` files that follow your file structure convention. */
'libs/*/*/*/index.ts',
(indexPath: string) => {
// ...
return {
projects: {
[projectRoot]: {
name: projectName,
projectType: 'library',
// highlight-start
targets: {
lint: {
command: 'eslint .',
options: {
cwd: projectRoot,
},
},
test: {
command: 'vitest',
options: {
cwd: projectRoot,
root: '.',
(indexPathList) => {
return indexPathList.map((indexPath) => {
// ...
return [
indexPath,
{
projects: {
[projectRoot]: {
name: projectName,
projectType: 'library',
// highlight-start
targets: {
lint: {
command: 'eslint .',
options: {
cwd: projectRoot,
},
},
test: {
command: 'vitest',
options: {
cwd: projectRoot,
root: '.',
},
},
},
// highlight-end
},
},
// highlight-end
},
},
};
];
});
},
];
```
Expand All @@ -343,56 +356,66 @@ Note that while we could technically hide the configuration files (e.g., `.eslin
While the example above is a good start, it is still missing the caching configuration, but here is the good news: you can also infer the caching configuration.

```ts title="tools/plugins/implicit-libs.ts"
export const createNodes: CreateNodes = [
export const createNodesV2: CreateNodesV2 = [
/* This will look for all `index.ts` files that follow your file structure convention. */
'libs/*/*/*/index.ts',
(indexPath: string) => {
// ...

return {
projects: {
[projectRoot]: {
// ...
targets: {
lint: {
command: 'eslint .',
// ...
(indexPathList) => {
return indexPathList.map((indexPath) => {
// ...
return [
indexPath,
{
projects: {
[projectRoot]: {
name: projectName,
projectType: 'library',
// highlight-start
cache: true,
inputs: [
'default',
'^default',
'{workspaceRoot}/.eslintrc.json',
`{workspaceRoot}/${libs}/${platform}/.eslintrc.json`,
'{workspaceRoot}/tools/eslint-rules/**/*',
{
externalDependencies: ['eslint'],
targets: {
lint: {
command: 'eslint .',
// ...
// highlight-start
cache: true,
inputs: [
'default',
'^default',
'{workspaceRoot}/.eslintrc.json',
`{workspaceRoot}/${libs}/${platform}/.eslintrc.json`,
'{workspaceRoot}/tools/eslint-rules/**/*',
{
externalDependencies: ['eslint'],
},
],
outputs: ['{options.outputFile}'],
// highlight-end
},
],
outputs: ['{options.outputFile}'],
// highlight-end
},
test: {
command: 'vitest',
// ...
// highlight-start
cache: true,
inputs: [
'default',
'^production',
{
externalDependencies: ['vitest'],
},
{
env: 'CI',
test: {
command: 'vitest',
// ...
// highlight-start
cache: true,
inputs: [
'default',
'^production',
{
externalDependencies: ['vitest'],
},
{
env: 'CI',
},
],
outputs: [
`{workspaceRoot}/coverage/${libs}/${platform}/${name}`,
],
// highlight-end
},
],
outputs: [`{workspaceRoot}/coverage/${libs}/${platform}/${name}`],
},
// highlight-end
},
},
},
},
};
];
});
},
];
```
Expand All @@ -415,20 +438,26 @@ _(e.g. [@nx/eslint](https://github.com/nrwl/nx/blob/master/packages/eslint/src/p
Finally, you can let the plugin tag the libraries based on the file structure convention.

```ts title="tools/plugins/implicit-libs.ts"
export const createNodes: CreateNodes = [
export const createNodesV2: CreateNodesV2 = [
/* This will look for all `index.ts` files that follow your file structure convention. */
'libs/*/*/*/index.ts',
(indexPath: string) => {
// ...

return {
projects: {
[projectRoot]: {
// ...
// highlight-next-line
tags: [`platform:${platform}`, `scope:${scope}`, `type:${type}`],
(indexPathList) => {
return indexPathList.map((indexPath) => {
// ...

return [
indexPath,
{
projects: {
[projectRoot]: {
// ...
// highlight-next-line
tags: [`platform:${platform}`, `scope:${scope}`, `type:${type}`],
},
},
},
},
};
];
});
},
];
```
Expand Down Expand Up @@ -469,65 +498,70 @@ While Implicit Libraries make library generators less useful, implementing a gen
Here is the full plugin example:

```ts title="tools/plugins/implicit-libs.ts"
import { CreateNodes } from '@nx/devkit';
import { CreateNodesV2 } from '@nx/devkit';

export const createNodes: CreateNodes = [
export const createNodesV2: CreateNodesV2 = [
'libs/*/*/*/index.ts',
(indexPath: string) => {
const [libs, platform, scope, name] = indexPath.split('/');
const projectRoot = `${libs}/${platform}/${scope}/${name}`;
const projectName = `${platform}-${scope}-${name}`;
const nameParts = name.split('-');
const type = nameParts.at(-1);

return {
projects: {
[projectRoot]: {
name: projectName,
projectType: 'library',
tags: [`platform:${platform}`, `scope:${scope}`, `type:${type}`],
targets: {
lint: {
command: 'eslint .',
options: {
cwd: projectRoot,
},
cache: true,
inputs: [
'default',
'^default',
'{workspaceRoot}/.eslintrc.json',
`{workspaceRoot}/${libs}/${platform}/.eslintrc.json`,
'{workspaceRoot}/tools/eslint-rules/**/*',
{
externalDependencies: ['eslint'],
},
],
outputs: ['{options.outputFile}'],
},
test: {
command: 'vitest',
options: {
cwd: projectRoot,
root: '.',
},
cache: true,
inputs: [
'default',
'^production',
{
externalDependencies: ['vitest'],
(indexPathList[]) => {
return indexPathList.map(indexPath => {
const [libs, platform, scope, name] = indexPath.split('/');
const projectRoot = `${libs}/${platform}/${scope}/${name}`;
const projectName = `${platform}-${scope}-${name}`;
const nameParts = name.split('-');
const type = nameParts.at(-1);

return [
indexPath,
{
projects: {
[projectRoot]: {
name: projectName,
projectType: 'library',
tags: [`platform:${platform}`, `scope:${scope}`, `type:${type}`],
targets: {
lint: {
command: 'eslint .',
options: {
cwd: projectRoot,
},
cache: true,
inputs: [
'default',
'^default',
'{workspaceRoot}/.eslintrc.json',
`{workspaceRoot}/${libs}/${platform}/.eslintrc.json`,
'{workspaceRoot}/tools/eslint-rules/**/*',
{
externalDependencies: ['eslint'],
},
],
outputs: ['{options.outputFile}'],
},
{
env: 'CI',
test: {
command: 'vitest',
options: {
cwd: projectRoot,
root: '.',
},
cache: true,
inputs: [
'default',
'^production',
{
externalDependencies: ['vitest'],
},
{
env: 'CI',
},
],
outputs: [`{workspaceRoot}/coverage/${libs}/${platform}/${name}`],
},
],
outputs: [`{workspaceRoot}/coverage/${libs}/${platform}/${name}`],
},
},
},
},
},
};
}
];
});
},
];
```
Expand Down

0 comments on commit 2b8759f

Please sign in to comment.