@nx-boat-tools/common v0.1.0-alpha.2
Nx Boat Tools - Common
The common
plugin contains executors, generators, and other utilities that can be shared across all of the rest of the boat tools.
💡 How to install
npm install -D @nx-boat-tools/common
# OR
yarn add -D @nx-boat-tools/common
🏃 Executors
chain-execute
Chain execute is an essential building block for the rest of Nx Boat Tools. With more complex projects, the build process can involve many different steps... each of which being their own executor. We see value in grouping these all together into a single "chain" executor so all steps will always be called each time and always in a particular order. Instead of running lint
, buildSrc
, version
, buildDocker
, etc individually, you can instead just run build
and it can run them the same way every time.
Available options:
name | type | default | description |
---|---|---|---|
targets | string[] | [] | An array containing the other executors to call |
preTargets | string[] | [] | An array containing additional targets to call before the main target block |
postTargets | string[] | [] | An array containing additional targets to call after the main target block |
stages | object | The stage definitions for the chain. See Using Stages below. | |
run | string[] | all non-explicit stages | An array what stages to run. See Using Stages below. |
Example:
First let's take a look at the workspace configuration below. It illustrates a build
target that will chain together first the lint
executor and then the buildSrc
executor. If the configuration is specified to be production
then it will then end by also calling the special
executor as well.
//workspace.json
{
//...
"projects": {
"example": {
//...
"targets": {
"setup": {
"executor": "some-setup-executor"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"buildSrc": {
"executor": "@nrwl/node:package"
//...
},
"special": {
"executor": "some-special-executor"
//...
},
"build": {
"executor": "@nx-boat-tools/common:chain-execute",
"options": {
"targets": ["lint", "buildSrc"]
},
"configurations": {
"production": {
"preTargets": ["setup"],
"postTargets": ["special"]
}
}
}
}
}
}
}
To trigger all of our build steps we now just have to call the build
target...
nx build example # will call lint and then buildSrc
# OR
nx run example:build # will also call lint and then buildSrc
# OR, for production...
nx run example:build:production # will call setup first, then lint and buildSrc, and lastly special
Using Stages
Stages allow you to control what parts of a chain get ran apart from configurations. Think of it as, configurations specify how something is built whereas stages specify what is built. The idea is that the stages are defined in the json configuration and then a run argument can be specified when running the chain target. Let's take a look at a sample json config:
//workspace.json
{
//...
"projects": {
"example": {
//...
"targets": {
"clean": {
"executor": "some-clean-executor"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"buildSrc": {
"executor": "@nrwl/node:package"
//...
},
"preSpecial": {
"executor": "some-special-executor"
//...
},
"special": {
"executor": "some-special-executor"
//...
},
"postSpecial": {
"executor": "some-special-executor"
//...
},
"prePackage": {
"executor": "some-package-executor"
//...
},
"package": {
"executor": "some-package-executor"
//...
},
"pastPackage": {
"executor": "some-package-executor"
//...
},
"build": {
"executor": "@nx-boat-tools/common:chain-execute",
"options": {
"preTargets": ["clean"],
"targets": ["buildSrc"],
"postTargets": ["lint"],
"stages": {
"special": {
"targets": ["preSpecial"],
"targets": ["special"],
"postTargets": ["postSpecial"]
},
"package": {
"explicit": true,
"targets": ["prePackage"],
"targets": ["package"],
"postTargets": ["postPackage"]
}
}
}
}
}
}
}
}
When the chain is executed, it will run any preTargets
defined, then any regular targets
, followed by any postTargets
. For each "block", it starts by executing, in order, any "root" targets--that is any targets not inside a stage. It then will execute the targets for each stage in the order the stage is defined, skipping any stages that aren't in the run argument or fail the explicit requirement.
Let's look at some examples of how to use the above config.
nx build example
# This will call the following targets, in order: clean, preSpecial, buildSrc, special, lint, postSpecial
# Note that, since the run arg wasn't specified, the package stage wasn't explicitly requested so it was skipped.
nx build example --run=special
# This is the same as the above command, running in order: clean, preSpecial, buildSrc, special, lint, postSpecial
# Note that, since the run arg didn't include the package stage, it wasn't explicitly requested so it was skipped.
nx build example --run=package
# This will call the following targets, in order: clean, prePackage, buildSrc, package, lint, postPackage
# Note that, since the run arg included the package stage, it was executed. Because the special stage wasn't, it was skipped.
nx build example --run=special,package
# This will call the following targets, in order: clean, preSpecial, prePackage, buildSrc, special, package, lint, postSpecial, postPackage
# Note that, since the run arg included both the special and package stages, they were both executed.
✍️ Generators
chain
The chain
generator adds a chain-execute target to an existing Nx project.
Available options:
name | type | default | description |
---|---|---|---|
name | string | Required. The name of the chain-execute target | |
project | string | Required. The name of the project to add the chain-execute target to. | |
preTargets | string | A comma seperated list of pre targets to include in the chain. | |
targets | string | A comma seperated list of pre targets to include in the chain. | |
postTargets | string | A comma seperated list of post targets to include in the chain. |
Updates to workspace.json
:
The project configuration will be updated as follows:
- If a target with the same name that was specified existed previously and:
- It was not a
chain-execute
target: it will be renamed to have aSrc
suffix. - It was a
chain-execute
target: the targets, preTargets, and postTargets specified will be appended to the end of any existing targets.
- It was not a
- If no target wth the name specified previously existed:
- The target will then be added to the project as a
chain-execute
with the given targets, preTargets, and postTargets.
- The target will then be added to the project as a
🚩 Note: The chain
generator cannot add the actual targets used in the chain. It can only reference them and will not verify that they exist at the time the chain is created.
The following is an example of what's added to the workspace.json
for a project when adding a chain-execute target:
//workspace.json BEFORE
{
//...
"projects": {
"my-app": {
"root": "apps/my-app",
"projectType": "application",
"sourceRoot": "apps/my-app/src",
"targets": {
"build": {
"executor": "@nrwl/node:package"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"package": {
"executor": "some-package-executor"
}
},
"tags": ""
}
}
}
//workspace.json AFTER
{
//...
"projects": {
"my-app": {
"root": "apps/my-app",
"projectType": "application",
"sourceRoot": "apps/my-app/src",
"targets": {
"build": {
"executor": "@nrwl/node:package"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"package": {
"executor": "some-package-executor"
//...
},
"someChain": {
"executor": "@nx-boat-tools/common:chain-execute",
"options": {
"preTargets": ["lint"],
"targets": ["build"],
"postTargets": ["package"]
}
},
"tags": ""
}
}
}
Adding chain
to a project
The following illustrates how to add a chain-execute target to a project:
#Add a chain-execute target named build to a project named my-project
nx g @nx-dev-tools/common:chain build --project=my-project --preTargets=pre1,pre2 --targets=target --postTargets=post1,post2
chain-stage
The chain-stage
generator adds a stage to a chain-execute target for an existing Nx project.
Available options:
name | type | default | description |
---|---|---|---|
name | string | Required. The name of the chain-execute stage | |
chainTarget | string | Required. The name of the chain-execute target | |
project | string | Required. The name of the project containing the chain-execute target. | |
preTargets | string | A comma seperated list of pre targets to include in the stage. | |
targets | string | A comma seperated list of pre targets to include in the stage. | |
postTargets | string | A comma seperated list of post targets to include in the stage. |
Updates to workspace.json
:
The project configuration will be updated as follows:
- If a target with the same name that was specified existed previously and:
- It was not a
chain-execute
target: it will be renamed to have aSrc
suffix. - It was a
chain-execute
target:- The root targets, preTargets, and postTargets will be unaffected
- If no stage with the name specified existed previously:
- The stage will be appended after any existing stages and will contain the targets, preTargets, and postTargets specified
- If a stage with the name specified existed previously:
- The targets, preTargets, and postTargets specified will be appended to the end of any existing targets for the stage.
- It was not a
- If no target wth the name specified previously existed:
- The target will then be added to the project as a
chain-execute
with the given stage containing the targets, preTargets, and postTargets specified.
- The target will then be added to the project as a
🚩 Note: The chain-stage
generator cannot add the actual targets used in the chain. It can only reference them and will not verify that they exist at the time the stage is created.
The following is an example of what's added to the workspace.json
for a project when adding a stage to a chain-execute target:
//workspace.json BEFORE
{
//...
"projects": {
"my-app": {
"root": "apps/my-app",
"projectType": "application",
"sourceRoot": "apps/my-app/src",
"targets": {
"build": {
"executor": "@nrwl/node:package"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"package": {
"executor": "some-package-executor"
},
"pre": {
"executor": "some-executor"
},
"post": {
"executor": "some-executor"
},
"target": {
"executor": "some-executor"
},
"someChain": {
"executor": "@nx-boat-tools/common:chain-execute",
"options": {
"preTargets": ["lint"],
"targets": ["build"],
"postTargets": ["package"]
}
},
"tags": ""
}
}
}
//workspace.json AFTER
{
//...
"projects": {
"my-app": {
"root": "apps/my-app",
"projectType": "application",
"sourceRoot": "apps/my-app/src",
"targets": {
"build": {
"executor": "@nrwl/node:package"
//...
},
"lint": {
"executor": "@nrwl/linter:eslint"
//...
},
"package": {
"executor": "some-package-executor"
//...
},
"pre": {
"executor": "some-executor"
},
"post": {
"executor": "some-executor"
},
"someChain": {
"executor": "@nx-boat-tools/common:chain-execute",
"options": {
"preTargets": ["lint"],
"targets": ["build"],
"postTargets": ["package"],
"stages": {
"src": {
"preTargets": ["pre"],
"targets": ["target"],
"postTargets": ["post"],
}
}
},
"target": {
"executor": "some-executor"
}
},
"tags": ""
}
}
}
Adding chain-stage
to a project
The following illustrates how to add a stage to a chain-execute target for a project:
#Add a stage named src to the build chain-execute target for a project named my-project
nx g @nx-dev-tools/common:chain-stage src --chainTarget=build --project=my-project --preTargets=pre1,pre2 --targets=target --postTargets=post1,post2