This repository contains a collection of free and open-source codemods/transform scripts to help update Node.js projects.
To run the transform scripts use codemod
command below:
npx codemod <transform> --target <path> [...options]
transform
- name of transform. see available transforms below.path
- directory to transform. defaults to the current directory.
Check out this doc for the full list of available commands.
All Node.js codemods are also available in the Codemod Registry.
Correct TypeScript specifiers
npx codemod node/correct-ts-specifiers
This script transforms import specifiers in source code from the broken state TypeScript's compiler (tsc
) requires into proper ones. This is a one-and-done process, and the updated source code should be committed to your version control (eg git); thereafter, source-code import statements should be authored to be compliant with the ECMAScript (JavaScript) standard.
This is useful when source code is processed by standards-compliant software like Node.js.
This script does not just blindly find & replace file extensions within specifiers: It confirms that the targeted file of replacement specifier actually exists; in cases where there is ambiguity (such as two files with the same basename in the same location but different relevant file extensions), it logs an error, skips that specifier, and continues processing.
This script does not confirm that the targetted module in the replacement contains the exports cited in the import statement. This should not actually ever result in a problem because ambiguous cases are skipped (so if there is a problem, it existed before the migration started). Merely running your source code after the mirgration completes will confirm all is good (if there are problems, node will error, citing exactly where the problems are).
💡 Note
- If you're using
tsconfig
'spaths
, you will need a loader likenodejs-loaders/dev/alias
npm i nodejs-loaders
NODE_OPTIONS="--loader=nodejs-loaders/dev/alias" \
npx codemod node/correct-ts-specifiers
- If you want your source code to still be processessable with
tsc
(for instance, to run type-checking as a lint or test step), you'll need to setallowImportingTsExtensions
. You will need to use a different transpiler to convert your source code to JavaScript (you probably should be doing that anyway).
- no file extension →
.cts
,.mts
,.js
,.ts
,.d.cts
,.d.mts
, or.d.ts
.cjs
→.cts
,.mjs
→.mts
,.js
→.ts
.js
→.d.cts
,.d.mts
, or.d.ts
- Package.json subimports
- tsconfig paths (requires a loader)
Before:
import { URL } from 'node:url';
import { bar } from '@dep/bar';
import { foo } from 'foo';
import { Cat } from './Cat.ts';
import { Dog } from '…/Dog/index.mjs'; // tsconfig paths
import { baseUrl } from '#config.js'; // package.json imports
export { Zed } from './zed';
// should be unchanged
export const makeLink = (path: URL) => (new URL(path, baseUrl)).href;
const nil = await import('./nil.js');
const cat = new Cat('Milo');
const dog = new Dog('Otis');
After:
import { URL } from 'node:url';
import { bar } from '@dep/bar';
import { foo } from 'foo';
import { Cat } from './Cat.ts';
import { Dog } from '…/Dog/index.mts'; // tsconfig paths
import { baseUrl } from '#config.js'; // package.json imports
export type { Zed } from './zed.d.ts';
// should be unchanged
export const makeLink = (path: URL) => (new URL(path, baseUrl)).href;
const nil = await import('./nil.ts');
const cat = new Cat('Milo');
const dog = new Dog('Otis');
- Directory / commonjs-like specifiers¹
import foo from '..'; // where '..' → '../index.ts' (or similar)
¹ Support may be added in a future release
To provide feedback on existing codemods or request new ones open a GitHub issue in this repo.
Feel free to open a PR in this repo to contribute your codemods for Node.js migrations.