Lesson 0004 · ~12 minutes
One skill: put standardization work in
.moon/tasks, control
who inherits and
how locals merge — so maintenance means one edit, not
N copy-pastes.
You can design a shared lint/test surface for
a monorepo: where the file lives, who gets it
(inheritedBy), and how one app tweaks args without forking
the whole task.
Lesson 1’s monorepo win was
consistent tooling. moon’s answer is not “paste eslint into every
moon.yml.” It is
task inheritance: define once at the workspace level, inherit many or all projects.
.moon/tasks/**/*
moon.* — unique work + merge/override
Classic shared set (from
create a project):
format, lint, test, typecheck — then per-app build /
dev stay local.
inheritedBy
Each file under .moon/tasks can limit itself with
inheritedBy. Omit it (or leave empty) →
all projects inherit that file.
# .moon/tasks/node-frontend-library.yml
inheritedBy:
toolchain: 'node'
stack: 'frontend'
layer: 'library'
tasks:
lint:
command: 'eslint --no-error-on-unmatched-pattern .'
language(s), layer(s), stack(s),
tag(s), toolchain(s), file(s)
tags / toolchains support
and / or / not clauses
Projects declare identity with
language, layer, stack,
tags in their moon.* — inheritance only works
if that metadata is honest.
After global match, a project can filter with
workspace.inheritedTasks:
# apps/special/moon.yml
workspace:
inheritedTasks:
include: ['lint', 'test']
exclude: ['format']
rename:
buildApplication: 'build'
Order is fixed: include → exclude → rename.
Global task build + local task build → one
merged task. Field strategies
(mergeArgs, mergeDeps, mergeInputs,
…):
Prefer command when you want inheritance merges.
script does not merge — it replaces. See
commands vs scripts.
.moon/tasks file location
(tasks config).
/ means workspace-root relative (shared configs).
implicitDeps / implicitInputs on a global
file always attach (e.g. always ^:build) — they ignore
merge options.
Equal-length options. Design-review the inheritance surface.
Best place for a lint task every TypeScript library should share?
A tasks file has
inheritedBy: { toolchain: node, layer: library }. Who
inherits?
Global lint exists. One app needs one extra eslint flag.
Best approach?
Order of workspace.inheritedTasks filters?
Recommended:
Task inheritance
(conditions + merge strategies). Then skim
.moon/tasks config
and keep the
inheritance sheet
open.