Last active
May 5, 2024 13:30
-
-
Save rigwild/2be7c5ccb6d21ab01fc1c47e1f565518 to your computer and use it in GitHub Desktop.
Script to recursively convert all imports from a directory to ESM compatible imports with `.js` file extensions, will also replace directory imports with direct `/index.js` imports.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// @ts-check | |
/** | |
* This script is used to fix imports in the generated typechain types. | |
* | |
* The generated typechain types are not compatible with ESM imports. | |
* They use directory imports and imports without file extensions. | |
* | |
* Usage: | |
* | |
* npx hardhat compile | |
* node scripts/renameImportsForEsmSupport.js | |
*/ | |
import * as fs from 'fs' | |
import * as path from 'path' | |
import * as url from 'url' | |
const __filename = url.fileURLToPath(import.meta.url) | |
const __dirname = path.dirname(__filename) | |
const directoryPath = path.join(__dirname, 'typechain-types') | |
const fixImports = filePath => { | |
console.log(`Fixing imports for file: ${filePath}`) | |
let data = fs.readFileSync(filePath, 'utf8') | |
const allMatches = data.match(/from "(\..*?)(?<!\.js)"/g) | |
if (!allMatches) return | |
// Try to add `.ts` to the import and check if it is a valid file | |
// If it is a valid file, append `.js` to the import | |
// else, append `/index.js` to the import | |
let result = data | |
for (const match of allMatches) { | |
const importPath = match.replace(/from ["'](.*?)(?<!\.js)["']/, '$1') | |
const tsPath = path.join(path.dirname(filePath), `${importPath}.ts`) | |
const jsPath = path.join(path.dirname(filePath), `${importPath}.js`) | |
const indexTsPath = path.join(path.dirname(filePath), `${importPath}/index.ts`) | |
const indexJsPath = path.join(path.dirname(filePath), `${importPath}/index.js`) | |
// console.log(` Checking: ${tsPath}`) | |
// console.log(` Checking: ${jsPath}`) | |
// console.log(` Checking: ${indexTsPath}`) | |
// console.log(` Checking: ${indexJsPath}`) | |
// Set the import path prefix (to make sure we don't have `././something.js`) | |
let importPathPrefix = './' | |
if (importPath.startsWith('./') || importPath.startsWith('../')) { | |
importPathPrefix = '' | |
} | |
// Fix the import | |
if (fs.existsSync(jsPath) || fs.existsSync(tsPath)) { | |
result = result.replace(match, `from "${importPathPrefix}${importPath}.js"`) | |
} else if (fs.existsSync(indexTsPath) || fs.existsSync(indexJsPath)) { | |
result = result.replace(match, `from "${importPathPrefix}${importPath}/index.js"`) | |
} else { | |
console.log(`Could not find file for import: ${match}`) | |
} | |
} | |
fs.writeFileSync(filePath, result, 'utf8') | |
} | |
const traverseDirectories = dirPath => { | |
fs.readdirSync(dirPath, { withFileTypes: true }).forEach(dirent => { | |
const fullPath = path.join(dirPath, dirent.name) | |
if (dirent.isDirectory()) { | |
traverseDirectories(fullPath) | |
} else if (dirent.isFile() && dirent.name.endsWith('.ts')) { | |
fixImports(fullPath) | |
} | |
}) | |
} | |
console.log(`Fixing imports to be ESM compatible in: ${directoryPath}`) | |
traverseDirectories(directoryPath) | |
// fixImports(directoryPath + '/index.ts') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
The script supports parent directory path traversal like
from "../xxx"
as well.This works both for double
"
and single quotes'
, but will generate double quotes imports"
.