Skip to content

Instantly share code, notes, and snippets.

@DaggieBlanqx
Last active March 31, 2026 18:51
Show Gist options
  • Select an option

  • Save DaggieBlanqx/0c7c8340d32f60d65fa1ec42ba1ddb78 to your computer and use it in GitHub Desktop.

Select an option

Save DaggieBlanqx/0c7c8340d32f60d65fa1ec42ba1ddb78 to your computer and use it in GitHub Desktop.
For converting ESM to CJS
const fs = require('fs')
const path = require('path')
const files = process.argv.slice(2)
function convertFile (filePath) {
let src = fs.readFileSync(filePath, 'utf8')
const original = src
// 1. import X from 'y' → const X = require('y')
src = src.replace(/^import\s+(\w+)\s+from\s+(['"`][^'"`]+['"`]);?/gm, 'const $1 = require($2);')
// 2. import { a, b, c } from 'y' → const { a, b, c } = require('y')
src = src.replace(/^import\s+(\{[^}]+\})\s+from\s+(['"`][^'"`]+['"`]);?/gm, 'const $1 = require($2);')
// 3. import * as X from 'y' → const X = require('y')
src = src.replace(/^import\s+\*\s+as\s+(\w+)\s+from\s+(['"`][^'"`]+['"`]);?/gm, 'const $1 = require($2);')
// 4. export default X → module.exports = X
src = src.replace(/^export\s+default\s+/gm, 'module.exports = ')
// 5. export const X = ... → const X = ... then append module.exports.X = X
const namedExports = []
src = src.replace(/^export\s+const\s+(\w+)\s*=/gm, (match, name) => {
namedExports.push(name)
return `const ${name} =`
})
// 6. export { a, b, c } → module.exports = { a, b, c }
src = src.replace(/^export\s+\{([^}]+)\};?/gm, (match, names) => {
return `module.exports = {${names}};`
})
// 7. export function X → function X then append module.exports.X = X
src = src.replace(/^export\s+function\s+(\w+)/gm, (match, name) => {
namedExports.push(name)
return `function ${name}`
})
// Append named export assignments at the end
if (namedExports.length > 0) {
const unique = [...new Set(namedExports)]
src = src.trimEnd() + '\n\n' + unique.map(n => `module.exports.${n} = ${n};`).join('\n') + '\n'
}
if (src !== original) {
fs.writeFileSync(filePath, src, 'utf8')
console.log('✅ Converted:', filePath)
} else {
console.log('⚠️ No changes:', filePath)
}
}
files.forEach(f => {
try {
convertFile(f)
} catch (err) {
console.error('❌ Error on', f, err.message)
}
})
// Usage:
// node convert-esm-to-cjs.js <file1> [file2] [file3] ...
//
// Examples:
// node convert-esm-to-cjs.js src/utils.js
// node convert-esm-to-cjs.js src/utils.js src/helpers.js lib/index.js
// node convert-esm-to-cjs.js src/**/*.js
//
// Before (ESM):
// import path from 'path'
// import { readFile } from 'fs'
// import * as _ from 'lodash'
//
// export default function main() { return 42 }
//
// export function greet(name) { return `Hello, ${name}` }
// export const PI = 3.14
//
// export { greet, PI }
//
// After (CJS):
// const path = require('path');
// const { readFile } = require('fs');
// const _ = require('lodash');
//
// module.exports = function main() { return 42 }
//
// function greet(name) { return `Hello, ${name}` }
// const PI = 3.14
//
// module.exports = { greet, PI };
//
// module.exports.greet = greet;
// module.exports.PI = PI;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment