---
slug: moon-v1.19
title: moon v1.19 - Improvements to task dependencies, codegen, and more
authors: [milesj]
tags: [task, deps, args, env, codegen, templates, experiments]
image: ./img/moon/v1.19.png
---

In this release, we're introducing some long-awaited and requested improvements.

<!--truncate-->

## Configure args and env vars for task dependencies

This has been a long standing request from the community, and we're happy to finally deliver it.
Starting with v1.19, you can now configure optional command line arguments and environment variables
for each task [`deps`](/docs/config/project#deps) entry. These values will be passed to the task
when it is executed.

Here's an example of what both patterns look like. The `target` field is required when configuring
an object, and both the `args` and `env` fields can be mixed and matched.

```yaml title="moon.yml"
tasks:
  build:
    command: 'vite build'
    deps:
      # Just a target
      - '^:build'

      # With args (string)
      - target: '^:build'
        args: '--mode production'

      # With env vars
      - target: '^:build'
        env:
          NODE_ENV: 'production'

      # With args (array) and env vars
      - target: '^:build'
        args:
          - '--mode'
          - 'production'
        env:
          NODE_ENV: 'production'
```

When using this functionality, there are a few things to understand about its implementation, and
how it affects the rest of the pipeline:

- When extending or inheriting a task and a merger is required, and this task has a dependency with
  a colliding target, the `args` and `env` fields will _NOT_ be deeply merged. Whichever task is
  inherited last will have its `deps` used.
- When multiple dependencies of the same target are ran in the action pipeline, but with differing
  args or env vars, only 1 will run at a time. We try to avoid running them in parallel to avoid
  collisions and corrupting outputs.
- Arguments and environment variables do _NOT_ support tokens.
- If dependencies all write to the same output, cleaning the output is your responsibility, not
  moon's.

## Codegen improvements

Code generation is one of moon's oldest features, and hasn't been improved in quite a while. We felt
the time was right to give it a little love.

### Extend other templates

This has been a [request for over a year](https://github.com/moonrepo/moon/issues/434), and we
finally found the time to put it on the roadmap. Starting with this release, you can now extend
other templates using the [`extends`](/docs/config/template#extends) setting in
[`template.yml`](/docs/config/template), which supports a list of template names.

Templates will be recursively extended from top to bottom, and all files and variables will be
inherited and merged at the top-level.

```yaml title="template.yml"
title: 'npm package'
extends: ['node-common']
```

### Configure a default destination

When you call [`moon generate`](/docs/commands/generate) you must provide a destination directory
for the generated files, or we'll prompt you to provide one. But what if you wanted to standardize
the destination? For example, a package scaffolding template should go to `packages/`. This is now
possible with the optional [`destination`](/docs/config/template#destination) setting in
[`template.yml`](/docs/config/template).

If no destination is provided to `moon generate`, we'll use this default destination.

```yaml title="template.yml"
title: 'npm package'
destination: 'packages/[name | kebab_case]'
variables:
  name:
    type: 'string'
    default: ''
    required: true
    prompt: 'Package name?'
```

:::info

For better interoperability, this setting can also reference variables using `[var]` syntax, and can
also use Tera filters. Learn more about this in the
[code generation documentation](/docs/guides/codegen#interpolation).

:::

## Resolved long-standing experiments

moon has a concept of [experiments](/docs/config/workspace#experiments), where certain features are
gated behind a flag. This allows us to support new and old functionality in parallel, and also allow
users to gradually upgrade when encountering a breaking change. For many months now, we've had 2
experiments running, and have decided on a path forward.

The first is `experiments.interweavedTaskInheritance`, which would inherit global and local tasks in
order, interweaved within each other. The old implementation would inherit global first, then local
second, distinctly grouping them. Since this experiment was introduced, we have not received a
single bug report or issue. This is a good sign that the new behavior is working as expected, and as
such, have decided _to move forward_ with this experiment and make it the new implementation. The
old implementation has been removed entirely.

The second is `experiments.taskOutputBoundaries`, which was rather controversial when introduced.
This experiment would trigger an error anytime a [task's `outputs`][outputs] overlapped within
another [task's `outputs`][outputs]. The reason for this change, is that multiple tasks writing to
the same output location could "corrupt" the expected state, and trigger unexpected results when
hydrating from the cache. However in practice, this restriction has caused more headache and
introduced a steeper learning curve then expected. It also caused problems with
[tasks that extend](/docs/config/project#extends) from another, resulting in the same outputs being
used. Because of this, we've decided _to **not** move forward_ with this experiment, and allow
whatever task outputs you wish (we trust you're smart enough to not shoot yourself in the foot).

## Other changes

View the [official release](https://github.com/moonrepo/moon/releases/tag/v1.19.0) for a full list
of changes.

- Updated proto to v0.26 (from v0.25), which includes a new shims implementation.
- Updated VS Code extension to support multiple VS Code workspace folders.

[outputs]: /docs/config/project#outputs
