
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
200+ well-tested helper functions & classes for Node.js, including globbing, file watcher, zip, socket and so on | 200+ 个 NodeJS 工具库,顶 140+ 个 NPM 依赖,比如通配符、文件监听、网络库、Zip 压缩等
200+ 个 NodeJS 工具库,顶 140+ 个 NPM 依赖,比如通配符、文件监听、网络库、Zip 压缩等。
如果你有依赖强迫症,这一个库就能帮你省不少依赖,而且风格统一 + 全中文注释 + 稳定高性能。
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")
提供创建、移动、复制、搜索文件和文件夹相关的工具函数,所有函数均可放心地直接调用。
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 字符;遍历、复制文件夹时不支持递归;如果你对操作系统不熟,很可能踩坑。
类似 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 |
内存文件系统提供了和 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 |
监听文件的新增、修改和删除。
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 |
判断路径是否符合规则,支持通配符、正则和自定义函数。
通配符语法同 .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 |
对文件路径的操作,扩充 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 |
快速压缩、解压 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 |
在 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 |
创建一个 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 通信。
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 |
提供网络相关的工具函数。
const net = require("tutils/net")
console.log(net.remoteIP()) // 打印本机 IP
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
public-ip | remoteIP |
对网络地址的操作,扩充 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 |
启动子进程、设置当前进程退出回调。
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 |
在沙盒中执行指定的 JavaScript 代码。类似 eval,但不能访问当前范围的变量。
注意本函数不提供安全隔离,不能用于执行不信任的代码
const vm = require("tutils/vm")
vm.runInVM(`var x = 1`)
线程池,可以利用多核 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 |
提供命令行输出内容的格式化功能。
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 |
提供命令行操作。
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 |
loggerconst { 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 编码,中文会先编码。
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 |
快速实现加密算法。
const crypto = require("tutils/crypto")
crypto.md5("x") // 计算 MD5 值
crypto.sha1("x") // 计算 SHA-1 值
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
md5 | md5 |
sha1 | sha1 |
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 |
const js = require("tutils/js")
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
js-string-escape | encodeJS |
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 |
const css = require("tutils/css")
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
cssesc | encodeCSS |
计算行列号
const lineColumn = require("tutils/lineColumn")
lineColumn.indexToLineColumn("", 0)
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
find-line-column | indexToLineColumn, lineColumnToIndex |
lines-and-columns | LineMap |
读写 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 |
同时生成代码及 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 |
动态修改、拼接字符串并生成 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 |
串联执行异步任务。
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 |
类似 Promise,但可以更灵活地阻塞和回复。
const { Deferred } = require("tutils/deferred")
const deferred = new Deferred()
deferred.reject() // 开始执行异步操作
setTimeout(() => {
deferred.resolve() // 异步操作结束
}, 2000)
await deferred
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
deferred | Deferred |
同原生的 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 |
允许直接载入 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 |
const {jsx, Fragment} = require("tutils/jsx")
/** @jsx jsx */
/** @jsxFrag Fragment */
var div = <button id="my" disabled>Hello World</button>
console.log(div)
const tpl = require("tutils/tpl")
tpl.compileTPL(`{$.data + 2}`)({data: 1}) // "3"
| npm 包名 | TUtils 对应的函数/类 |
|---|---|
ejs | compileTPL |
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 |
FAQs
200+ well-tested helper functions & classes for Node.js, including globbing, file watcher, zip, socket and so on | 200+ 个 NodeJS 工具库,顶 140+ 个 NPM 依赖,比如通配符、文件监听、网络库、Zip 压缩等
The npm package tutils receives a total of 33 weekly downloads. As such, tutils popularity was classified as not popular.
We found that tutils demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.