Repository navigation
Conversation
The 8 packages published raw .ts, which plain Node (scripts, Playwright,
Node servers, Next without transpilePackages) can't import from
node_modules. Each package now compiles file-for-file with the TypeScript 7
native compiler: every src/**/*.ts(x) becomes one dist/**/*.js plus .d.ts
and maps, imports left as imports, so module identity and singletons are
exactly the source's (no bundle, no inlined second copy).
- tsconfig.build.json per package (rootDir src, outDir dist, NodeNext,
rewriteRelativeImportExtensions, declaration + maps, tests excluded);
relative imports in emitted files now carry .ts extensions.
- exports: { types, source, default } per subpath (node/default order kept
for /protocol/storage/fs); files ship dist + src; main/types point at dist.
- deco bin runs dist/v8/cli/main.js; tsx is no longer a runtime dependency.
typescript stays the 5.x peer that `deco schema` loads (TS 7 has no JS API);
builds use the `typescript7` alias through scripts/tsc.mjs.
- `deco schema` names a compiled .d.ts after its source (declaration map),
so schema definition ids are the same from dist or source.
- Workspace: root prepare builds on install; type-checks and vitest resolve
@decocms/* through the "source" condition; tests/globalSetup.ts rebuilds
blocks' dist for the CLI tests that spawn the bin.
- Release prepareCmd builds after the version sync; each package's prepack
rebuilds. New CI workflow: typecheck, build, plain-Node import of every
built export.
- nextjs-smoke drops transpilePackages. CLAUDE.md documents the build rule.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…servability conformance fixture The v7 removal dropped it from dependencies, but the telemetry docs' snippet fixture still imports it for typechecking, so a fresh install failed observability.test.ts. Dev-only; knip ignores it since only the fixture uses it. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…ot to decocms-blocks The apps resolve @decocms/blocks/* through its dist types, so a parallel --filter build raced blocks' tsc and failed with TS2307 in prepare. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The 8 publishable packages (
@decocms/blocks, plus@decocms/apps-{shopify,vtex,wake,magento,algolia,resend,sfmc-personalization}) publish raw.ts. Plain Node can't import.tsfromnode_modules, so these can't use them without a TypeScript loader: Playwright, scripts, Node servers, and Next withouttranspilePackages. Studio's e2e fixture currently needstsxregister()just to load@decocms/blocks/protocol.Approach: compile file by file, no bundler
tsconfig.build.json(extendstsconfig.build.base.json:rootDir src,outDir dist,module/moduleResolution: NodeNext,rewriteRelativeImportExtensions,declaration+declarationMap+sourceMap). Tests and fixtures are excluded.typescript7, an npm alias of[email protected]), run throughscripts/tsc.mjs. The plaintypescriptname stays on 5.x because TS 7 has no JS compiler API, anddeco schema(plus Next type-checks and a few conformance tests) loadtypescriptthrough that API.--clean distruns before every build, so a deleted or renamed source never leaves stale output behind.src/x.tsbecomes exactly onedist/x.js, and relative imports are rewritten from./x.tsto./x.js. The module graph indistmatches the source graph edge for edge. No file is inlined into another, so a registry or singleton module loads once, which is what CLAUDE.md requires after the tsup incident. On top of that,createCMSkeys its instance onSymbol.foronglobalThis, so even two forced copies ofcms.jsreturn the same CMS.src, so the schema ids thatdeco schemabuilds from types stay@decocms/blocks/src/v8/types.ts@Seoinstead ofdist/...d.ts.Exports and conditions
{ "types": "./dist/….d.ts", "source": "./src/….ts", "default": "./dist/….js" }.sourceis for tools that compile TypeScript and want.ts./protocol/storage/fsstill listsnodebeforedefault, and Workers/browser conditions resolve tounsupported.js, as the original map did.filesshipsdistplussrc, because thesourcecondition and the declaration maps both point intosrc. Tests are not shipped.customConditions: ["source"]) and vitest resolve thesourcecondition, so typechecks and tests run on.tswith no build step.examples/nextjs-smokeconsumes the builtdistlike any npm package, andbun installbuilds the workspace.decobin without tsxbin/deco.jsimportsdist/v8/cli/main.jsdirectly, so plain Node, Bun andnpxrun it with no loader.tsxis no longer a runtime dependency.typescriptstays an optional peer, and onlydeco schemaloads it, when it runs.Release and CI
prepareCmdissync-versions.mjs && bun run buildbefore eachnpm publish. Each package also has"prepack": "npm run build".node.@opentelemetry/apiis now a devDependency ofpackages/blocks, and knip ignores it. The v7 removal dropped it, but the telemetry docs' snippet fixture still imports it, soobservability.test.tsfailed on a fresh install.Verification
I packed the 8 packages the way the release does (
sync-versionsat 8.99.0,bun run build,npm pack) and installed the tarballs into a clean folder outside the repo. The checks below used Node 26.9.@decocms/blocksand its subpaths/analytics,/cli,/fetch,/secrets,/protocol,/protocol/keys,/protocol/server,/protocol/storage/fsand/protocol/conformance, the 7 app clients, and@decocms/apps-wake/storefrontand/storefront/types.createCMSplusforRelease().resolve("Card")resolves a nested reference. A missing block returnsNOT_FOUND.@decocmsfiles.dist/v8/cms.jsloaded exactly once, and nosrc/*.tsfile loaded. With two forced copies ofcms.js, bothcreateCMScalls return the same instance.--conditions=workerdorbrowserresolves todist. esbuild with the Wrangler set (workerd,worker,browser,--platform=browser) picksprotocol/storage/fs/unsupported.js.--platform=nodepicks the real fs storage.npx deco --helpworks. On a fixture site,deco schema,deco contentanddeco checkall succeed (2 blocks saved, 0 errors). The schema ids point atsrc/*.ts.--strict --skipLibCheck falseunder NodeNext and under Bundler, on TS 5.9.3 and on TS 7.0.2. It includes a@ts-expect-errorline that fails if the types come through asany.blocks-protocole2e fixture without tsx installed.runConformanceagainstcreateContentHandler(createFsStorage(...))gave 33 passed, 0 failed, 14 skipped.bun install --frozen-lockfile,bun run typecheck,bun run build,bun run test(1740 passed, 104 skipped) andbun run checkall pass.Things to know, none caused by this PR: running
npm packwithoutsync-versionsleavesworkspace:*in the app tarballs, and the release always runs sync first. Running Node with--conditions=sourceagainstnode_modulesfails withERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING, which is expected.Stack: v8 ← 01 ← … ← 12 ← 13 ← 14
🤖 Generated with Claude Code
https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Summary by cubic
The 8 publishable packages (
@decocms/blocksand the 7@decocms/apps-*) now publish compiled JavaScript instead of raw.ts, so plain Node (scripts, Playwright, Node servers, Next withouttranspilePackages) can import them fromnode_moduleswithout a TypeScript loader.Build and publish
src/x.tsbecomes onedist/x.jsplus.d.tsand maps, with relative imports rewritten to.js, so module boundaries (and the registry singleton) match the source exactly.{ types, source, default };filesshipsdistandsrc(tests excluded), and declaration maps point back tosrcsodeco schemaids keep theirsrc/...paths.@decocms/blocksbefore the apps, which resolve it through its dist types; a parallel build raced blocks'tscand failed inprepare.prepackand the releaseprepareCmdbuild before each publish; new CI type-checks, builds, and imports every built export with plain Node.nextjs-smokeexample dropstranspilePackages.CLI and tooling
bin/deco.jsnow runs the compileddist/v8/cli/main.js, sodecoworks under plain Node, Bun, andnpxwith no loader;tsxis no longer a runtime dependency.typescript7alias);typescriptstays on 5.x becausedeco schema, Next type-checks, and a few conformance tests load it through its JS compiler API, which TypeScript 7 lacks.sourcecondition, so local work keeps running.tswithout a prior build.@opentelemetry/apias a devDependency ofpackages/blocksto fix a fresh-installobservability.test.tsfailure.Written for commit 013607c. Summary will update on new commits.