Merge pull request #31954 from overleaf/ar-remove-js-to-esm-transform

[web] remove esm transforms

GitOrigin-RevId: cd6aadcc66fa31026e8cb56f7b5f8fc5c5f8e18c
This commit is contained in:
Andrew Rumble
2026-03-03 10:54:20 +00:00
committed by Copybot
parent 81b7121408
commit a4ef0c7ce1
10 changed files with 0 additions and 1656 deletions

1367
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -193,7 +193,6 @@
"zod-validation-error": "^4.0.1"
},
"devDependencies": {
"5to6-codemod": "^1.8.0",
"@ai-sdk/react": "^3.0.2",
"@babel/core": "^7.28.5",
"@babel/plugin-proposal-decorators": "^7.28.0",

View File

@@ -1,89 +0,0 @@
import minimist from 'minimist'
import { exec } from 'node:child_process'
import { promisify } from 'node:util'
import Runner from 'jscodeshift/src/Runner.js'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
// use minimist to get a list of files from the argv
const {
dryRun,
verbose,
usage,
_: files,
} = minimist(process.argv.slice(2), {
boolean: ['dryRun', 'usage', 'verbose'],
})
function printUsage() {
console.log(
'node scripts/esm-migration/cjs-to-esm.mjs [files] [--dryRun] [--format] [--lint] [--usage] [--verbose]'
)
console.log(
'WARNING: this will only work in local development as important dependencies will be missing in production'
)
console.log('Options:')
console.log(' files: a list of files to convert')
console.log('--dryRun: do not actually run the commands, just print them')
console.log('--format: run prettier to fix formatting')
console.log(' --lint: run eslint to fix linting')
console.log(' --usage: show this help message')
console.log('--verbose: enable verbose output')
process.exit(0)
}
if (usage) {
printUsage()
}
if (!Array.isArray(files) || files.length === 0) {
console.error('You must provide a list of files to convert')
printUsage()
process.exit(1)
}
const promisifiedExec = promisify(exec)
const transforms = [
'5to6-codemod/transforms/cjs.js',
'5to6-codemod/transforms/exports.js',
'./codemods/esmoduleDirname.js',
'./codemods/addExtensions.js',
'./codemods/fixMongodbImport.js',
]
const config = {
output: import.meta.dirname,
silent: verbose,
print: false,
verbose: verbose ? 1 : 0,
hoist: true,
dry: dryRun,
runInBand: true,
}
if (dryRun) {
console.log('Dry run mode enabled. No changes will be made.')
}
for (const transformPath of transforms) {
if (verbose) {
console.log(`Running transform: ${transformPath}`)
}
const transform = fileURLToPath(await import.meta.resolve(transformPath))
await Runner.run(transform, files, config)
}
const webRoot = fileURLToPath(new URL('../../', import.meta.url))
if (!dryRun) {
for (const file of files) {
// move files with git mv
const newFileName = file.replace('.js', '.mjs')
await promisifiedExec(`git mv ${file} ${newFileName}`)
const relativePath = path.relative(webRoot, file)
console.log(
`transformed ${relativePath} and renamed it to have a .mjs extension`
)
}
}

View File

@@ -1,33 +0,0 @@
const fs = require('node:fs')
const Path = require('node:path')
module.exports = function (fileInfo, api) {
const j = api.jscodeshift
const root = j(fileInfo.source)
// Add extension to relative path imports
root
.find(j.ImportDeclaration)
.filter(path => path.node.source.value.startsWith('.'))
.forEach(path => {
const importPath = path.node.source.value
const fullPathJs = Path.resolve(
Path.dirname(fileInfo.path),
`${importPath}.js`
)
const fullPathMjs = Path.resolve(
Path.dirname(fileInfo.path),
`${importPath}.mjs`
)
if (fs.existsSync(fullPathJs)) {
path.node.source.value = `${importPath}.js`
} else if (fs.existsSync(fullPathMjs)) {
path.node.source.value = `${importPath}.mjs`
}
})
return root.toSource({
quote: 'single',
})
}

View File

@@ -1,14 +0,0 @@
module.exports = function transformer(file, api) {
const j = api.jscodeshift
return j(file.source)
.find(j.Identifier, { name: '__dirname' })
.replaceWith(
j.memberExpression(
j.metaProperty(j.identifier('import'), j.identifier('meta')),
j.identifier('dirname'),
false
)
)
.toSource()
}

View File

@@ -1,54 +0,0 @@
import path from 'node:path'
import fs from 'node:fs'
/**
* @param {import('jscodeshift').FileInfo} file
* @param {import('jscodeshift').API} api
*/
module.exports = function transformer(file, api) {
const j = api.jscodeshift
const root = j(file.source)
let hasChanges = false
const considerExtensionReplacement = nodePath => {
const source = nodePath.value.source
if (
!source ||
typeof source.value !== 'string' ||
!source.value.endsWith('.js')
) {
return
}
const importPath = source.value
const currentDirectory = path.dirname(file.path)
const jsPath = path.resolve(currentDirectory, importPath)
if (fs.existsSync(jsPath)) {
return
}
const mjsImportPath = importPath.replace(/\.js$/, '.mjs')
const mjsPath = path.resolve(currentDirectory, mjsImportPath)
if (fs.existsSync(mjsPath)) {
j(nodePath).get('source').replace(j.literal(mjsImportPath))
hasChanges = true
}
}
const declarationTypes = [
j.ImportDeclaration,
j.ExportNamedDeclaration,
j.ExportAllDeclaration,
]
declarationTypes.forEach(type => {
root
.find(type, { source: s => s !== null })
.forEach(considerExtensionReplacement)
})
return hasChanges ? root.toSource({ quote: 'single' }) : null
}

View File

@@ -1,46 +0,0 @@
const { getLastImport } = require('./utils')
module.exports = function (fileInfo, api) {
const j = api.jscodeshift
const root = j(fileInfo.source)
const body = root.get().value.program.body
// Fix mongodb-legacy import
root
.find(j.ImportDeclaration, {
source: { value: 'mongodb-legacy' },
specifiers: [{ imported: { name: 'ObjectId' } }],
})
.forEach(path => {
// Create new import declaration
const newImport = j.importDeclaration(
[j.importDefaultSpecifier(j.identifier('mongodb'))],
j.literal('mongodb-legacy')
)
// Create new constant declaration
const newConst = j.variableDeclaration('const', [
j.variableDeclarator(
j.objectPattern([
j.property(
'init',
j.identifier('ObjectId'),
j.identifier('ObjectId')
),
]),
j.identifier('mongodb')
),
])
// Replace the old import with the new import
j(path).replaceWith(newImport)
// Insert the new constant declaration after the last import
const lastImportIndex = getLastImport(body)
body.splice(lastImportIndex + 1, 0, newConst)
})
return root.toSource({
quote: 'single',
})
}

View File

@@ -1,13 +0,0 @@
/**
*
* @return {Node}
*/
function getLastImport(body) {
return body.reduce((lastIndex, node, index) => {
return node.type === 'ImportDeclaration' ? index : lastIndex
}, -1)
}
module.exports = {
getLastImport,
}

View File

@@ -1,17 +0,0 @@
#!/bin/bash
set -e
script_dir=$(dirname "$0")
FILES_TO_FIX=$(eslint . --format compact --no-color \
| grep 'import/no-unresolved' \
| cut -d':' -f1 \
| sort -u)
if [ -z "$FILES_TO_FIX" ]; then
echo "No files with 'import/no-unresolved' errors found. Nothing to do!"
exit 0
fi
echo "$FILES_TO_FIX" | xargs jscodeshift --parser=babel -t "$script_dir/codemods/fixMissingJsImports.mjs"

View File

@@ -1,22 +0,0 @@
#!/bin/bash
if [ -z "$1" ]; then
echo "Usage: transform-dir.sh <module_path>"
exit 1
fi
MODULE_PATH=$1
while true; do
FILES=$(node scripts/esm-check-migration.mjs -f "$MODULE_PATH" -j | jq -r '.filesNotImportedViaCjs | join(" ")')
if [ -z "$FILES" ]; then
break
fi
# We want word splitting here
# shellcheck disable=SC2086
node transform/cjs-to-esm/cjs-to-esm.mjs $FILES
done
make format_fix > /dev/null
echo "All files processed."