如何用js-yaml生成保留引号的有效Docker Compose文件?
解决js-yaml生成Docker Compose时保留指定字段引号的问题
核心方案
js-yaml默认遵循YAML规范,仅对含特殊字符的字符串自动添加引号。要强制给command、image、network_mode这类字段保留引号,有以下几种可靠实现方式:
1. 自定义类型标签强制加引号
通过扩展js-yaml的Schema,定义一个强制输出双引号的字符串类型,标记需要保留引号的字段:
const yaml = require('js-yaml'); // 定义强制双引号的自定义字符串类型 const QuotedString = new yaml.Type('!str', { kind: 'scalar', resolve: data => typeof data === 'string', construct: data => data, represent: data => `"${data}"` }); // 扩展默认Schema,加入自定义类型 const customSchema = yaml.DEFAULT_SCHEMA.extend([QuotedString]); // 配置Docker Compose时,给需要引号的字段加上自定义标签 const composeConfig = { version: '3.8', services: { dotnet-app: { image: '!str mcr.microsoft.com/dotnet/aspnet:8.0', command: '!str ["dotnet", "TeamTemplate.dll"]', network_mode: '!str bridge' } } }; // 使用自定义Schema序列化 const yamlContent = yaml.dump(composeConfig, { schema: customSchema }); console.log(yamlContent);
输出的YAML会保留指定字段的引号:
version: '3.8' services: dotnet-app: image: "mcr.microsoft.com/dotnet/aspnet:8.0" command: "[\"dotnet\", \"TeamTemplate.dll\"]" network_mode: "bridge"
2. 通过styles参数指定字段样式
如果仅需针对个别字段设置引号,可直接在dump方法中通过styles配置指定字符串样式为双引号:
const yaml = require('js-yaml'); const composeConfig = { version: '3.8', services: { dotnet-app: { image: 'mcr.microsoft.com/dotnet/aspnet:8.0', command: '["dotnet", "TeamTemplate.dll"]', network_mode: 'bridge' } } }; const yamlContent = yaml.dump(composeConfig, { styles: { '!!str': { image: '"', command: '"', network_mode: '"' } } }); console.log(yamlContent);
3. 不推荐:手动加引号+关闭转义
虽然可以给字符串手动添加引号,但需要关闭js-yaml的转义逻辑,这种方式容易因字段内容含特殊字符引发格式问题,仅临时场景可用:
const yamlContent = yaml.dump(composeConfig, { noCompatMode: true, quotingType: '"' });
关于json2yaml的差异
json2yaml默认给所有字符串添加引号,而js-yaml遵循YAML规范自动判断是否需要引号。要对齐json2yaml的输出效果,必须通过上述自定义规则强制添加引号。
内容的提问来源于stack exchange,提问作者Meester Over
相关产品推荐
相关产品推荐

