UNPKG

@honor-minigame/cli

Version:

honor minigame pack cli

197 lines (187 loc) 6.06 kB
import fs from 'fs' import $path from 'path' import { info } from './logger.js' // path <string> | <Buffer> | <URL> // options <Object> // recursive <boolean> 如果为 true,则执行递归的目录删除。在递归模式中,如果 path 不存在则不报告错误,并且在失败时重试操作。默认值: false。 // exclude <Regexp> 符合该正则的就不删除 // 在文件(而不是目录)上使用 fs.rmdirSync() 会导致在 Windows 上出现 ENOENT 错误、在 POSIX 上出现 ENOTDIR 错误。 // 稳定性 - 递归的删除是实验性的(因此不在生产环境中使用原来的参数,2而采用更兼容的方式) const rmdirSync = (path, options) => { if (options && options.recursive) { let files = [] if (fs.existsSync(path)) { if (fs.statSync(path).isDirectory()) { files = fs.readdirSync(path) for (const file of files) { const currentPath = $path.join(path, file) if (fs.statSync(currentPath).isDirectory()) { rmdirSync(currentPath, options) } else { fs.unlinkSync(currentPath) } } } } } return fs.rmdirSync(path) } // 拓展 // 将指定路径上的文件内容解析为json对象 const parse = (path) => { const json = fs.readFileSync(path) return JSON.parse(json) || {} } // 依赖 rmdirSync const clearDir = (path, options) => { if (fs.existsSync(path)) { let files = [] if (fs.existsSync(path)) { files = fs.readdirSync(path) for (const file of files) { const currentPath = $path.join(path, file) if (options && options.exclude && options.exclude.test(currentPath)) { console.log(`不删除${currentPath}`) continue } if (fs.statSync(currentPath).isDirectory()) { clearDir(currentPath, options) let currentFiles = [] currentFiles = fs.readdirSync(currentPath) if (!currentFiles.length) { fs.rmdirSync(currentPath) } } else { fs.unlinkSync(currentPath) } } } } else { if (options && options.build) { console.log(`创建目录${path}`) fs.mkdirSync(path) } } } const overwrite = (src, dest, options) => { if (options) { options.basePath = $path.normalize(src) } overwriteFile(src, dest, options) } // 覆盖指定的文件或者文件夹中同名的文件和文件夹(不会删除dest中存在但是src中不存在的文件和文件夹) const overwriteFile = (src, dest, options) => { if (!fs.existsSync(src)) { console.log(`不存在${src}`) return } if (options && options.exclude) { const relativePath = $path.relative(options.basePath, $path.normalize(src)) if (options.basePath !== $path.normalize(src) && options.exclude.test(relativePath)) { console.log(`${src}-x->${dest}`) return } } if (fs.statSync(src).isDirectory()) { if (!fs.existsSync(dest)) { fs.mkdirSync(dest) } let files = [] files = fs.readdirSync(src) for (const file of files) { if (options && options.exclude && options.exclude.test(file)) { continue } overwriteFile($path.join(src, file), $path.join(dest, file), options) } } else { const directory = $path.dirname(dest) fs.mkdirSync(directory, { recursive: true }) // 默认情况下,如果 dest 已经存在,则覆盖它。 fs.copyFileSync(src, dest) } return true } /** * 遍历目录文件 同步方法 * @param dir * @param files 收集的文件列表 */ const traverseDirSync = function (dir, files, options) { const st = fs.statSync(dir) if (st && st.isFile()) { files.push(dir) return } const list = fs.readdirSync(dir) list.forEach(function (file) { const isExclude = options && options.exclude && options.exclude.test(file) if (!isExclude) { file = $path.join(dir, file) const stat = fs.statSync(file) if (stat && stat.isDirectory()) { traverseDirSync(file, files, options) } else { if (options && options.include) { if (options.include.test(file)) { files.push(file) } return } files.push(file) } } }) } /** * 替换文件夹中文件的字符串 * @param {*} dir 文件夹 * @param {*} options {include: 需要替换的文件, exclude: 需要排除的文件或文件夹,map: 需要替换的字符串, to:需要替换成该字符串} * options: replaceFrom:map找到字符串,其中需要被替换的字符串,replaceTo:其中需要替换成的字符串 * @returns */ const replaceFiles = (dir, options) => { if (!fs.existsSync(dir)) { console.log(`不存在${dir}`) return } if (!options || !options.map) { console.log(`options或map、to为空,${options}`) return } const files = [] traverseDirSync(dir, files, options) // console.log(files) for (const file of files) { let content = fs.readFileSync(file, { encoding: 'utf-8' }) const regexp = new RegExp(options.map, 'g') if (content && options.map.test(content)) { if (options.replaceFrom && options.replaceTo) { info(`>>>> ${file} replaceTo ${options.replaceTo}`) var match while ((match = regexp.exec(content)) !== null) { var replaceStr = match[0].replace(options.replaceFrom, options.replaceTo) content = content.replace(match[0], replaceStr) } fs.writeFileSync(file, content) } else if (options.to) { info(`>>>> ${file} replaceTo ${options.to}`) content = content.replace(regexp, options.to) fs.writeFileSync(file, content) } } } return true } const fsExt = { clearDir, parse, overwrite } export { rmdirSync, replaceFiles, fsExt }