tutils
v2.4.0
Published
200+ well-tested helper functions & classes for Node.js, including globbing, file watcher, zip, socket and so on | 200+ 个 NodeJS 工具库,顶 140+ 个 NPM 依赖,比如通配符、文件监听、网络库、Zip 压缩等
Readme
TUtils
200+ 个 NodeJS 工具库,顶 140+ 个 NPM 依赖,比如通配符、文件监听、网络库、Zip 压缩等。
如果你有依赖强迫症,这一个库就能帮你省不少依赖,而且风格统一 + 全中文注释 + 稳定高性能。
特性
- 【强大】30+ 个独立模块,可单独引用;
- 【轻量】无外部依赖,所有源码含注释不超过 400K;
- 【稳定】大量的单元测试(覆盖率 80%+)和生产实践,测试用例和社区同步;
- 【性能】鉴于功能专一,几乎所有模块在性能上稳超 NPM 社区模块;
- 【文档】完美全中文文档,VSCode/WebStorm/VS 等可智能提示。
为什么要重做轮子
- 追求纯净:不要为了一个简单功能,依赖几十个包;只支持 Node 最新稳定版(LTS),无历史包袱;
- 追求简洁:一个需求对应一种最短实现,而不是提供各种用法让用户按习惯选择;
- 追求性能:每个模块只专注自身功能,不做多余的操作,减少硬盘读写和内存消耗;
- 追求统一:统一的命名和设计,可以做到举一反三,过目不忘,而不用每次都要翻文档;
- 追求方便:一次安装,即可直接使用所有功能;
- 很多 NPM 包对中日韩文支持不好。
TUtils 总体上提供了“一站式”的使用方式,为你省去在 NPM 上查找、对比模块的烦恼。
安装
npm install tutils --save注意:TUtils 基于 ES2018 编写,仅支持 Node v10.12 或更高版本。
一行代码引用所有模块:
const tutils = require("tutils")或者,单独引入任一模块:
const fsSync = require("tutils/fileSystemSync")
const fs = require("tutils/fileSystem")
const mfs = require("tutils/memoryFileSystem")
const watcher = require("tutils/fileSystemWatcher")
const matcher = require("tutils/matcher")
const path = require("tutils/path")
const zipFile = require("tutils/zipFile")
const request = require("tutils/request")
const server = require("tutils/httpServer")
const ws = require("tutils/webSocket")
const net = require("tutils/net")
const url = require("tutils/url")
const ps = require("tutils/process")
const vm = require("tutils/vm")
const worker = require("tutils/workerPool")
const ansi = require("tutils/ansi")
const commandLine = require("tutils/commandLine")
const logger = require("tutils/logger")
const base64 = require("tutils/base64")
const crypto = require("tutils/crypto")
const html = require("tutils/html")
const js = require("tutils/js")
const json = require("tutils/json")
const css = require("tutils/css")
const lineColumn = require("tutils/lineColumn")
const sourceMap = require("tutils/sourceMap")
const textWriter = require("tutils/textWriter")
const textDocument = require("tutils/textDocument")
const asyncQueue = require("tutils/asyncQueue")
const deferred = require("tutils/deferred")
const eventEmitter = require("tutils/eventEmitter")
const require = require("tutils/require")
const resolver = require("tutils/resolver")
const jsx = require("tutils/jsx")
const tpl = require("tutils/tpl")
const misc = require("tutils/misc")API 文档
模块列表
目录
- 文件操作
- fileSystemSync:文件操作(同步)
- fileSystem:文件操作(异步)
- memoryFileSystem:文件操作(内存模拟)
- fileSystemWatcher:监听
- matcher:通配符
- path:路径计算
- zipFile:Zip 压缩/解压(v2.1.6 新增)
- 网络
- request:发送 HTTP/HTTPS 请求
- httpServer:HTTP 服务器封装
- webSocket:WebSocket 服务端和客户端
- net:底层网络相关的工具函数
- url:地址计算
- 进程
- process:进程操作
- vm:JS 沙盒
- workerPool:线程池
- 命令行
- ansi:命令行颜色、格式
- commandLine:命令行操作
- logger:日志记录器
- 编码、解析
- 生成代码
- lineColumn:行列号和索引换算
- sourceMap:读写源映射(Source Map)
- textWriter:字符串拼接和生成源映射(Source Map)
- textDocument:字符串编辑和生成源映射(Source Map)
- 异步
- asyncQueue:串行执行多个异步任务
- deferred:同时等待多个异步任务
- eventEmitter:支持异步的事件触发器
- 其它
文件操作
fileSystemSync
提供创建、移动、复制、搜索文件和文件夹相关的工具函数,所有函数均可放心地直接调用。
const fs = require("tutils/fileSystemSync")
// 判断存在
fs.existsFile("dir/foo.txt") // 判断文件是否存在
fs.existsDir("dir") // 判断文件夹是否存在
fs.getStat("dir/foo") // 读取路径信息,比如是否是文件夹,大小、最后修改时间
// 读取文件
fs.readFile("dir/foo.jpg") // 读取二进制文件,返回 Buffer
fs.readText("dir/foo.txt") // 读取文本文件,返回字符串
fs.readText("dir/foo.txt", false) // 读取文本文件,如果文件不存在返回 null,而不是报错
// 写入文件
fs.writeFile("dir/foo.txt", "Hello world") // 覆盖已有文件,如果文件不存在则自动创建
fs.writeFile("dir/foo.txt", "Hello world", false) // 不覆盖已有文件
fs.appendFile("dir/foo.txt", "Hello world") // 追加到文件末尾
// 复制和移动文件
fs.copyFile("dir/foo.txt", "dir/copied.txt") // 比先读取再写入快
fs.moveFile("dir/foo.txt", "dir/moved.txt") // 比先复制再删除快
// 删除文件
fs.deleteFile("dir/foo.txt") // 如果文件不存在则忽略
// 遍历文件夹
fs.glob("*.txt") // 搜索当前文件夹下所有 .txt 文件
fs.glob(["*.{js,jsx}", "!node_modules"], "dir") // 搜索 dir 文件夹下所有 .js/.jsx 文件,并忽略 node_modules
fs.readDir("dir") // 读取文件夹下的文件列表(仅一级)
fs.walk("dir", { // 更底层地遍历
file(path) {
console.log("发现文件:", path)
},
dir(path) {
console.log("发现文件夹:", path)
}
})
// 创建文件夹
fs.createDir("dir") // 文件夹已存在则忽略
fs.createTempDir() // 在系统临时目录创建空文件夹
fs.ensureDirExists("dir/foo.txt") // 确保所在文件夹存在
// 复制和移动文件夹
fs.copyDir("dir", "copied") // 比先读取再写入快
fs.moveDir("dir", "moved") // 比先复制再删除快
// 删除文件夹
fs.deleteDir("dir") // 自动删除内部所有子文件和文件夹
fs.cleanDir("dir") // 清空文件夹,比先删除再创建快
fs.deleteParentDirIfEmpty("dir/foo.txt") // 删除空文件夹为什么不使用 Node.js 自带的
fs模块?自带的
fs模块更接近操作系统底层,在有些细节上并不合需求,比如创建文件时,无法自动创建所在文件夹;读取文本文件时不跳过 BOM 字符;遍历、复制文件夹时不支持递归;如果你对操作系统不熟,很可能踩坑。
fileSystem
类似 fileSystemSync,提供创建、移动、复制、搜索文件和文件夹相关的工具函数,但是异步的(更快),所有函数均需要使用 await 语法等待结果。
const { fs } = require("tutils/fileSystem")
// 用法同 fileSystemSync,唯一区别是需要加 await
await fs.writeFile("foo.txt", "Hello world")| npm 包名 | TUtils 对应的函数/类 |
| ------------------- | ----------------------------------------------- |
| graceful-fs | FileSystem |
| fs-extra | FileSystem |
| graceful-fs-extra | FileSystem |
| mkdirp | FileSystem.createDir |
| make-dir | FileSystem.createDir |
| cp-file | FileSystem.copFile |
| cpy | FileSystem.copFile |
| ncp | FileSystem.copyDir |
| copy-files-tree | FileSystem.copyDir |
| clean-dir | FileSystem.cleanDir |
| delete | FileSystem.deleteDir |
| del | FileSystem.deleteDir |
| rimraf | FileSystem.deleteDir, FileSystem.deleteFile |
| node-glob | FileSystem.glob |
| fast-glob | FileSystem.glob |
| globby | FileSystem.glob |
| glob-all | FileSystem.glob |
| walker | FileSystem.walk |
| walkdir | FileSystem.walk |
| move-file | FileSystem.moveFile |
| path-exists | FileSystem.existsFile, FileSystem.existsDir |
memoryFileSystem
内存文件系统提供了和 FileSystem 完全相同的接口,但它会将数据保存到内存,避免多次硬盘读写。
使用 MemoryFileSystem 可以在不改变程序逻辑的情况下,实现类似 git --dry-run 或 npm publish --dry-run 的功能。
const { MemoryFileSystem } = require("tutils/memoryFileSystem")
const fs = new MemoryFileSystem()
// 之后用法同 fileSystem
await fs.writeFile("foo.txt", "Hello world")| npm 包名 | TUtils 对应的函数/类 |
| ----------- | -------------------- |
| memory-fs | MemoryFileSystem |
| mem-fs | MemoryFileSystem |
| memfs | MemoryFileSystem |
fileSystemWatcher
监听文件的新增、修改和删除。
- 支持 Windows/OSX/Linux
- 可同时监听多个目标,且监听列表可动态增删
- 支持非轮询的监听方式(性能高、占用内存小)
- 支持忽略特定路径(以提高性能)
- 支持暂停和恢复
- 纯 JS 实现,不会安装失败
const { FileSystemWatcher } = require("tutils/fileSystemWatcher")
const watcher = new FileSystemWatcher({
ignore: [".DS_Store", "Desktop.ini", "Thumbs.db", "ehthumbs.db", "*~", "*.tmp", ".git", ".vs", "node_modules"]
})
watcher.on("change", path => { console.log("修改:", path) })
watcher.on("delete", path => { console.log("删除:", path) })
watcher.on("create", path => { console.log("创建:", path) })
watcher.on("createDir", path => { console.log("创建文件夹:", path) })
watcher.on("deleteDir", path => { console.log("删除文件夹:", path) })
watcher.add(process.cwd(), () => { console.log("开始监听...") })
// 可以继续监听第二个文件夹,根文件夹必须已存在
watcher.add("dir", () => { console.log("添加监听...") })为什么不使用 Node.js 自带的
fs.watch?自带的
fs拥有诸多限制,比如可能误报、不稳定。FileSystemWatcher内部依然使用了自带的fs.watch,但做了很多判断使得结果更符合作者预期。
| npm 包名 | TUtils 对应的函数/类 |
| ----------- | -------------------- |
| chokidar | FileSystemWatcher |
| gaze | FileSystemWatcher |
| sane | FileSystemWatcher |
| watchpack | FileSystemWatcher |
matcher
判断路径是否符合规则,支持通配符、正则和自定义函数。
通配符语法同 .gitignore 文件,支持以下功能:
?: 匹配固定一个字符,但/和文件名开头的.除外*: 匹配任意个字符,但/和文件名开头的.除外**: 匹配任意个字符,但文件名开头的.除外[abc]: 匹配方括号中的任一个字符[a-z]: 匹配 a 到 z 的任一个字符[!abc]: 匹配方括号中的任一个字符以外的字符{abc,xyz}: 匹配大括号中的任一种模式\: 表示转义字符,如\[表示[按普通字符处理!xyz:如果通配符以!开头,表示排除匹配的项,注意如果排除了父文件夹,出于性能考虑,无法重新包含其中的子文件
const matcher = require("tutils/matcher")
// 判断是否匹配
matcher.match("/path.js", "/*.js") // true
matcher.match("/path.js", [/\.js/, "!node_modules"]) // true| npm 包名 | TUtils 对应的函数/类 |
| ------------- | -------------------- |
| glob | Matcher |
| node-glob | Matcher |
| matcher | Matcher, match |
| minimatch | match |
| micromatch | match |
| anymatch | match |
| glob-base | Matcher.base |
| glob-parent | Matcher.base |
| is-glob | isGlob |
path
对文件路径的操作,扩充 Node.js 自带 path 模块的功能。
注意本模块只处理路径字符串,并不会真的访问硬盘。
const path = require("tutils/path")
// 路径格式化
path.resolvePath("foo/goo/hoo", "../relative") // 转绝对路径
path.relativePath("foo/goo/hoo", "../relative") // 转相对路径
path.joinPath("foo/goo/hoo", "../relative") // 合并路径
path.normalizePath("foo/goo/hoo/../relative") // 规范化路径
path.isAbsolutePath("foo/goo/hoo") // 是否是绝对路径
// 读写文件夹
path.getDir("/root/foo.txt") // "/root"
path.setDir("/root/foo.txt", "goo") // "goo/foo.txt"
path.getRoot("/root/goo/foo.txt") // "/root"
path.setRoot("/root/goo/foo.txt", "/user") // "/user/goo/foo.txt"
// 读写文件名
path.getName("/root/foo.txt") // "foo.txt"
path.setName("/root/foo.txt", "goo.jpg") // "/root/goo.jpg"
path.prependName("foo/goo.txt", "fix_") // "foo/fix_goo.txt"
path.appendName("foo/goo.src.txt", "_fix") // "foo/goo_fix.src.txt"
path.appendIndex("foo/goo.src.txt") // "foo/goo_2.src.txt"
// 读写扩展名
path.getExt("/root/foo.txt")
path.setExt("/root/foo.txt", ".jpg") // "/root/foo.jpg"
// 路径判断
path.pathEquals("/root", "/root") // 判断路径是否相同,在 Windows 忽略大小写
path.containsPath("/root", "/root/foo") // 判断路径父子包含关系
path.deepestPath("/root", "/root/foo") // 获取最深路径
path.commonDir("/root/foo", "/root/foo/goo") // 获取公共文件夹| npm 包名 | TUtils 对应的函数/类 |
| ------------------ | -------------------- |
| rename-extension | setExt |
| changefilesname | setName |
| is-relative | isAbsolutePath |
| is-absolute | isAbsolutePath |
| normalize-path | normalizePath |
| path-is-inside | containsPath |
| contains-path | containsPath |
zipFile(v2.1.6 新增)
快速压缩、解压 Zip 文件。支持局部解压及更新部分文件。
const zipFile = require("tutils/zipFile")
// 快速压缩、解压
zipFile.compressFolder("dir") // 快速压缩 dir 文件夹中的内容为 dir.zip
zipFile.extractZip("dir.zip") // 快速将 dir.zip 解压到 dir 文件夹
// 更复杂操作
const file = zipFile.ZipFile.fromBuffer(buffer)
file.addFile("t.txt") // 添加文件
const result = file.compress() // 重新压缩| npm 包名 | TUtils 对应的函数/类 |
| ------------- | -------------------- |
| unzip | extractZip |
| adm-zip | ZipFile |
| extract-zip | extractZip |
网络
request
在 Node.js 提供类似发送 Ajax 请求的功能。
const request = require("tutils/request")
// 最简单的请求
console.log((await request.request("https://www.baidu.com")).text)
// POST 一个 json 接口,并保存 Cookie
const cookieJar = new request.CookieJar()
const response = await request.request("/api/post", {
method: "POST",
dataType: "json",
data: {
foo: 1
},
headers: {
"X-Request-With": "XMLHTTPRequest"
},
cookieJar: cookieJar
})
console.log(response.json)| npm 包名 | TUtils 对应的函数/类 |
| ----------------- | -------------------- |
| request | request |
| got | request |
| axios | request |
| wreck | request |
| cookiejar | CookieJar |
| touch-cookiejar | CookieJar |
httpServer
创建一个 HTTP 服务器,提供 Cookie、文件上传、Session 会话等扩展功能。
const httpServer = require("tutils/httpServer")
const server = new httpServer.HTTPServer({}, (req, res) => {
res.end(req.href)
})
server.listen(8080)| npm 包名 | TUtils 对应的函数/类 |
| ----------------- | --------------------- |
| express | HTTPServer |
| koa | HTTPServer |
| http-server | HTTPServer |
| body-parser | HTTPRequest.body |
| cookie-parser | HTTPRequest.cookies |
| cookie-sessions | HTTPServer.sessions |
| multipart | HTTPRequest.files |
webSocket
创建一个 WebSocket 服务器,同浏览器端原生 WebSocket 通信。
const webSocket = require("tutils/webSocket")
const server = new webSocket.WebSocketServer("ws://localhost:8080")
server.start()
server.on("connection", ws => {
ws.send("hello")
})
const client = new webSocket.WebSocket("ws://localhost:8080")
client.on("message", data => {
console.log(data)
client.send("hello")
})| npm 包名 | TUtils 对应的函数/类 |
| ------------------ | -------------------- |
| ws | WebSocket |
| websocket-driver | WebSocket |
net
提供网络相关的工具函数。
const net = require("tutils/net")
console.log(net.remoteIP()) // 打印本机 IP| npm 包名 | TUtils 对应的函数/类 |
| ----------- | -------------------- |
| public-ip | remoteIP |
url
对网络地址的操作,扩充 Node.js 自带 url 模块的功能。
const url = require("tutils/url")
// 地址格式化
url.resolveURL("http://example.com", "foo") // 转绝对地址
url.relativeURL("http://example.com", "http://example.com/foo") // 转相对地址
url.normalizeURL("http://example.com/foo/../relative") // 规范化地址
url.setBaseURL("foo", "base") // 设置基路径
// 地址判断
url.isAbsoluteURL("http://example.com/foo") // 是否是绝对地址
url.isExternalURL("http://example.com/foo") // 是否是其它站点的地址
// 查找并替换地址
url.replaceURL("请点击 http://example.com 继续", url => `<a href="${url}">${url}</a>`) // "请点击 <a href="http://example.com">http://example.com</a> 继续"| npm 包名 | TUtils 对应的函数/类 |
| ------------------ | -------------------- |
| resolve-pathname | resolveURL |
| relative-url | relativeURL |
| normalize-url | normalizeURL |
| is-relative-url | isAbsoluteURL |
| get-urls | replaceURL |
| linkify-it | replaceURL |
进程
process
启动子进程、设置当前进程退出回调。
const process = require("tutils/process")
// 执行命令
process.exec("echo hi")
// 打开浏览器
process.open("http://tealui.com")
// 设置进程退出后的回调,可通过 process.offExit 解绑
process.onExit(() => {
console.log("退出了")
})| npm 包名 | TUtils 对应的函数/类 |
| ------------- | -------------------- |
| cross-spawn | exec |
| execa | exec |
| open | open |
| signal-exit | onExit, offExit |
vm
在沙盒中执行指定的 JavaScript 代码。类似 eval,但不能访问当前范围的变量。
注意本函数不提供安全隔离,不能用于执行不信任的代码
const vm = require("tutils/vm")
vm.runInVM(`var x = 1`)workerPool
线程池,可以利用多核 CPU 同时执行多个复杂计算。
const { WorkerPool } = require("tutils/workerPool")
const pool = new WorkerPool(data => data[0] + data[1]) // 这个函数将在子线程执行,函数无法使用闭包
await pool.exec([1, 2]) // 3| npm 包名 | TUtils 对应的函数/类 |
| --------------------- | -------------------- |
| worker-threads-pool | WorkerPool |
命令行
ansi
提供命令行输出内容的格式化功能。
const ansi = require("tutils/ansi")
// 颜色
console.log(ansi.color("红色", ansi.ANSIColor.red))
console.log(ansi.backgroundColor("红色", ansi.ANSIColor.red))
console.log(ansi.removeANSICodes("...")) // 删除颜色
// 格式化(支持中文)
console.log(ansi.truncateString("很长的内容", "...")) // 超出命令行宽度则截断
console.log(ansi.wrapString("很长的内容")) // 超出命令行宽度则换行
console.log(ansi.formatList(["a", "ab"])) // 显示一个列表
console.log(ansi.formatTree([{indent: 0, label: "x"}, {indent: 1, label: "x1"}])) // 显示一个树
console.log(ansi.formatTable([["a", "ab"], ["a2", "ab2"]])) // 显示一个表格
console.log(ansi.formatCodeFrame("var a = 1\nvar b = 2", 1, 8) // 显示一段代码,带行号
console.log(ansi.ansiToHTML("")) // 转 HTML,保留颜色和其它格式| npm 包名 | TUtils 对应的函数/类 |
| ---------------------- | ---------------------------------- |
| ansi-color | color |
| ansi-colors | color |
| chalk | bold, color, backgroundColor |
| kleur | bold, color, backgroundColor |
| ansi-style-codes | ANSIColor |
| ansi-regex | ansiCodeRegExp |
| strip-ansi | removeANSICodes |
| strip-color | removeANSICodes |
| ansi-stripper | removeANSICodes |
| cli-truncate | truncateString |
| ansi-color-table | formatTable |
| chunk-text | wrapString |
| wrap-ansi | wrapString |
| cli-columns | formatList |
| console-log-tree | formatTree |
| ansi-color-table | formatTable |
| columnify | formatTable |
| formatter-codeframe | formatCodeFrame |
| ansicolor | ansiToHTML |
| ansi-to-html | ansiToHTML |
| ansi-html | ansiToHTML |
| stream-ansi2html | ansiToHTML |
| string-width | getStringWidth |
| monospace-char-width | getCharWidth |
commandLine
提供命令行操作。
const commandLine = require("tutils/commandLine")
// 光标
commandLine.hideCursor() // 隐藏光标,使用 commandLine.showCursor() 还原
// 清空命令行
commandLine.clear()
// 解析命令行参数
commandLine.parseCommandLineArguments()
// 格式化帮助命令
commandLine.formatCommandLineOptions({
"--x": {
"alias": "-x",
"description": "说明"
}
})
// 读取命令行输入
const name = await commandLine.input("请输入名字:")
console.log(name)
const choice = await commandLine.select(["打开", "关闭"], "请选择一个:")
console.log(choice)| npm 包名 | TUtils 对应的函数/类 |
| ---------------------- | ------------------------------------------------------- |
| show-terminal-cursor | showCursor |
| hide-terminal-cursor | hideCursor |
| cli-cursor | showCursor, hideCursor |
| restore-cursor | showCursor |
| meow | parseCommandLineArguments, formatCommandLineOptions |
| yargs | parseCommandLineArguments, formatCommandLineOptions |
| clear-cli | clear |
| node-console-input | input |
logger
const { Logger } = require("tutils/logger")
const logger = new Logger()
// 打印
logger.fatal("Hello world")
logger.error("Hello world")
logger.warning("Hello world")
logger.info("Hello world")
logger.success("Hello world")
logger.log("Hello world")
logger.debug("Hello world")
logger.trace("Hello world")
// 进度条
logger.showProgress("载入中") // 使用 logger.hideProgress() 隐藏
const taskId = loggger.begin("读取文件")
// ...执行读取文件操作...
logger.end(taskId)| npm 包名 | TUtils 对应的函数/类 |
| ----------- | -------------------- |
| logger | Logger |
| fancy-log | Logger |
编码、解析
base64
快速实现 Base64 编码,中文会先编码。
const base64 = require("tutils/base64")
base64.encodeBase64("")
base64.decodeBase64("")
base64.encodeDataURI("") // 生成 base64 的 data: 地址
base64.decodeDataURI("data: image/png;base64, ...") // 读取 base64 的 data: 地址| npm 包名 | TUtils 对应的函数/类 |
| ------------ | -------------------------------- |
| js-base64 | encodeBase64, decodeBase64 |
| data-urlse | encodeDataURI, decodeDataURI |
crypto
快速实现加密算法。
const crypto = require("tutils/crypto")
crypto.md5("x") // 计算 MD5 值
crypto.sha1("x") // 计算 SHA-1 值| npm 包名 | TUtils 对应的函数/类 |
| -------- | -------------------- |
| md5 | md5 |
| sha1 | sha1 |
html
const html = require("tutils/html")| npm 包名 | TUtils 对应的函数/类 |
| ---------------------- | -------------------------- |
| ent | encodeHTML, decodeHTML |
| entities | encodeHTML, decodeHTML |
| he | encodeHTML, decodeHTML |
| html-entities | encodeHTML |
| decode-html | decodeHTML |
| html-decoder | decodeHTML |
| html-entity-decoder | decodeHTML |
| html-encoder-decoder | encodeHTML, decodeHTML |
| html-parser | parseHTML |
js
const js = require("tutils/js")| npm 包名 | TUtils 对应的函数/类 |
| ------------------ | -------------------- |
| js-string-escape | encodeJS |
json
const json = require("tutils/json")
// 读取 JSON
json.readJSON("path.json") // 支持注释和末尾多余的逗号
json.normalizeJSON("{a:1,}") // 删除 JSON 字符串中的注释和末尾多余的逗号
// 写入 JSON
json.writeJSON("path.json", {}) // 安全写入 JSON 数据| npm 包名 | TUtils 对应的函数/类 |
| --------------------- | -------------------- |
| strip-json-comments | normalizeJSON |
| load-json-file | readJSON |
| write-json-file | writeJSON |
css
const css = require("tutils/css")| npm 包名 | TUtils 对应的函数/类 |
| -------- | -------------------- |
| cssesc | encodeCSS |
生成代码
lineColumn
计算行列号
const lineColumn = require("tutils/lineColumn")
lineColumn.indexToLineColumn("", 0)| npm 包名 | TUtils 对应的函数/类 |
| ------------------- | ---------------------------------------- |
| find-line-column | indexToLineColumn, lineColumnToIndex |
| lines-and-columns | LineMap |
sourceMap
读写 Source Map。
const sourceMap = require("tutils/sourceMap")
// 修改源映射
const map = new sourceMap.SourceMapBuilder({ /* 已存在的 map*/ })
map.addMapping(1, 2)
const output = map.toJSON() // 生成的新 map| npm 包名 | TUtils 对应的函数/类 |
| -------------------- | --------------------------------- |
| source-map | SourceMapBuilder |
| convert-source-map | SourceMapBuilder |
| merge-source-map | SourceMapBuilder.applySourceMap |
textWriter
同时生成代码及 Source Map。
const { TextWriter, SourceMapTextWriter } = require("tutils/textWriter")
const writer = new SourceMapTextWriter()
writer.write("hello")
console.log(writer.toString())
console.log(writer.sourceMap)| npm 包名 | TUtils 对应的函数/类 |
| ----------------------- | --------------------- |
| string-builder | TextWriter |
| source-list-map | SourceMapTextWriter |
| fast-sourcemap-concat | SourceMapTextWriter |
textDocument
动态修改、拼接字符串并生成 Source Map。
const { TextDocument, replace, insert } = require("tutils/textDocument")
const data = replace({
content: "var a = 1",
path: "source.js"
}, /\bvar\b/g, "let")
console.log(data.content)
console.log(data.sourceMap)| npm 包名 | TUtils 对应的函数/类 |
| -------------- | -------------------- |
| magic-string | TextDocument |
异步
asyncQueue
串联执行异步任务。
const { AsyncQueue } = require("tutils/asyncQueue")
const asyncQueue = new AsyncQueue()
await asyncQueue.then(async () => { /* 异步操作 1 */ })
await asyncQueue.then(async () => { /* 异步操作 2 */ })
await asyncQueue.then(async () => { /* 异步操作 3 */ })| npm 包名 | TUtils 对应的函数/类 |
| ----------------- | -------------------- |
| asyncqueue | AsyncQueue |
| node-asyncqueue | AsyncQueue |
deferred
类似 Promise,但可以更灵活地阻塞和回复。
const { Deferred } = require("tutils/deferred")
const deferred = new Deferred()
deferred.reject() // 开始执行异步操作
setTimeout(() => {
deferred.resolve() // 异步操作结束
}, 2000)
await deferred| npm 包名 | TUtils 对应的函数/类 |
| ---------- | -------------------- |
| deferred | Deferred |
eventEmitter
同原生的 events 模块,但支持异步事件。
const { EventEmitter } = require("tutils/eventEmitter")
const events = new EventEmitter()
events.on("error", data => console.log(data)) // 绑定 error 事件
await events.emit("error", "hello") // 触发 error 事件,输出 hello| npm 包名 | TUtils 对应的函数/类 |
| ---------- | -------------------- |
| events | EventEmitter |
| tappable | EventEmitter |
其它
require
允许直接载入 ES 模块代码;允许载入全局安装的模块。
const { registerESMLoader, addGlobalPath } = require("tutils/require")
registerESMLoader()
require("./esm.js")
addGlobalPath("dir") // require 时会从 dir 搜索模块| npm 包名 | TUtils 对应的函数/类 |
| ---------------- | -------------------- |
| esm | registerESMLoader |
| require-global | addGlobalPath |
resolver 模块
类似 require.resolve,但可提供更多的配置选择。
const { Resolver } = require("tutils/resolver")
const resolver = new Resolver()
const result = await resolver.resolve("tutils", process.cwd())| npm 包名 | TPack-Utils 对应的函数/类 |
| ------------------ | ------------------------- |
| enhanced-resolve | Resolver |
jsx
const {jsx, Fragment} = require("tutils/jsx")
/** @jsx jsx */
/** @jsxFrag Fragment */
var div = <button id="my" disabled>Hello World</button>
console.log(div)tpl
const tpl = require("tutils/tpl")
tpl.compileTPL(`{$.data + 2}`)({data: 1}) // "3"| npm 包名 | TUtils 对应的函数/类 |
| -------- | -------------------- |
| ejs | compileTPL |
misc
const misc = require("tutils/misc")
misc.stripBOM("...") // 删除字符串开头的 UTF-8 BOM 字符
misc.randomString() // 生成指定长度的随机字符串
misc.insertSorted() // 插入排序
misc.formatDate(new Date("2016/01/01 00:00:00")) // 格式化指定的日期对象
misc.formatRelativeDate(new Date("2016/01/01 00:00:00")) // 格式化时间为类似“几分钟前”的格式
misc.formatHRTime(process.hrtime()) // 格式化时间间隔
misc.formatSize(1024) // 格式化字节大小,1KB| npm 包名 | TUtils 对应的函数/类 |
| ---------------------- | -------------------- |
| strip-bom | stripBOM |
| sorted-array-type | insertSorted |
| escape-string-regexp | escapeRegExp |
| format-date | formatDate |
| dateformat | formatDate |
| Moment.js | formatDate |
| node-dateformate | formatDate |
| pretty-hrtime | formatHRTime |
| pretty-time | formatHRTime |
| pretty-bytes | formatSize |
| pretty-size | formatSize |
