Skip to content

Instantly share code, notes, and snippets.

@Reeska
Last active May 8, 2024 15:49
Show Gist options
  • Save Reeska/05c11a296f90b76548cec45b23674f71 to your computer and use it in GitHub Desktop.
Save Reeska/05c11a296f90b76548cec45b23674f71 to your computer and use it in GitHub Desktop.
A script to convert .js to .jsx when they contains JSX tags
// node ./rename-js-to-jsx.js ./my/folder
const fs = require('fs')
const path = require('path')
// Options
const src = process.argv[2] ?? './'
const pattern = process.argv[3] ? new RegExp(`${process.argv[3]}$`) : /.js$/
const newExtension = process.argv[4] ?? '.jsx'
console.log(`Path = ${src} ; pattern = ${pattern} ; newExtension = ${newExtension}`)
const getAllFiles = (dirPath, pattern, files = []) => {
const filesInDirectory = fs.readdirSync(dirPath)
return filesInDirectory.reduce((foundFiles, file) => {
if (fs.statSync(`${dirPath}/${file}`).isDirectory()) {
return getAllFiles(`${dirPath}/${file}`, pattern, foundFiles)
} else {
if (!matchPattern(file, pattern)) {
return foundFiles
}
return [
...foundFiles,
path.join(__dirname, dirPath, '/', file),
]
}
}, files)
}
const matchPattern = (filename, pattern) => filename.match(pattern)
const readFile = (path) => fs.readFileSync(path).toString('utf-8')
const renameFile = (path, extension) => {
try {
fs.renameSync(path, path.replace(pattern, extension))
console.log(`${path} [RENAMED]`)
return true
} catch (error) {
console.log(`${path} [KO]`, error)
return false
}
}
// <> </> <tag /> <tag></tag>
const containsJSX = (content) => /(<\/|\/>)/.test(content)
// Run
console.log('Search files...')
const files = getAllFiles(src, pattern)
.map((file) => ({filename: file, content: readFile(file)}))
.filter((file) => containsJSX(file.content))
.map((file) => file.filename)
console.log('Found files', files.length)
console.log('Renaming...')
const successFiles = files
.map((file) => renameFile(file, newExtension))
.filter(Boolean)
console.log(`Rename ${successFiles.length}/${files.length} with success.`)
if (successFiles.length !== files.length) {
console.log('Execution encountered some errors.')
process.exit(1)
}
@Reeska
Copy link
Author

Reeska commented Dec 8, 2022

How does it work, would you please explain!

This script will scans the files in the given directory and renames all .js files that contains JSX tags to .jsx files.

Signature:

node ./rename-js-to-jsx.js [directory] [oldExtension] [newExtension]

By default:

  • directory is the current directory
  • oldExtension is .js
  • newExtension is .jsx

You can customize which files to scan with the second argument.

For example to rename all .ts that contains JSX tags to .jsx (not a real example but still):

node ./rename-js-to-jsx.js ./src .ts

You can also customize which new extension you want for your JSX files with the third argument (more sense for this one):

node ./rename-js-to-jsx.js ./src .ts .tsx

@pspaulding
Copy link

I think the period in the pattern on line 8 should be escaped, otherwise treated as any character in regexp:

const pattern = process.argv[3] ? new RegExp(`${process.argv[3]}$`) : /\.js$/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment