chant dev local
Synopsis
Section titled “Synopsis”chant dev local <chant-dir> [--with <package>]... [--build '<command>'] [--json]chant dev local --reset [--build '<command>'] [--json]chant dev bundle-check [<package-dir>] [--json]Run in the root of a product, the directory with its package.json and package-lock.json.
What dev local does
Section titled “What dev local does”- Reads the
@intentius/chant*packages named in the product’s rootpackage.jsonand in each workspace package’spackage.json, adds each--withpackage (for example a lexicon that only an image installs), and adds the chant packages those depend on. - Runs
npm ciin the checkout when itspackage-lock.jsonchanged since the last run. The stamp isnode_modules/.chant-dev-localin the checkout. - Runs
npm packfor each package in the checkout, in an order where each package comes after the packages it builds against. Each package’sprepackbuilds it. The tarballs go to.chant-local/in the product, one fixed name per package (intentius-chant.tgz,intentius-chant-lexicon-k8s.tgz), so a later run replaces them. The product should list.chant-local/in.gitignore. - Points every
package.jsonof the product at the tarballs and runsnpm install --no-save --legacy-peer-deps. The root also gets every tarball as a devDependency, so a package that only a lexicon reaches is replaced too. Afterwards it writes eachpackage.jsonandpackage-lock.jsonback byte for byte, including when the install fails, sogit statusshows no change. Copies of the files are kept in.chant-local/manifests/. - Adds a
chantLocalfield,{ "commit": "<sha>[+dirty]", "dir": "<checkout>" }, to thepackage.jsonof every installed copy, wherever npm put it in the tree. It fails if a copy has a version other than the checkout’s. - Runs
--buildas a shell command in the product root (just build-cli,npm run build). - Checks the bundle of every package that declares
chantBundleCheck, and printschant commit: <sha>last.
--reset runs npm ci and then checks that every installed chant package is the version package-lock.json pins and has no chantLocal mark. After that it runs --build and the bundle check the same way.
The command does not create or move a worktree. Pass the checkout you want, for example a worktree at chant’s origin/main:
git -C ../chant worktree add --detach ../chant-local origin/mainnpx chant dev local ../chant-local --build 'just build-cli'npx chant dev local --reset --build 'just build-cli'A product whose pinned chant predates dev local (LOCAL_CHANT_FLOOR) can run the checkout’s own CLI instead: ../chant-local/packages/core/bin/chant dev local ../chant-local.
Exit codes: 0 when everything passed, 1 when the pack, install, build or bundle check failed, 2 for a usage error.
Bundle check
Section titled “Bundle check”chant dev bundle-check checks one package (<package-dir>), or every package of the product in the current directory that declares chantBundleCheck in its package.json:
{ "chantBundleCheck": { "bundle": "dist/terragucci.mjs", "maxBytes": 2359296, "needs": ["@intentius/chant"], "optional": ["@intentius/tsad-reference", "@cdktn/hcl2json"], "metafile": "../../node_modules/.cache/terragucci/metafile.json", "deny": [{ "pattern": "^typescript/", "what": "the TypeScript compiler" }] }}Paths are relative to the package. The check fails when:
- the bundle imports something other than Node’s modules, its runtime dependencies and the
optionalpackages; - a chant import (core or a lexicon, with any subpath) is not served by the installed package as compiled JS under Node’s
importcondition. Plain Node does not load TypeScript fromnode_modules; - a runtime dependency is not imported by the bundle and not listed in
needs, or a package inneedsis not a runtime dependency; - an
@intentius/chant*dependency or devDependency is not the root’s@intentius/chantpin, or that pin is not an exact version; - an installed chant package is not the pin and has no
chantLocalmark; - the bundle is over
maxBytes, or thenpm pack --dry-runtarball is overmaxPackBytes; - an input in the esbuild
metafilematches adenypattern. The pattern is matched against the input path with everything up to its lastnode_modules/removed.
From a build script
Section titled “From a build script”@intentius/chant/bundle-check imports only Node’s modules, so a product’s esbuild script can use it directly:
import { chantExternalPlugin, chantRuntimeTarget, checkBundle } from "@intentius/chant/bundle-check";
await esbuild.build({ /* ... */ plugins: [chantExternalPlugin(pkgDir)] });chantExternalPlugin(pkgDir) leaves external each chant import that the chant installed for pkgDir serves as compiled JS, and lets esbuild bundle the rest. chantRuntimeTarget(specifier, fromDir) returns the file Node would load for an import, or undefined. @intentius/chant/local-chant exports installLocalChant and resetLocalChant, the functions behind dev local.