.moon/toolchain.yml
The .moon/toolchain.yml
file configures the toolchain and the workspace development environment.
This file is optional.
Managing tool version's within the toolchain ensures a deterministic environment across any machine (whether a developer, CI, or production machine).
$schema: 'https://moonrepo.dev/schemas/toolchain.json'
extends
Defines an external .moon/toolchain.yml
to extend and inherit settings from. Perfect for
reusability and sharing configuration across repositories and projects. When defined, this setting
must be an HTTPS URL or relative file system path that points to a valid YAML document!
extends: 'https://raw.githubusercontent.com/organization/repository/master/.moon/toolchain.yml'
Settings will be merged recursively for blocks, with values defined in the local configuration taking precedence over those defined in the extended configuration.
JavaScript
deno
Enables and configures Deno.
depsFile
Path to the
dependencies file
that's used for re-exporting external libraries. This file is heavily used in hashing and caching
related scenarios. Defaults to deps.ts
.
deno:
depsFile: 'src/deps.ts'
lockfile
Enables lockfile (deno.lock
) support for Deno dependencies. When enabled, will run
deno cache
as part of the dependency
installation action. Defaults to false
.
deno:
lockfile: true
node
Enables and configures Node.js.
version
Defines the explicit Node.js version to use. We require an explicit and semantic major, minor, and patch version, to ensure the same environment is used across every machine. Ranges are not supported.
If this field is not defined, the global node
binary will be used.
node:
version: '16.13.0'
Version can also be defined with
.prototools
or be overridden with theMOON_NODE_VERSION
environment variable.
packageManager
Defines which package manager to utilize. Supports npm
(default), pnpm
, or yarn
.
node:
packageManager: 'yarn'
npm
, pnpm
, yarn
Optional fields for defining package manager specific configuration. The chosen setting is dependent
on the value of node.packageManager
. If these settings are not defined, the
latest version of the active package manager will be used (when applicable).
version
The version
setting defines the explicit package manager version to use. We require an explicit
major, minor, and patch version, to ensure the same environment is used across every machine.
If this field is not defined, the global npm
, pnpm
, and yarn
binaries will be used.
node:
packageManager: 'yarn'
yarn:
version: '3.1.0'
Version can also be defined with
.prototools
or be overridden with theMOON_NPM_VERSION
,MOON_PNPM_VERSION
, orMOON_YARN_VERSION
environment variables.
yarn
plugins
A list of plugins that will automatically be imported using yarn plugin import
(Yarn 2+ only). For
performance reasons, plugins will only be imported when the Yarn version changes.
node:
packageManager: 'yarn'
yarn:
version: '3.1.0'
plugins:
- 'interactive-tools'
- 'workspace-tools'
addEnginesConstraint
Injects the currently configured Node.js version as an engines
constraint to the root
package.json
field. Defaults to true
.
node:
addEnginesConstraint: true
For example, say our Node.js version is "16.15.0", and when we execute a run process through the
moon
binary, it will update the root package.json
with the below. We pin a fixed version to
ensure other Node.js processes outside of our toolchain are utilizing the same version.
{
// ...
"engines": {
"node": "16.15.0"
}
}
binExecArgs
Additional command line arguments to pass to the node
binary
when it's being executed by running a target. This will apply arguments to all Node.js based
targets, and cannot be changed on a per target basis.
node:
binExecArgs:
- '--preserve-symlinks'
- '--loader'
- '@boost/module/loader'
dedupeOnLockfileChange
Will dedupe dependencies after they have been installed, added, removing, or changed in any way, in
an effort to keep the workspace tree as clean and lean as possible. Defaults to true
.
node:
dedupeOnLockfileChange: true
dependencyVersionFormat
When syncing project dependencies, customize the format that will be used for the dependency version range. The following formats are supported (but use the one most applicable to your chosen package manager):
file
- Usesfile:../relative/path
and copies package contents.link
- Useslink:../relative/path
and symlinks package contents.star
- Uses an explicit*
.version
- Uses the explicit version from the dependent project'spackage.json
, e.g., "1.2.3".version-caret
- Uses the version from the dependent project'spackage.json
as a caret range, e.g., "^1.2.3".version-tilde
- Uses the version from the dependent project'spackage.json
as a tilde range, e.g., "~1.2.3".workspace
(default) - Usesworkspace:*
, which resolves to "1.2.3". Requires package workspaces.workspace-caret
- Usesworkspace:^
, which resolves to "^1.2.3". Requires package workspaces.workspace-tilde
- Usesworkspace:~
, which resolves to "~1.2.3". Requires package workspaces.
node:
dependencyVersionFormat: 'link'
This setting does not apply to peer dependencies, as they will always use a format of
^<major>.0.0
.
inferTasksFromScripts
Will infer and automatically create tasks from package.json
scripts. Defaults
to false
.
This requires the project's language to be "javascript" or "typescript", a
package.json
to exist in the project, and will take the following into account:
- Script names will be converted to kebab-case, and will become the task ID.
- Pre, post, and life cycle hooks are ignored.
- Tasks defined in
.moon/tasks.yml
ormoon.yml
take precedence over scripts of the same name.
To verify inferred tasks, run moon project <id>
(pass --json
to view raw
config and options). Tasks that are inferred will have their command and args set to
moon node run-script
.
node:
inferTasksFromScripts: true
This implementation shares functionality with
moon migrate from-package-json
, and will attempt to
determine environment variables, outputs, CI options, and more! Be aware of these when utilizing
this feature, especially in regards to runInCI
, as it may be inaccurate!
syncProjectWorkspaceDependencies
Will sync a project's dependsOn
setting as normal dependencies within the
project's package.json
. If a dependent project does not have a package.json
, or if a dependency
of the same name has an explicit version already defined, the sync will be skipped. Defaults to
true
.
node:
syncProjectWorkspaceDependencies: true
A quick example on how this works. Given the following dependsOn
:
dependsOn:
- 'designSystem'
- 'reactHooks'
Would result in the following dependencies
within a project's package.json
. The version format
can be customized with node.dependencyVersionFormat
.
{
// ...
"dependencies": {
"@company/design-system": "workspace:*",
"@company/react-hooks": "workspace:*"
// ...
}
}
syncVersionManagerConfig
Will sync the currently configured Node.js version to a 3rd-party version manager's
config/rc file. Supports "nodenv" (syncs to .node-version
), "nvm" (syncs to .nvmrc
), or none
(default).
node:
syncVersionManagerConfig: 'nvm'
This is a special setting that ensure other Node.js processes outside of our toolchain are utilizing the same version, which is a very common practice when managing dependencies.
typescript
Dictates how moon interacts with and utilizes TypeScript within the workspace. This field is optional and is undefined by default. Define it to enable TypeScript support.
createMissingConfig
When syncing project references and a depended on project does not have
a tsconfig.json
, automatically create one. Defaults to true
.
typescript:
createMissingConfig: true
projectConfigFileName
Defines the file name of the tsconfig.json
found in the project root. We utilize this setting when
syncing project references between projects. Defaults to tsconfig.json
.
typescript:
projectConfigFileName: 'tsconfig.build.json'
rootConfigFileName
Defines the file name of the tsconfig.json
found in the workspace root. We utilize this setting
when syncing projects as references. Defaults to tsconfig.json
.
typescript:
rootConfigFileName: 'tsconfig.projects.json'
rootOptionsConfigFileName
Defines the file name of the config file found in the workspace root that houses shared compiler
options. Defaults to tsconfig.options.json
. This setting is used in the following scenarios:
- When creating a
tsconfig.json
for a project, sets theextends
field to this value.
typescript:
rootOptionsConfigFileName: 'tsconfig.base.json'
routeOutDirToCache
Updates the outDir
compiler option in each project's tsconfig.json
to
route to moon's cache folder. This is useful when using project references and wanting to keep all
the compiled .d.ts
files out of the project folder. Defaults to false
.
typescript:
routeOutDirToCache: true
As a demonstration, if we had an npm package located at "packages/components", the outDir
compiler
option will be re-routed to the following when syncing.
{
// ...
"compilerOptions": {
// ...
"outDir": "../../.moon/cache/types/packages/components"
}
}
syncProjectReferences
Will sync a project's dependencies (when applicable) as project
references within that project's tsconfig.json
, and the workspace root tsconfig.json
. Defaults
to true
when the parent typescript
setting is defined, otherwise false
.
typescript:
syncProjectReferences: true
A quick example on how this works. Given the following dependsOn
:
dependsOn:
- 'designSystem'
- 'reactHooks'
Would result in the following references
within both tsconfig.json
s.
{
// ...
"references": [
// ...
{ "path": "../../design-system" },
{ "path": "../../react-hooks" }
]
}
This setting assumes you're using the file organization as defined in our official TypeScript project references in-depth guide.
syncProjectReferencesToPaths
Will sync a project's tsconfig.json
project references to the paths
compiler option, using the referenced project's package.json
name. This is useful for mapping
import aliases to their source code. Defaults to false
.
typescript:
syncProjectReferencesToPaths: true
As a demonstration, if we had a reference to a shared npm package with the name @brand/components
,
the paths
compiler option would be updated to the following when syncing. The index file may exist
in a src
folder, or the root of the package.
{
// ...
"compilerOptions": {
// ...
"paths": {
"@brand/components": ["../shared/components/src/index.ts"],
"@brand/components/*": ["../shared/components/src/*"]
}
},
"references": [
{
"path": "../shared/components"
}
]
}
This setting runs after
syncProjectReferences
and will inherit any synced references from that setting.
Rust
rust
v1.5.0
Enables and configures Rust.
version
Defines the explicit Rust toolchain version/channel to use. We require an explicit and semantic major, minor, and patch version, to ensure the same environment is used across every machine.
If this field is not defined, the global cargo
, rustc
, and other binaries will be used.
rust:
version: '1.69.0'
Version can also be defined with
.prototools
.
bins
A list of crates/binaries (with optional versions) to install into Cargo (~/.cargo/bin
), and make
them available to the cargo
command. Binaries will be installed with
cargo-binstall
in an effort to reduce build and
compilation times.
rust:
bins:
- 'cargo-make@0.35.0'
- 'cargo-nextest'
Binaries that have been installed into Cargo can be referenced from task commands:
tasks:
test:
command: 'nextest run --workspace'
syncToolchainConfig
Will automatically sync the currently configured Rust version
to the
toolchain.channel
field in rust-toolchain.toml
, relative to the root Cargo.lock
. If the file
does not exist, it will be created.
This is a special setting that ensures other Rust/Cargo processes outside of our toolchain are utilizing the same version, which is a very common practice.
rust:
version: '1.69.0'
syncToolchainConfig: true
To demonstrate this, the settings above would sync the following file:
[toolchain]
channel = "1.69.0"