Summary
Published packages are ESM ("type": "module" in 52 of 53) but their emitted relative specifiers have no file extensions, so native Node ESM cannot resolve them. Consumers must go through a bundler or transpiler.
This is a deliberate consequence of moduleResolution: "bundler" in packages/preset-typescript/base.json, not a regression. Filing it so the limitation is documented rather than rediscovered.
Reproduction
packages/artifacts/dist/index.js:
export { ArtifactMetadata, ArtifactsSliceConfig, ArtifactType, } from './ArtifactsSliceConfig';
Node's ESM resolver does not append .js, so importing this from bare node fails on the nested specifier. It is package-wide, not specific to any entry point:
| package |
extensionless relative specifiers in dist/index.js |
ai-core |
49 |
room-store |
7 |
artifacts |
6 |
Impact
Low today, as far as I can tell:
- No package in the repo declares a
bin, so nothing here runs under native Node.
- Bundler and transpiler consumers are unaffected — Vite, esbuild, and
tsc with paths all resolve extensionless specifiers fine.
It becomes a problem for a consumer that wants to import a React-free entry (@sqlrooms/artifacts/config, @sqlrooms/artifacts/ai) from a plain Node script — a migration, a server-side tool, a CLI. Those entries are dependency-light on purpose, so Node is a reasonable thing to expect, and it is the first thing someone will try.
Options
- Leave as is, documented.
moduleResolution: "bundler" is coherent for a component library, and there is no demonstrated consumer. Fixing costs a lot of churn for no current beneficiary.
NodeNext + explicit .js extensions on every relative specifier across all packages. Correct, but a large mechanical change with real regression surface.
- Bundle each package's entry points so the emitted files have no unresolved relative specifiers. Contains the change to build config, but changes the build tool for every package.
My suggestion is (1) until someone actually needs it, hence this issue rather than a PR. Worth noting that (2) and (3) also do not fix the separate problem of the repo's own Jest suites being unable to load workspace dist — that one is about ESM output not being transformed, and is tracked separately.
Context
Came up while reviewing #866, which adds a React-free ./config subpath to @sqlrooms/artifacts. That PR's docs and README now state the bundler-only scope explicitly so the new entry does not imply native Node support.
Summary
Published packages are ESM (
"type": "module"in 52 of 53) but their emitted relative specifiers have no file extensions, so native Node ESM cannot resolve them. Consumers must go through a bundler or transpiler.This is a deliberate consequence of
moduleResolution: "bundler"inpackages/preset-typescript/base.json, not a regression. Filing it so the limitation is documented rather than rediscovered.Reproduction
packages/artifacts/dist/index.js:Node's ESM resolver does not append
.js, so importing this from barenodefails on the nested specifier. It is package-wide, not specific to any entry point:dist/index.jsai-coreroom-storeartifactsImpact
Low today, as far as I can tell:
bin, so nothing here runs under native Node.tscwithpathsall resolve extensionless specifiers fine.It becomes a problem for a consumer that wants to import a React-free entry (
@sqlrooms/artifacts/config,@sqlrooms/artifacts/ai) from a plain Node script — a migration, a server-side tool, a CLI. Those entries are dependency-light on purpose, so Node is a reasonable thing to expect, and it is the first thing someone will try.Options
moduleResolution: "bundler"is coherent for a component library, and there is no demonstrated consumer. Fixing costs a lot of churn for no current beneficiary.NodeNext+ explicit.jsextensions on every relative specifier across all packages. Correct, but a large mechanical change with real regression surface.My suggestion is (1) until someone actually needs it, hence this issue rather than a PR. Worth noting that (2) and (3) also do not fix the separate problem of the repo's own Jest suites being unable to load workspace
dist— that one is about ESM output not being transformed, and is tracked separately.Context
Came up while reviewing #866, which adds a React-free
./configsubpath to@sqlrooms/artifacts. That PR's docs and README now state the bundler-only scope explicitly so the new entry does not imply native Node support.