moon v0.16 - Per-project tool versions and TypeScript improvements
With this release, we've landed a long standing request of supporting project-level overrides for tools configured in the workspace, as well as some quality of life improvements for TypeScript.
Per-project tool version overrides
Since moons inception, our toolchain has only supported a single version of a tool (Node.js), as we wanted to embrace the single version policy and encourage all consumers to keep their tooling version consistent across all projects for reliability. While this works flawlessly, it's not entirely realistic, as many companies have legacy projects that are stuck on older versions for whatever reason, and integrating them into moon was rather difficult.
Well no more! We've refactored our toolchain to support tool overrides on a project-by-project
basis. Since we only support Node.js at the moment, this can be achieved with the new
workspace.node.version
setting in
moon.yml
.
For example, if your workspace Node.js version is configured as v18.
node:
version: '18.0.0'
You can now override this version at the project-level. Let's go with v14.
workspace:
node:
version: '14.0.0'
When running a task from a project with overrides, the toolchain will download, install, and configure the new version behind the scenes. This new version will then be used to install dependencies and execute the tasks commands.
Although we now support overriding the tool version, the workspace configured package manager (
node.packageManager
) and associated version cannot be overridden. This is unlikely to change.
Per-project dependency installs
Because of the toolchain refactor above, we now support per-project dependency installs as a welcome side-effect. This is a necessary step in supporting new languages, especially for those that don't install dependencies in the workspace for all projects, and must install them per project.
This also means that moon now supports non-package.json
workspaces! If your repository is not
using npm/pnpm/yarn workspaces, or a project is not listed within the workspaces glob list,
dependencies will be installed within the project.
TypeScript improvements
Routing outDir
to the cache
A requirement for using project references is that each project must compile declarations (.d.ts
)
so that consumers/dependents can resolve type information. While this makes sense, it becomes rather
unfortunate as each project folder is now littered with the declaration outputs, which are typically
gitignored.
To improve this experience, we're introducing a new setting
typescript.routeOutDirToCache
, that will update the
outDir
compiler option of all projects to route to moon's cache directory (which should already
be gitignored). This will standardize the use of project references for the entire repository.
For example, a project at "packages/components" will route to the following output directory:
{
// ...
"compilerOptions": {
// ...
"outDir": "../../.moon/cache/types/packages/components"
}
}
If you require declarations to live within the project, for example an npm package that ships types, you should introduce an additional configuration to handle this, like
tsconfig.build.json
.
Mapping project references as paths
moon automatically keeps TypeScript project references in sync with the
typescript.syncProjectReferences
setting, which
is great, but we can take it further. With the new
typescript.syncProjectReferencesToPaths
setting, project references (either synced or explicitly defined) will also be mapped to the
paths
compiler option, automating the list of import aliases.
For example, if a reference has the package name @brand/components
, the paths
will be mapped
with:
{
// ...
"compilerOptions": {
// ...
"paths": {
"@brand/components": ["../shared/components/src/index.ts"],
"@brand/components/*": ["../shared/components/src/*"]
}
},
"references": [
{
"path": "../shared/components"
}
]
}
Other changes
View the official release for a full list of changes.
- Template files can now be suffixed with
.tera
or.twig
for syntax highlighting. - We now display more commands and information when running tasks.
- Declare implicit task dependencies with a new
runner.implicitDeps
setting.
What's next?
Expect the following in the v0.17 release!
- Webhooks for important pipeline events (for real this time)!
- YAML anchors and references in config files.
- And many more...