esm-loader
Node.js loader for loading TypeScript using esbuild.
Features
- Transforms TypeScript to ESM on demand
- Classic Node.js resolution (extensionless & directory imports)
- Cached for performance boost
- Supports Node.js v12.20.0+
- Handles
node:
import prefixes - Resolves
tsconfig.json
paths
Tip:
esm-loader doesn't hook into
require()
calls or transform CommonJS files (.js
in commonjs package,.cjs
,.cts
).Use this with cjs-loader for CommonJS support. Alternatively, use tsx to handle them both automatically.
Install
npm install --save-dev @esbuild-kit/esm-loader
Usage
Pass @esbuild-kit/esm-loader
into the --loader
flag.
node --loader @esbuild-kit/esm-loader ./file.ts
TypeScript configuration
The following properties are used from tsconfig.json
in the working directory:
strict
: Whether to transform to strict modejsx
: Whether to transform JSXWarning: When set to
preserve
, the JSX syntax will remain untransformed. To prevent Node.js from throwing a syntax error, chain another Node.js loader that can transform JSX to JS.jsxFactory
: How to transform JSXjsxFragmentFactory
: How to transform JSX FragmentsjsxImportSource
: Where to import JSX functions fromallowJs
: Whether to apply the tsconfig to JS filespaths
: For resolving aliases
tsconfig.json
path
Custom By default, tsconfig.json
will be detected from the current working directory.
To set a custom path, use the ESBK_TSCONFIG_PATH
environment variable:
ESBK_TSCONFIG_PATH=./path/to/tsconfig.custom.json node --loader @esbuild-kit/esm-loader ./file.ts
Cache
Modules transformations are cached in the system cache directory (TMPDIR
). Transforms are cached by content hash so duplicate dependencies are not re-transformed.
Set environment variable ESBK_DISABLE_CACHE
to a truthy value to disable the cache:
ESBK_DISABLE_CACHE=1 node --loader @esbuild-kit/esm-loader ./file.ts
FAQ
Can it import JSON modules?
Yes. This loader transpiles JSON modules so it's also compatible with named imports.
Can it import ESM modules over network?
Node.js has built-in support for network imports behind the --experimental-network-imports
flag.
You can pass it in with esm-loader
:
node --loader @esbuild-kit/esm-loader --experimental-network-imports ./file.ts
Can it resolve files without an extension?
In ESM, import paths must be explicit (must include file name and extension).
For backwards compatibility, this loader adds support for classic Node resolution for extensions: .js
, .json
, .ts
, .tsx
, .jsx
. Resolving a index
file by the directory name works too.
import file from './file' // -> ./file.js
import directory from './directory' // -> ./directory/index.js
Can it use Node.js's CommonJS resolution algorithm?
ESM import resolution expects explicit import paths, whereas CommonJS resolution expects implicit imports (eg. extensionless & directory imports).
As a result of this change, Node.js changes how it imports a path that matches both a file and directory. In ESM, the directory would be imported, but in CJS, the file would be imported.
To use to the CommonJS resolution algorithm, use the --experimental-specifier-resolution=node
flag.
node --loader @esbuild-kit/esm-loader --experimental-specifier-resolution=node ./file.ts
Related
-
tsx - Node.js runtime powered by esbuild using
@esbuild-kit/cjs-loader
and@esbuild-kit/esm-loader
. -
@esbuild-kit/cjs-loader - TypeScript & ESM to CJS transpiler using the Node.js loader API.