nx/docs/shared/recipes/plugins/create-preset.md
Jack Hsu 8fa7065cf1
docs(misc): update generator examples to use new directory/path positional args (#28144)
This PR updates examples in `.md` files (both docs and blog posts) to
use positional args. Nx 20 changes the position arg to be either
`directory` for apps/libs or `path` for artifacts (e.g. components).

So before you'd do this:

```
nx g app myapp --directory=apps/myapp
nx g lib mylib --directory=libs/mylib
nx g lib mylib --directory=libs/nested/mylib
nx g lib @acme/foo --directory=libs/@acme/foo --importPath=@acme/foo
nx g component foo --directory=libs/ui/src/foo --pascalCaseFiles
```

Will now be simplified to

```
nx g app apps/myapp
nx g lib libs/mylib
nx g lib libs/nested/mylib
nx g lib libs/@acme/foo # name and import path are both "@acme/foo"
nx g component libs/ui/src/foo/Foo
```

For cases where `name` and `importPath` need to be changed, you can
always manually specify them.

```
nx g lib libs/nested/foo # name is foo
nx g lib libs/nested/foo --name=nested-foo # specify name with prefix
nx g lib libs/@acme/foo --name # use "foo" as name and don't match importPath
nx g lib libs/@internal/foo --importPath=@acme/foo # different importPath from name

<!-- If this is a particularly complex change or feature addition, you can request a dedicated Nx release for this pull request branch. Mention someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they will confirm if the PR warrants its own release for testing purposes, and generate it for you if appropriate. -->

## Current Behavior
<!-- This is the behavior we have today -->

## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR -->

## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is merged. -->

Fixes #
2024-09-30 13:20:10 -04:00

4.0 KiB

Create a Custom Plugin Preset

When you create a new nx workspace, you run the command: npx create-nx-workspace. This command accepts a --preset option, for example: npx create-nx-workspace --preset=react-standalone. This preset option is pointing to a special generator function (remember, a generator is a function that simplifies an entire code generation script into a single function) that Nx will call when this npx create-nx-workspace command is run, that will generate your initial workspace.

{% youtube src="https://www.youtube.com/embed/yGUrF0-uqaU" title="Develop a Nx Preset for your Nx Plugin" /%}

What is a preset?

At its core, a preset is a special generator that is shipped as part of an Nx Plugin package.

All first-party Nx presets are built into Nx itself, but you can create your own plugin and create a generator with the magic name: preset. Once you've published your plugin on npm, you can now run the create-nx-workspace command with the preset option set to the name of your published package.

To use a concrete example, let's look at the qwik-nx Nx community plugin. They include a preset generator that you can use to create a new Nx workspace with Qwik support.

npx create-nx-workspace --preset=qwik-nx

Create a new Nx plugin

If you don't have an existing plugin you can create one by running

npx create-nx-plugin my-org --pluginName my-plugin

Creating a "Preset" generator

To create our preset inside of our plugin we can run

nx generate @nx/plugin:generator packages/happynrwl/src/generators/preset

{% callout type="warning" title="Double check" %} The word preset is required for the name of this generator {% /callout %}

You should have a similar structure to this:

happynrwl/
	├── e2e
	├── jest.config.js
	├── jest.preset.js
	├── nx.json
	├── package-lock.json
	├── package.json
	├── packages
	│   └── happynrwl
	│       ├── src
	│       │   ├── executors
	│       │   ├── generators
	│       │   │   ├── happynrwl
	│       │   │   └── preset 		// <------------- Here
	│       │   └── index.ts
	├── tools
	└── tsconfig.base.json

After the command is finished, the preset generator is created under the folder named preset. The generator.ts provides an entry point to the generator. This file contains a function that is called to perform manipulations on a tree that represents the file system. The schema.json provides a description of the generator, available options, validation information, and default values.

Here is the sample generator function which you can customize to meet your needs.

export default async function (tree: Tree, options: PresetGeneratorSchema) {
  const normalizedOptions = normalizeOptions(tree, options);
  addProjectConfiguration(tree, normalizedOptions.projectName, {
    root: normalizedOptions.projectRoot,
    projectType: 'application',
    sourceRoot: `${normalizedOptions.projectRoot}/src`,
    targets: {
      exec: {
        executor: 'nx:run-commands',
        options: {
          command: `node ${projectRoot}/src/index.js`,
        },
      },
    },
    tags: normalizedOptions.parsedTags,
  });
  addFiles(tree, normalizedOptions);
  await formatFiles(tree);
}

To get an in-depth guide on customizing/running or debugging your generator see local generators.

Usage

Before you are able to use your newly created preset you must package and publish it to a registry.

After you have published your plugin to a registry you can now use your preset when creating a new workspace

npx create-nx-workspace my-workspace --preset=my-plugin-name