前言
老板:小陈,最近接手了一个js项目,听说ts比较高大上啊,看看这两三天能不能搞定
我内心os:我丢,这么古老的项目,500+的js文件,让我两三天搞定......
我:噢噢,我先看看.......
打工人,打工魂,打工的都是人上人,没办法,还是得硬着头皮上
解决方案
一开始,我也是想直接一个一个文件地替换,500+多个啊,这要搞到何年何月........
如果,我先将.js文件转换为.ts文件,.jsx文件转换为.tsx不就完了吗,至于类型标注,就在每个文件顶部加入 // @ts-nocheck , 不就搞定了吗
虽然不是很完美,但是可以准点下班,说不定还能摸摸鱼....
实现效果
实现核心代码
下方都有源码地址,请放心食用
1、文件夹/文件递归遍历读取内容
/**
* @description:
* @param directory 目录文件夹
* @param useSubdirectories 是否继续向该目录下的文件夹遍历文件
* @param extList 文件夹名
* @return {*}
*/
function enumerableFile(
directory,
useSubdirectories = false,
extList = ['.java']
) {
return new Promise((resolve, reject) => {
const logFun = (text, val = false) => {
console.log(`文件夹${directory}下未存在${extList.join('/')}文件`)
reject(val)
}
if (path) {
const filesList = []
// 递归读取文件
function readFileList(directory, useSubdirectories, extList) {
const files = fs.readdirSync(directory)
if (files && Array.isArray(files) && files.length) {
files.forEach((item) => {
const fullPath = path.join(directory, item)
const stat = fs.statSync(fullPath)
if (stat.isDirectory() && useSubdirectories) {
readFileList(
path.join(directory, item),
useSubdirectories,
extList
)
} else {
const info = getPathInfo(fullPath)
extList.includes(info.ext) && filesList.push(fullPath)
}
})
} else {
logFun(`文件夹${directory}下未存在${extList.join('/')}文件`)
}
}
readFileList(directory, useSubdirectories, extList)
// 生成需要的对象
if (filesList.length) {
const res = filesList.map((item) => ({
path: item,
...getPathInfo(item),
}))
// console.log(`遍历文件夹${directory}下的${extList.join('/')}文件`, res);
resolve(res)
} else {
logFun(`文件夹${directory}下未存在${extList.join('/')}文件`)
}
} else {
logFun(`读取文件夹名不能为空!`)
}
})
}
2、重命名文件
/**
* @description: 重命名文件后缀
* @param {string} filePath 文件路径
* @param {Object} converRules 转换规则 , 键为旧后缀名,值为新后缀名
* @param {boolean} isBackupOldFile 是否备份旧文件,true 则表示为备份旧的,加入特定名称, false表示为不备份,直接替换
* @return {*}
*/
function reExtname(
filePath,
converRules = {
'.js': '.ts',
'.jsx': '.tsx',
},
isBackupOldFile = false
) {
return new Promise((resolve, reject) => {
if (filePath) {
const oldExtNames = Object.keys(converRules)
if (oldExtNames?.length) {
const newExtNames = Object.values(converRules)
const bool = newExtNames.every((ele) => Boolean(ele))
if (bool) {
isFileExisted(filePath)
.then((res) => {
const fileInfo = getPathInfo(filePath)
console.log('fileInfo=====>', fileInfo)
const { ext, name, dir } = fileInfo
if (ext) {
const newExtName = converRules[ext]
if (newExtName) {
let newPath = `${dir}\\${name}${newExtName}`
let oldPath = filePath
// 如果需要备份旧文件
if (isBackupOldFile) {
// 如果已经备份,则不再备份
const backupName = 'backups'
if (filePath.indexOf(backupName) === -1) {
console.log('进入备份=====>')
const newBackupPath = `${dir}\\${name}-${backupName}${ext}`
fs.rename(oldPath, newBackupPath, (error) => {
if (error) {
reject('文件备份失败:', error)
}
})
oldPath = newBackupPath
}
}
fs.rename(oldPath, newPath, (error) => {
if (error) {
reject('文件重命名失败:', error)
} else {
console.log(`重命名成功,${filePath} ===> ${newPath}`)
resolve(newPath)
}
})
} else {
reject('文件后缀名不满足转换匹配规则')
}
} else {
reject('文件后缀名不存在,无法实现转换')
}
})
.catch((res) => {
console.error('重命名出错', res)
})
} else {
reject('重命名文件后缀名不能为空')
}
} else {
reject('重命名文件后缀名不能为空')
}
} else {
reject('未获取到重命名文件路径')
}
})
}
3、文件内容追加方法
/**
* @description: 追加文件头部内容,内容追加在前面
* @param {*} path 文件路径
* @param {*} data 追加的文件内容
* @param {*} isRepeatWrite 是否重复写入
* @param {*} escapeChar 转义字符
* @return {*}
*/
function appendToHeadData(
path,
data,
isRepeatWrite = false,
escapeChar = '\n'
) {
return new Promise((resolve, reject) => {
if (path) {
if (data) {
readFileFun(path)
.then((fileData) => {
return Promise.resolve(fileData)
})
.then((fileData) => {
const newData = `${data}${escapeChar}${fileData}`
if (isRepeatWrite) {
return parseFile(path, newData)
} else {
if (fileData.indexOf(data) === -1) {
return parseFile(path, newData)
} else {
return Promise.reject('内容已追加,不可重复追加')
}
}
})
.then((res) => {
console.log('追加内容成功:', res)
res && resolve(path)
})
.catch((err) => {
reject('追加头部内容失败:' + err)
})
} else {
reject('追加内容文件内容不能为空')
}
} else {
reject('追加内容文件路径不能为空')
}
})
}
总结
主要是使用node模块fs
- 遍历读取文件夹/文件,找到目标文件
- 使用文件重命名后缀
- 追加文件内容
源码
file-convert : github.com/ArcherNull/…
完结撒花。。。