cjs-to-esm.mjs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import minimist from 'minimist'
  2. import { exec } from 'node:child_process'
  3. import { promisify } from 'node:util'
  4. import Runner from 'jscodeshift/src/Runner.js'
  5. import { fileURLToPath } from 'node:url'
  6. import path from 'node:path'
  7. // use minimist to get a list of files from the argv
  8. const {
  9. dryRun,
  10. verbose,
  11. usage,
  12. _: files,
  13. } = minimist(process.argv.slice(2), {
  14. boolean: ['dryRun', 'usage', 'verbose'],
  15. })
  16. function printUsage() {
  17. console.log(
  18. 'node scripts/esm-migration/cjs-to-esm.mjs [files] [--dryRun] [--format] [--lint] [--usage] [--verbose]'
  19. )
  20. console.log(
  21. 'WARNING: this will only work in local development as important dependencies will be missing in production'
  22. )
  23. console.log('Options:')
  24. console.log(' files: a list of files to convert')
  25. console.log('--dryRun: do not actually run the commands, just print them')
  26. console.log('--format: run prettier to fix formatting')
  27. console.log(' --lint: run eslint to fix linting')
  28. console.log(' --usage: show this help message')
  29. console.log('--verbose: enable verbose output')
  30. process.exit(0)
  31. }
  32. if (usage) {
  33. printUsage()
  34. }
  35. if (!Array.isArray(files) || files.length === 0) {
  36. console.error('You must provide a list of files to convert')
  37. printUsage()
  38. process.exit(1)
  39. }
  40. const promisifiedExec = promisify(exec)
  41. const transforms = [
  42. '5to6-codemod/transforms/cjs.js',
  43. '5to6-codemod/transforms/exports.js',
  44. './codemods/esmoduleDirname.js',
  45. './codemods/addExtensions.js',
  46. './codemods/fixMongodbImport.js',
  47. ]
  48. const config = {
  49. output: import.meta.dirname,
  50. silent: verbose,
  51. print: false,
  52. verbose: verbose ? 1 : 0,
  53. hoist: true,
  54. dry: dryRun,
  55. runInBand: true,
  56. }
  57. if (dryRun) {
  58. console.log('Dry run mode enabled. No changes will be made.')
  59. }
  60. for (const transformPath of transforms) {
  61. if (verbose) {
  62. console.log(`Running transform: ${transformPath}`)
  63. }
  64. const transform = fileURLToPath(await import.meta.resolve(transformPath))
  65. await Runner.run(transform, files, config)
  66. }
  67. const webRoot = fileURLToPath(new URL('../../', import.meta.url))
  68. if (!dryRun) {
  69. for (const file of files) {
  70. // move files with git mv
  71. const newFileName = file.replace('.js', '.mjs')
  72. await promisifiedExec(`git mv ${file} ${newFileName}`)
  73. const relativePath = path.relative(webRoot, file)
  74. console.log(
  75. `transformed ${relativePath} and renamed it to have a .mjs extension`
  76. )
  77. }
  78. }