Skip to content

Instantly share code, notes, and snippets.

@cevr
Last active August 23, 2023 15:20
Show Gist options
  • Save cevr/cba0326782883f2da8c380f89faaee56 to your computer and use it in GitHub Desktop.
Save cevr/cba0326782883f2da8c380f89faaee56 to your computer and use it in GitHub Desktop.
ts-morph codefix for esm imports
const path = require('path');
const fs = require('fs');
const { Project, SyntaxKind } = require('ts-morph');
async function main() {
const project = new Project();
const glob = path.join(process.cwd(), './**/(src|test)/**/*.{ts,tsx,js}');
project.addSourceFilesAtPaths(glob);
project.getSourceFiles().forEach(async (sourceFile) => {
const imports = sourceFile.getImportDeclarations();
const expts = sourceFile.getExportDeclarations();
const declarations = imports.concat(expts);
if (!declarations.length) {
return;
}
declarations.forEach((declaration) => {
declaration.getDescendantsOfKind(SyntaxKind.StringLiteral).forEach((stringPath) => {
const text = stringPath.getText().replace(/'/g, '');
if (text.endsWith('.js')) return;
// this represents paths to barrel files eg ('..')
if (text.endsWith('.')) {
stringPath.replaceWithText(`'${text}/index.js'`);
return;
}
if (text.startsWith('.')) {
const newPath = `'${text}.js'`;
const filePath = path.join(sourceFile.getDirectoryPath(), `${text}/index.ts`);
// second check is for js interop
const exists = fs.existsSync(filePath) || fs.existsSync(filePath.replace('.ts', '.js'));
stringPath.replaceWithText(exists ? `'${text}/index.js'` : newPath);
}
});
});
await sourceFile.save();
});
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment