jsesc-es
v1.0.2
Published
Given some data, jsesc returns the shortest possible stringified & ASCII-safe representation of that data.
Maintainers
Readme
jsesc-es
English | 简体中文
基于流行的 jsesc 库,使用现代 TypeScript + ESM 重构,100% API 兼容
给定一些数据,jsesc-es 返回该数据的字符串化表示。jsesc-es 类似于 JSON.stringify(),但有以下不同:
- 默认情况下输出 JavaScript 而不是 JSON,支持 ES6 map 和 set 等数据结构;
- 提供多种选项来自定义输出;
- 默认情况下输出 ASCII 安全,在需要时使用转义序列;
- 新特性:完整的 TypeScript 支持和全面的类型定义;
- 新特性:原生 ES 模块,支持 tree-shaking;
- 新特性:现代开发工具链和改进的性能。
对于任何输入,jsesc-es 都会生成最短的有效可打印 ASCII 输出。这里有一个在线演示。
jsesc-es 的输出可以用来替代 JSON.stringify 的输出,以避免乱码和其他编码问题,甚至可以避免错误,当向 JavaScript 解析器或 UTF-8 编码器传递 JSON 格式数据(可能包含 U+2028 行分隔符、U+2029 段落分隔符或孤立代理)时。
✨ jsesc-es 的新特性
🔥 TypeScript 优先
- 内置类型定义 - 无需
@types/jsesc - 完整类型安全 和全面的
JsescOptions接口 - 更好的 IDE 支持 包括 IntelliSense 和自动补全
- 编译时类型安全选项验证
📦 现代模块系统
- 原生 ES 模块 支持 tree-shaking
- 多种导入样式 - 默认导入、命名导入或混合导入
- CommonJS 兼容性 用于传统项目
- 优化的包大小 配合现代构建工具
⚡ 增强性能
- 改进的函数处理 更好的类型检测
- 优化的转义逻辑 适用于常见用例
- 现代 JavaScript 特性 提供更好的性能
- 相比原版减少的包开销
🛠️ 开发体验
- 现代工具链 使用 Vitest、tsdown 和 pnpm
- 更好的错误消息 集成 TypeScript
- 全面的测试覆盖 包含类型检查
- 积极维护 定期更新
安装
# pnpm(推荐)- https://pnpm.io/
pnpm add jsesc-es
# yarn - https://yarnpkg.com/
yarn add jsesc-es
# npm - https://www.npmjs.com/
npm install jsesc-es
# 或其他运行时如...
# bun - https://bun.sh/
bun add jsesc-es
# deno - https://deno.land/
deno add jsesc-es使用方法
ES 模块(推荐)
// 默认导入(最常见)
import jsesc from 'jsesc-es'
// 命名导入
import { jsesc } from 'jsesc-es'
// 带类型导入
import type { JsescOptions } from 'jsesc-es'
import jsesc from 'jsesc-es'
// 导入版本信息
import { version } from 'jsesc-es'
// 混合导入(不推荐)
import jsesc, { version } from 'jsesc-es'TypeScript 使用
import type { JsescOptions } from 'jsesc-es'
import jsesc from 'jsesc-es'
// 类型安全的选项
const options: JsescOptions = {
quotes: 'single',
wrap: true,
es6: true,
minimal: false
}
// 类型安全的函数使用
function escapeForHTML(input: string): string {
return jsesc(input, {
quotes: 'double',
wrap: true,
isScriptContext: true
})
}
// 类型安全的配置对象
const configs = {
json: { json: true } as JsescOptions,
minimal: { minimal: true } as JsescOptions,
es6: { es6: true, quotes: 'backtick' } as JsescOptions
}CommonJS(传统支持)
// CommonJS require(仍然支持)
const jsesc = require('jsesc-es')
// 动态导入(现代替代方案)
const { jsesc } = await import('jsesc-es')Node.js ESM
确保您的 package.json 包含:
{
"type": "module"
}或使用 .mjs 文件扩展名:
// app.mjs
import jsesc from 'jsesc-es'API
jsesc(value, options?)
此函数接受一个值并返回该值的转义版本,其中任何非可打印 ASCII 符号的字符都使用最短可能(但有效的)JavaScript 字符串转义序列进行转义。第一个支持的值类型是字符串:
jsesc('Ich ♥ Bücher')
// → 'Ich \\u2665 B\\xFCcher'
jsesc('foo 𝌆 bar')
// → 'foo \\uD834\\uDF06 bar'除了字符串,value 也可以是数组、对象、map、set、数字、BigInt 或 buffer。在这种情况下,jsesc 返回值的字符串化版本,其中任何非可打印 ASCII 符号的字符都以相同方式转义。
// 转义数组
jsesc([
'Ich ♥ Bücher',
'foo 𝌆 bar'
])
// → '[\'Ich \\u2665 B\\xFCcher\',\'foo \\uD834\\uDF06 bar\']'
// 转义对象
jsesc({
'Ich ♥ Bücher': 'foo 𝌆 bar'
})
// → '{\'Ich \\u2665 B\\xFCcher\':\'foo \\uD834\\uDF06 bar\'}'配置选项
可选的 options 参数接受一个具有以下选项的对象。在 TypeScript 中,使用 JsescOptions 类型获得完整的类型安全:
import type { JsescOptions } from 'jsesc-es'
const options: JsescOptions = {
// 您的选项在这里,享有完整的 IntelliSense 支持
}quotes
quotes 选项的默认值是 'single'。这意味着输入字符串中出现的任何 ' 都被转义为 \',以便输出可以在用单引号包裹的字符串字面量中使用。
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.')
// → 'Lorem ipsum "dolor" sit \\\'amet\\\' etc.'
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
quotes: 'single'
})
// → '`Lorem` ipsum "dolor" sit \\\'amet\\\' etc.'如果您想将输出用作用双引号包裹的字符串字面量的一部分,请将 quotes 选项设置为 'double'。
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
quotes: 'double'
})
// → '`Lorem` ipsum \\"dolor\\" sit \'amet\' etc.'如果您想将输出用作模板字面量(即用反引号包裹)的一部分,请将 quotes 选项设置为 'backtick'。
jsesc('`Lorem` ipsum "dolor" sit \'amet\' etc.', {
quotes: 'backtick'
})
// → '\\`Lorem\\` ipsum "dolor" sit \'amet\' etc.'numbers
numbers 选项的默认值是 'decimal'。这意味着任何数值都使用十进制整数字面量表示。其他有效选项是 binary、octal 和 hexadecimal。
jsesc(42, { numbers: 'binary' })
// → '0b101010'
jsesc(42, { numbers: 'octal' })
// → '0o52'
jsesc(42, { numbers: 'decimal' })
// → '42'
jsesc(42, { numbers: 'hexadecimal' })
// → '0x2A'wrap
wrap 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输出是一个有效的 JavaScript 字符串字面量,用引号包裹。
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
quotes: 'single',
wrap: true
})
// → '\'Lorem ipsum "dolor" sit \\\'amet\\\' etc.\''
jsesc('Lorem ipsum "dolor" sit \'amet\' etc.', {
quotes: 'double',
wrap: true
})
// → '"Lorem ipsum \\"dolor\\" sit \'amet\' etc."'es6
es6 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输入中的任何星界 Unicode 符号都使用 ECMAScript 6 Unicode 代码点转义序列进行转义。
// 默认情况下,`es6` 选项是禁用的:
jsesc('foo 𝌆 bar 💩 baz')
// → 'foo \\uD834\\uDF06 bar \\uD83D\\uDCA9 baz'
// 启用它:
jsesc('foo 𝌆 bar 💩 baz', {
es6: true
})
// → 'foo \\u{1D306} bar \\u{1F4A9} baz'escapeEverything
escapeEverything 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输出中的所有符号都被转义——甚至是可打印的 ASCII 符号。
jsesc('lolwat"foo\'bar', {
escapeEverything: true
})
// → '\\x6C\\x6F\\x6C\\x77\\x61\\x74\\"\\x66\\x6F\\x6F\\\'\\x62\\x61\\x72'minimal
minimal 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输出中只有有限的符号集合被转义。
注意: 启用此选项后,jsesc-es 的输出不再保证是 ASCII 安全的。
jsesc('foo\u2029bar\nbaz©qux𝌆flops', {
minimal: true
})
// → 'foo\\u2029bar\\nbaz©qux𝌆flops'isScriptContext
isScriptContext 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输出中出现的 </script 和 </style 被转义。
jsesc('foo</script>bar', {
isScriptContext: true
})
// → 'foo<\\/script>bar'compact
compact 选项接受布尔值(true 或 false),默认为 true(启用)。启用时,数组和对象的输出尽可能紧凑。
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
compact: true // 这是默认值
})
// → '{\'Ich \u2665 B\xFCcher\':\'foo \uD834\uDF06 bar\'}'
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
compact: false
})
// → '{\n\t\'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'indent
indent 选项接受字符串值,默认为 '\t'。当 compact 设置禁用(false)时,indent 选项的值用于格式化输出。
jsesc({ 'Ich ♥ Bücher': 'foo 𝌆 bar' }, {
compact: false,
indent: ' '
})
// → '{\n \'Ich \u2665 B\xFCcher\': \'foo \uD834\uDF06 bar\'\n}'indentLevel
indentLevel 选项接受数值,默认为 0。它表示当前的缩进级别。
jsesc(['a', 'b', 'c'], {
compact: false,
indentLevel: 1
})
// → '[\n\t\t\'a\',\n\t\t\'b\',\n\t\t\'c\'\n\t]'json
json 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,输出是有效的 JSON。
jsesc('foo\x00bar\xFF\uFFFDbaz', {
json: true
})
// → '"foo\\u0000bar\\u00FF\\uFFFDbaz"'
jsesc({ 'foo\x00bar\xFF\uFFFDbaz': 'foo\x00bar\xFF\uFFFDbaz' }, {
json: true
})
// → '{"foo\\u0000bar\\u00FF\\uFFFDbaz":"foo\\u0000bar\\u00FF\\uFFFDbaz"}'lowercaseHex
lowercaseHex 选项接受布尔值(true 或 false),默认为 false(禁用)。启用时,转义序列中的任何字母十六进制数字都是小写的。
jsesc('Ich ♥ Bücher', {
lowercaseHex: true
})
// → 'Ich \\u2665 B\\xfccher'
// ^^
jsesc(42, {
numbers: 'hexadecimal',
lowercaseHex: true
})
// → '0x2a'
// ^^版本信息
// 访问版本信息
import jsesc, { version } from 'jsesc-es'
console.log(jsesc.version) // 例如:"0.0.3"
console.log(version) // 例如:"0.0.3"从 jsesc 迁移
从原始 jsesc 库迁移很简单:
1. 更新依赖
# 移除旧包
npm uninstall jsesc
# 安装新包
npm install jsesc-es2. 更新导入
// 之前(CommonJS)
const jsesc = require('jsesc')
// 之后(ES 模块)
import jsesc from 'jsesc-es'
// 或带类型(TypeScript)
import jsesc, { type JsescOptions } from 'jsesc-es'3. 享受增强功能
- 完整的 TypeScript 支持 无需额外设置
- 更好的 IDE 体验 包括 IntelliSense
- 现代模块系统 支持 tree-shaking
- 100% API 兼容 - 无需代码更改
详细的迁移说明,请参见 MIGRATION.md。
TypeScript 示例
创建工具函数
import type { JsescOptions } from 'jsesc-es'
import jsesc from 'jsesc-es'
// 创建类型安全的工具函数
function createEscaper(defaultOptions: JsescOptions) {
return (input: string, options?: Partial<JsescOptions>): string => {
return jsesc(input, { ...defaultOptions, ...options })
}
}
// 预配置的转义器
const escapeForHTML = createEscaper({
quotes: 'double',
wrap: true,
isScriptContext: true
})
const escapeForJSON = createEscaper({
json: true
})
const escapeMinimal = createEscaper({
minimal: true
})
// 具有完整类型安全的使用
const htmlSafe = escapeForHTML('Hello "World"')
const jsonSafe = escapeForJSON({ message: 'Hello 世界' })
const minimalEscape = escapeMinimal('简单文本')高级配置
import type { JsescOptions } from 'jsesc-es'
// 定义配置预设
const PRESETS: Record<string, JsescOptions> = {
html: {
quotes: 'double',
wrap: true,
isScriptContext: true,
escapeEverything: false
},
json: {
json: true,
compact: true
},
es6: {
es6: true,
quotes: 'backtick',
wrap: true
},
debug: {
escapeEverything: true,
compact: false,
indent: ' '
}
} as const
// 类型安全的预设使用
function escapeWithPreset(
input: any,
preset: keyof typeof PRESETS,
overrides?: Partial<JsescOptions>
): string {
const config = { ...PRESETS[preset], ...overrides }
return jsesc(input, config)
}性能
jsesc-es 相比原版包含几项性能改进:
- 优化的类型检查 提供更好的运行时性能
- 改进的函数处理 增强的检测逻辑
- 现代 JavaScript 特性 更好的引擎优化
- 常见转义场景中的开销减少
- Tree-shaking 支持 更小的包大小
浏览器支持
jsesc-es 通过其双构建系统提供广泛的兼容性:
运行时要求
对于 ES 模块(推荐):
- Node.js:14+(原生 ESM 支持)
- 浏览器:Chrome 61+、Firefox 60+、Safari 10.1+、Edge 16+
- ES 模块:需要原生支持
对于 CommonJS(传统):
- Node.js:6+(转译输出)
- 浏览器:Chrome 27+、Firefox 3+、Safari 4+、Opera 10+(使用打包器)
构建目标 vs. 模块系统
虽然 jsesc-es 通过其转译的 CommonJS 构建保持与传统环境的兼容性(目标 node6、chrome27 等),ES 模块需要原生支持 import/export 语法的现代环境。构建目标确保 JavaScript 语法和 API 在较旧环境中工作,但 模块系统本身 有最低版本要求。
要点:
- 📦 CommonJS 构建:在非常旧的环境中工作(Node 6+、Chrome 27+)
- 🚀 ESM 构建:需要具有原生 ESM 支持的现代环境
- 🔧 传统项目:使用 CommonJS 或使用 Babel/TypeScript 转译 ESM
- ⚡ 现代项目:使用 ESM 获得更好的 tree-shaking 和性能
TypeScript 支持
- TypeScript:4.5+
- 内置类型:无需
@types/包
开发
# 克隆仓库
git clone https://github.com/Drswith/jsesc-es.git
cd jsesc-es
# 安装依赖
pnpm install
# 运行测试
pnpm test
# 构建项目
pnpm build
# 类型检查
pnpm typecheck
# 代码检查
pnpm lint贡献
欢迎贡献!请阅读我们的贡献指南了解行为准则和提交拉取请求的流程详情。
许可证
本项目采用 MIT 许可证 - 详情请参见 LICENSE 文件。
致谢
- Mathias Bynens - 原始 jsesc 库的创建者
- TypeScript 团队 - 提供出色的工具和类型系统
- 开源社区 - 持续的反馈和贡献
jsesc-es - 现代的、TypeScript 优先的 JavaScript 字符串转义方法。🚀
