js-yaml
js-yaml 是一个 Node.js 或浏览器通用的 YAML 解析 & 序列化库, JS 对象 ↔ YAML 文本 互转,读写 .yml/.yaml 配置文件。
特点
- 纯
JS编写,无依赖 - 支持
YAML 1.2全语法 - 区分安全 / 不安全解析,防注入
- 可读写本地
YAML配置文件 - 配合
config包做项目环境配置首选
安装
bash
npm install js-yaml --save1
基本用法
推荐使用 safeLoad
出于安全考虑,推荐默认使用 yaml.safeLoad() 而非 yaml.load():
safeLoad()只解析标准 YAML 类型,防止代码注入攻击load()支持自定义 JS 类型(如!!js/function),可能执行恶意代码- 仅在需要解析自定义类型时才使用
load()
1. YAML 字符串 → JS 对象
使用 yaml.safeLoad() 解析 YAML 字符串(推荐):
javascript
const yaml = require('js-yaml');
const yamlStr = `
name: myapp
version: 1.0.0
database:
host: localhost
port: 3306
name: mydb
`;
// ✅ 推荐:使用 safeLoad 防止代码注入
const config = yaml.safeLoad(yamlStr);
console.log(config);
// 输出:
// {
// name: 'myapp',
// version: '1.0.0',
// database: { host: 'localhost', port: 3306, name: 'mydb' }
// }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2. JS 对象 → YAML 字符串
使用 yaml.dump() 将 JS 对象序列化为 YAML 字符串:
javascript
const yaml = require('js-yaml');
const config = {
name: 'myapp',
version: '1.0.0',
database: {
host: 'localhost',
port: 3306,
name: 'mydb'
}
};
const yamlStr = yaml.dump(config);
console.log(yamlStr);
// 输出:
// name: myapp
// version: 1.0.0
// database:
// host: localhost
// port: 3306
// name: mydb1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
3. 读取 YAML 文件
javascript
const yaml = require('js-yaml');
const fs = require('fs');
try {
// ✅ 推荐:使用 safeLoad 读取文件
const config = yaml.safeLoad(fs.readFileSync('./config.yml', 'utf8'));
console.log(config.database.host); // localhost
} catch (e) {
console.log('读取配置文件失败:', e);
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
4. 写入 YAML 文件
javascript
const yaml = require('js-yaml');
const fs = require('fs');
const config = {
app: {
name: 'myapp',
port: 3000
},
db: {
host: 'localhost',
port: 3306
}
};
fs.writeFileSync('./config.yml', yaml.dump(config), 'utf8');
console.log('配置文件已写入');1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
API 详解
yaml.safeLoad(yamlString, options) ✅ 推荐
将 YAML 字符串安全解析为 JS 对象,只支持标准 YAML 类型。
参数:
yamlString(string): YAML 格式的字符串options(object, 可选): 解析选项
常用选项:
javascript
yaml.safeLoad(yamlStr, {
filename: 'config.yml', // 用于错误提示
onWarning: (warning) => console.log(warning), // 警告回调
schema: yaml.DEFAULT_SAFE_SCHEMA // 安全 schema(默认)
});1
2
3
4
5
2
3
4
5
yaml.load(yamlString, options) ⚠️ 谨慎使用
将 YAML 字符串解析为 JS 对象,支持自定义 JS 类型(可能存在安全风险)。
安全警告
load() 支持解析 !!js/function、!!js/regexp 等自定义类型,可能导致代码注入攻击。 仅在需要解析自定义类型时使用,否则请使用 safeLoad()。
参数:
yamlString(string): YAML 格式的字符串options(object, 可选): 解析选项
常用选项:
javascript
yaml.load(yamlStr, {
filename: 'config.yml', // 用于错误提示
onWarning: (warning) => console.log(warning), // 警告回调
schema: yaml.DEFAULT_FULL_SCHEMA, // 完整 schema(支持自定义类型)
json: false // 是否兼容 JSON
});1
2
3
4
5
6
2
3
4
5
6
yaml.dump(object, options)
将 JS 对象序列化为 YAML 字符串。
参数:
object(object): 要序列化的 JS 对象options(object, 可选): 序列化选项
常用选项:
javascript
yaml.dump(obj, {
indent: 2, // 缩进空格数,默认 2
lineWidth: 80, // 每行最大宽度,默认 80
noRefs: false, // 是否忽略循环引用
sortKeys: false, // 是否按键排序
skipInvalid: false, // 是否跳过无效值
flowLevel: -1 // 流式风格的嵌套层级
});1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
yaml.loadAll(yamlString, iterator, options)
解析包含多个文档的 YAML 字符串(用 --- 分隔):
javascript
const yamlStr = `
---
name: doc1
---
name: doc2
`;
const docs = yaml.loadAll(yamlStr);
console.log(docs);
// 输出: [{ name: 'doc1' }, { name: 'doc2' }]1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
实际应用示例
1. 多环境配置管理
yaml
app:
name: myapp
port: 3000
database:
host: localhost
port: 3306
name: mydb1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
yaml
database:
host: 10.0.0.5
port: 3306
logging:
level: error1
2
3
4
5
6
2
3
4
5
6
javascript
const yaml = require('js-yaml');
const fs = require('fs');
const path = require('path');
function loadConfig(env = 'development') {
// 加载默认配置
const defaultConfig = yaml.safeLoad(
fs.readFileSync(path.join(__dirname, 'config/default.yml'), 'utf8')
);
// 加载环境配置
const envConfigPath = path.join(__dirname, `config/${env}.yml`);
let envConfig = {};
if (fs.existsSync(envConfigPath)) {
envConfig = yaml.safeLoad(fs.readFileSync(envConfigPath, 'utf8'));
}
// 合并配置
return { ...defaultConfig, ...envConfig };
}
const config = loadConfig(process.env.NODE_ENV || 'development');
console.log(config);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2. 与 config 包配合使用
javascript
// 在 node-config 中使用 YAML 格式
// 只需安装 js-yaml,node-config 会自动识别 .yml 文件
// config/default.yml
/*
app:
name: myapp
port: 3000
*/
const config = require('config');
console.log(config.get('app.name')); // myapp1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
3. 安全解析(防止注入)
javascript
const yaml = require('js-yaml');
// 使用 safeLoad 防止代码注入
const untrustedYaml = `
!!js/function "function(){return process.exit(1)}"
`;
// ❌ 危险:可能执行恶意代码
// const result = yaml.load(untrustedYaml);
// ✅ 安全:只解析标准 YAML 类型
const safeResult = yaml.safeLoad(untrustedYaml);1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
4. 自定义 YAML 类型
javascript
const yaml = require('js-yaml');
// 定义自定义类型
const PersonType = new yaml.Type('!person', {
kind: 'mapping',
construct: (data) => {
return { name: data.name, age: data.age, type: 'Person' };
}
});
const CUSTOM_SCHEMA = yaml.DEFAULT_SCHEMA.extend({ implicit: [], explicit: [PersonType] });
const yamlStr = `
!person
name: Alice
age: 30
`;
const person = yaml.load(yamlStr, { schema: CUSTOM_SCHEMA });
console.log(person); // { name: 'Alice', age: 30, type: 'Person' }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注意事项
1. 安全性
- 使用
safeLoad()代替load()处理不可信的 YAML 内容 safeLoad()只解析标准 YAML 类型,防止代码注入
javascript
// ✅ 推荐:处理不可信内容
const config = yaml.safeLoad(untrustedYamlString);
// ⚠️ 谨慎:仅用于可信内容
const config = yaml.load(trustedYamlString);1
2
3
4
5
2
3
4
5
2. 性能优化
对于大型 YAML 文件,可以使用流式处理:
javascript
const yaml = require('js-yaml');
const fs = require('fs');
// 使用流式读取
const stream = fs.createReadStream('./large-config.yml', 'utf8');
let data = '';
stream.on('data', (chunk) => {
data += chunk;
});
stream.on('end', () => {
const config = yaml.safeLoad(data);
console.log('配置加载完成');
});1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
3. 错误处理
javascript
try {
const config = yaml.safeLoad(yamlStr);
} catch (e) {
if (e instanceof yaml.YAMLException) {
console.error('YAML 解析错误:', e.message);
console.error('位置: 行', e.mark.line, '列', e.mark.column);
} else {
console.error('其他错误:', e);
}
}1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
4. 编码问题
确保文件使用 UTF-8 编码:
javascript
const fs = require('fs');
const yaml = require('js-yaml');
// ✅ 正确:指定 UTF-8 编码,使用 safeLoad
const config = yaml.safeLoad(fs.readFileSync('./config.yml', 'utf8'));
// ❌ 错误:可能导致编码问题
const config = yaml.safeLoad(fs.readFileSync('./config.yml').toString());1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
常见问题
Q: YAML 和 JSON 有什么区别?
A: YAML 是 JSON 的超集,具有以下优势:
- 更易读:使用缩进而非括号
- 支持注释:
# 这是注释 - 支持多行字符串
- 支持更丰富的数据类型
Q: 如何处理循环引用?
A: 使用 noRefs 选项:
javascript
const obj = { a: 1 };
obj.self = obj; // 循环引用
const yamlStr = yaml.dump(obj, { noRefs: true });1
2
3
4
2
3
4
Q: 如何保留 YAML 注释?
A: js-yaml 不支持保留注释,解析后注释会丢失。如需保留注释,考虑使用其他库如 yaml。

