[Typescript] Native ES module support
Node.js 13.2.0 introduced support for native ES modules.
This means you can natively run code containing thing like import { Foo } from 'bar'
, use top-level await
and more!
How to unambiguously indicate which type of module you’re authoring
- Files with the
.mjs
extension are treated as native ES modules - Files with the
.cjs
extension are treated as CJS modules
You can also indicate whether .js
files in your project should be treated as ES or CJS modules. In your package.json
you may include a top-level "type"
field with either of the following values
"module"
indicates that.js
files should be run as ES modules"commonjs"
indicates that.js
files should be run as CommonJS
Note that even as of Node 20.8.0, Node.js still assumes .js
files are CommonJS if you specify no "type"
field at all in your "package.json"
// you can import a js file without any extension
// import tools.js file
import * as tools from "./tools"
// If you change tools.js to tool.cjs file
// you need to add extenstion
import * as tools from "./tools.cjs"
TypeScript ES modules
TypeScript 5 supports native modules that follow the established conventions, replacing the j
with a t
(just as is done for .jsx
and .tsx
files). .
.mts
files are for TypeScript ES modules, and generate ES modules as output.cts
files are for TypeSCript CJS modules, and generate CJS modules as output
Given that TypeScript gives you control of the module format in compiled output, you may wonder what the use case is for allowing this degree of flexibility
Imagine you have a large Node project, currently in CJS, and you want to incrementally start converting a few modules at a time. This flexibility would allow you use these two types of modules side-by-side as you incrementally migrate, without attempting a risky automatic conversion that could have ramifications on build output.
Sometimes you also may want different lint rules to apply to different module types, different tsconfig
s, etc… Different file extensions make it easy to apply tools specifically, via global https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html