方式一:yaml库。 功能强大,支持对注释处理。推荐
先来看一个例子,读取yaml文件处理后写回yaml文件:
const YAML = require('yaml');
const updir = ps.join(PROJECT_DIR, `../../`,);
try {
const gatewayConfPath = `${updir}/gateway/config/gateway.config.yml`;
const gatewayDoc = YAML.parseDocument(fs.readFileSync(gatewayConfPath, 'utf8'));
const baseDoc = YAML.parseDocument(ymlContent || fs.readFileSync(`${updir}/backend/base.yml`, 'utf8'));
//判断gatewayDoc中是否存在apiEndpoints.lbname,不存在则添加baseDoc中的apiEndpoints.lbname
!gatewayDoc.hasIn(['apiEndpoints', lbname]) && gatewayDoc.setIn(['apiEndpoints', lbname], baseDoc.getIn(['apiEndpoints', lbname]));
!gatewayDoc.hasIn(['serviceEndpoints', lbname]) && gatewayDoc.setIn(['serviceEndpoints', lbname], baseDoc.getIn(['serviceEndpoints', lbname]));
!gatewayDoc.hasIn(['pipelines', lbname]) && gatewayDoc.setIn(['pipelines', lbname], baseDoc.getIn(['pipelines', lbname]));
fs.writeFileSync(gatewayConfPath, YAML.stringify(gatewayDoc));
} catch (e) {
console.log(e);
}
下面是yaml库中的一些概念和方法属性的介绍:
const YAML = require('yaml'); //引入yaml库
const doc = YAML.parseDocument(fs.readFileSync('./file.yml', 'utf8')); // yaml转为document对象。 (ps:也可以使用new Document(['some', 'values', { balloons: 99 }]) 创建document)
console.log(doc.contents)//The contents of a parsed document will always consist of Scalar, YAMLMap, YAMLSeq or null values.
// YAMLMap {
// items:
// [ Pair {
// key: Scalar { value: 'YAML', range: [ 0, 4, 4 ] },
// value:
// YAMLSeq {
// items:
// [ Scalar {
// value: 'A human-readable data serialization language',
// range: [ 10, 54, 55 ] },
// Scalar {
// value: 'https://en.wikipedia.org/wiki/YAML',
// range: [ 59, 93, 94 ] } ],
// range: [ 8, 94, 94 ] } },
// Pair {
// key: Scalar { value: 'yaml', range: [ 94, 98, 98 ] },
// value:
// YAMLSeq {
// items:
// [ Scalar {
// value: 'A complete JavaScript implementation',
// range: [ 104, 140, 141 ] },
// Scalar {
// value: 'https://www.npmjs.com/package/yaml',
// range: [ 145, 180, 180 ] } ],
// range: [ 102, 180, 180 ] } } ],
// range: [ 0, 180, 180 ] }
在所有 YAML 文档中,支持两种形式的集合:顺序YAMLSeq集合和键值YAMLMap集合。这些集合的 JavaScript 表示形式都有一个items数组,该数组可以 ( YAMLSeq) 或必须 ( YAMLMap) 由Pair对象组成,Pair包含 key和 任何类型的value,包括null。 YAMLSeq对象的items数组可以包含任何类型的值。
Scalar: 已解析文档的内容将把其所有非对象值包装在Scalar对象中,这些对象本身可能位于YAMLMap和YAMLSeq集合的某个层次结构中。但是,这不是文档的字符串化的要求,它对其输入值相当宽容,并且在遇到未包装的值时将使用doc.createNode()
Document中常用属性、方法:
commentBefore:文档最前面的注释
comment:文档最后的注释
contents:文档的内容
schema: 文档的schema
add(value), addIn(path, value) add是在顶层节点添加,addIn是在指定路径添加.下同
delete(key), deleteIn(path)
get(key, [keep]), getIn(path, [keep])
has(key), hasIn(path)
set(key, value), setIn(path, value)
举例说明:
const doc = new YAML.Document({ a: 1, b: [2, 3] }) // { a: 1, b: [ 2, 3 ] }
doc.add({ key: 'c', value: 4 }) // { a: 1, b: [ 2, 3 ], c: 4 }
doc.addIn(['b'], 5) // { a: 1, b: [ 2, 3, 5 ], c: 4 }
doc.set('c', 42) // { a: 1, b: [ 2, 3, 5 ], c: 42 }
doc.delete('c') // { a: 1, b: [ 2, 3, 5 ] }
doc.deleteIn(['b', 1]) // { a: 1, b: [ 2, 5 ] }
转为js or json格式(ps:转为js json中注释会丢失,若不想丢失需parseDocument转为document对象,操作document)
YAML.parse(fs.readFileSync('./file.yml', 'utf8'))//转为js对象 {xx:xx}
YAML.parse('[ true, false, maybe, null ]\n')// [ true, false, 'maybe', null ]
YAML.stringify(3.14159) //转为字符串 '3.14159\n'
doc.toJS() //转为js对象 {xx:xx}
doc.toString() //转为字符串
方式二:js-yaml库 功能不如yaml强大,无法保留注释
(ps:作者说不打算兼容保留注释相关功能,因为相当于重构了,如果需要此功能需要用其他框架)
读取yaml处理后写回yaml文件:
const yaml = require('js-yaml');
const updir = ps.join(PROJECT_DIR, `../../`,);
try {
const gatewayConfPath = `${updir}/gateway/config/gateway.config.yml`;
const gatewayConf = yaml.load(fs.readFileSync(gatewayConfPath, 'utf8')); //加载yaml文件
const base = yaml.load(ymlContent || fs.readFileSync(`${updir}/backend/base.yml`, 'utf8'));
_.defaultsDeep(gatewayConf, base); //合并对象
const yamlStr = yaml.dump(gatewayConf); //转为yaml字符串
fs.writeFileSync(gatewayConfPath, yamlStr); //写入yaml文件
} catch (e) {
console.log(e);
}