mkdist
mkdist copied to clipboard
Declarations not genered to `.mts` and `.cts` files
Environment
mkdist 1.1.2 on Node.js 16.14.2, v18.14.0.
Reproduction
- Have
.mts
and.cts
files in yoursrc
directory. - Run
mkdist -d --ext js
Example project files
// farewells.cts
export function sayGoodbye(name: string) {
console.log(`Goodbye, ${name}!`)
}
// greetings.ts
export function sayHello(name: string) {
console.log(`Hello, ${name}!`)
}
// index.mts
import { sayHello } from './greetings.js'
import { sayGoodbye } from './farewells.cjs'
sayHello('World')
sayGoodbye('World')
StackBlitz example: https://stackblitz.com/edit/node-erv3qh?file=package.json&view=editor (use pnpm build:tsc
to build with TypeScript and pnpm build:mkdist
to build with mkdist
, start
to run ./dist/index.mjs
with Node).
Describe the bug
mkdist
ignores .cts
and .mts
files and copies them as is instead of compiling them to .cjs
(+.d.cts
) and .mjs
(+.d.mts
) respectfully.
Additional context
I could've tried to explain the importance of these file extensions on my own but Bing did a nicer job than me 😢
The
.mjs
and.cjs
extensions are used to specify the module type of a JavaScript file in Node.js 16+. The.mjs
extension indicates that the file is an ECMAScript module (ESM), which is a standard format for modular JavaScript code. The.cjs
extension indicates that the file is a CommonJS module, which is a legacy format that was widely used before ESM was introduced^1.The
.mts
and.cts
extensions are used to specify the module type of a TypeScript file. TypeScript is a superset of JavaScript that adds static types and other features. The.mts
extension indicates that the file is an ESM TypeScript file, which will be emitted as an.mjs
file when compiled to JavaScript. The.cts
extension indicates that the file is a CommonJS TypeScript file, which will be emitted as a.cjs
file when compiled to JavaScript^1.These extensions help Node.js to determine how to load and execute different types of modules without relying on ambiguous heuristics or configuration options^3. They also help developers to write clear and consistent code across different environments.
While this is a nice explanation, it fails to mention a few other important things:
If your file has a .ts
extension, TypeScript always assumes the resulting file will have .js
extension. So if any of the files in your project imports the other file that has .ts
extension, and you use Node16
(NodeNext
) module resolution (which you very much should btw), TypeScript forces you to write import with .js
extension, which is incompatible with mkdist
, unless you force it in .js
extension mode (--ext js
), which you cannot do in environments like nuxt-module-builder
without patching it (which is exactly what I'm struggling with and what I am doing).
The other important thing is that .ts
, .cts
, .mts
on the declaration files imply the existence of the file with the same basename: that is, index.d.ts
says ‘the declaration file is for index.js
’, a.d.cts
is ‘for a.cjs
’, and b.d.mts
is ‘for b.mjs
’. That becomes super important for libraries that ship with wildcard exports
in package.json
, as well helps you as developer to avoid writing types
condition which may or may not lead to a correct declaration file (without types
export condition TypeScript looks for [basename].d.[ts/cts/mts]
).
{
"exports": {
"./locale-data/*": { "import": "./dist/locale-data/*" }
}
}
Logs
No response