# Publish Release

> Guidelines for building, packaging, and publishing projects.

Guidelines for building, packaging, and publishing projects. Use when modifying publishConfig, resolvePluginService, package.json main/types/exports for publishable libraries, checking dist folder generation, debugging package resolution for released artifacts, or rehearsing a publish against the local Verdaccio registry.

- Page: https://ss33.ai/skills/organizzolini/publish-release-26808703541
- Publisher: organizzolini
- Category: [Software Development](https://ss33.ai/skills/category/software-development-t44z8z) › [DevOps & cloud](https://ss33.ai/skills/category/software-development-t44z8z/devops-and-cloud-unkt50)
- License: MIT
- Source: https://github.com/organizzolini/codebase/blob/dfcbcaf78074c8a6e2b449048e15cf63cd8c49ce/.agents/skills/publish-release/SKILL.md

## Skill

SKILL.md: https://ss33.ai/api/v1/ss33/download/organizzolini/publish-release-26808703541

# Publish and Release

## Build Output and Publishing

- **Every build writes into its own project's `dist/`** — `projects/logging/dist`,
  `projects/caelundas/caelundas-cli/dist` — never a top-level one. `dist` is already
  gitignored and in the folder-structure rule's `ignorePatterns`.
- **`projects/configuration/tsconfig.json` sets `declaration: true`**, so every build
  emits `.d.ts` beside its `.js`. Turning it off silently removes the types a
  published package ships.
- **A package's `main`, `types`, and `exports` point at TypeScript sources**, and
  `publishConfig` carries the emitted `dist/` paths beside them — pnpm applies
  those at publish time, so one manifest serves the workspace and a published
  consumer. **Verify a change here by packing, not by reading:** `pnpm pack` in
  the package, then inspect the tarball's `package.json`.
- **`files` must name `dist`.** Without it, packing falls back to the ignore
  files and the tarball ships no build output at all.
- **A plugin entry's `resolvePluginService` must stay a static import.** A
  dynamic `import()` escapes the `@swc-node/register` require hook into Node's
  own ESM resolver, and `nx g` then fails with `Cannot find module
  './modules/plugin/plugin-context.utilities'`.

Why the manifest fields stay on sources, which `publishConfig` fields pnpm
actually applies, and why shrinking the Nx plugin closure buys nothing is
[ADR 0009](../../documentation/adr/0009-keep-manifest-fields-on-typescript-sources.md). **Do
not point `main` or `exports` at `dist/`** — it deadlocks the plugin graph load
and breaks `fallow-dead-code` and `vitest`.

## Rehearsing a Publish

**Before trusting a publish change, rehearse it** against the local registry:
publish the packed tarball to Verdaccio and import it from a project outside
the workspace. A naive rehearsal reaches the real npmjs.org registry, so follow
[local-registry-rehearsal.md](local-registry-rehearsal.md) step by step.
