What is comment-json?
The comment-json npm package allows you to parse, modify, and stringify JSON files while preserving comments. This is particularly useful for configuration files where comments are often used to provide context or instructions.
What are comment-json's main functionalities?
Parsing JSON with comments
This feature allows you to parse JSON strings that include comments. The comments are ignored in the resulting JavaScript object.
const commentJson = require('comment-json');
const jsonWithComments = `{
// This is a comment
"key": "value"
}`;
const parsed = commentJson.parse(jsonWithComments);
console.log(parsed); // { key: 'value' }
Stringifying JSON with comments
This feature allows you to convert a JavaScript object back into a JSON string, optionally including comments.
const commentJson = require('comment-json');
const obj = { key: 'value' };
const jsonString = commentJson.stringify(obj, null, 2);
console.log(jsonString); // {
// This is a comment
"key": "value"
}
Modifying JSON while preserving comments
This feature allows you to modify a parsed JSON object and then convert it back to a JSON string, preserving the original comments.
const commentJson = require('comment-json');
const jsonWithComments = `{
// This is a comment
"key": "value"
}`;
let parsed = commentJson.parse(jsonWithComments);
parsed.newKey = 'newValue';
const modifiedJsonString = commentJson.stringify(parsed, null, 2);
console.log(modifiedJsonString); // {
// This is a comment
"key": "value",
"newKey": "newValue"
}
Other packages similar to comment-json
json5
JSON5 is a JSON extension that aims to make JSON more human-friendly. It allows comments, trailing commas, and more. However, unlike comment-json, JSON5 does not preserve comments when parsing and stringifying.
hjson
Hjson is a user interface for JSON. It allows comments and is designed to be easy to read and write. Similar to JSON5, Hjson does not preserve comments when converting between JSON and JavaScript objects.
jsonc-parser
The jsonc-parser package is used by Visual Studio Code to handle JSON with comments. It can parse JSON with comments and provide a syntax tree, but it is more complex to use compared to comment-json.
- Parse JSON strings with comments into JavaScript objects and MAINTAIN comments
- supports comments everywhere, yes, EVERYWHERE in a JSON file, eventually 😆
- fixes the known issue about comments inside arrays.
- Stringify the objects into JSON strings with comments if there are
The usage of comment-json
is exactly the same as the vanilla JSON
object.
Install
$ npm i comment-json
Usage
package.json:
{
"name": "comment-json"
}
const {
parse,
stringify
} = require('comment-json')
const fs = require('fs')
const obj = parse(fs.readFileSync('package.json').toString())
console.log(obj.name)
stringify(obj, null, 2)
parse()
parse(text, reviver? = null, remove_comments? = false)
: object | string | number | boolean | null
- text
string
The string to parse as JSON. See the JSON object for a description of JSON syntax. - reviver?
Function() | null
Default to null
. It acts the same as the second parameter of JSON.parse
. If a function, prescribes how the value originally produced by parsing is transformed, before being returned. - remove_comments?
boolean = false
If true, the comments won't be maintained, which is often used when we want to get a clean object.
Returns object | string | number | boolean | null
corresponding to the given JSON text.
If the content
is:
{
"foo" :
1
,
"bar": [
"baz"
,
"quux"
]
}
const parsed = parse(content)
console.log(parsed)
And the result will be:
{
[Symbol.for('before-all')]: [{
type: 'BlockComment',
value: '\n before-all\n ',
inline: false
}, {
type: 'LineComment',
value: ' before-all',
inline: false
}],
...
[Symbol.for('after-prop:foo')]: [{
type: 'BlockComment',
value: ' after-prop:foo ',
inline: true
}],
foo: 1,
bar: [
"baz",
"quux",
[Symbol.for('after-value:0')]: [{
type: 'LineComment',
value: ' after-value:0',
inline: true
}, ...],
...
]
}
There are EIGHT kinds of symbol properties:
Symbol.for('before-all')
Symbol.for('before')
Symbol.for(`before:${prop}`)
Symbol.for(`after-prop:${prop}`)
Symbol.for(`after-colon:${prop}`)
Symbol.for(`after-value:${prop}`)
Symbol.for('after')
Symbol.for('after-all')
And the value of each symbol property is an array of CommentToken
interface CommentToken {
type: 'BlockComment' | 'LineComment'
value: string
inline: boolean
}
console.log(parse(content, null, true))
And the result will be:
{
foo: 1,
bar: [
"baz",
"quux"
]
}
Special cases
const parsed = parse(`
// comment
1
`)
console.log(parsed === 1)
If we parse a JSON of primative type with remove_comments:false
, then the return value of parse()
will be of object type.
The value of parsed
is equivalent to:
const parsed = new Number(1)
parsed[Symbol.for('before-all')] = [{
type: 'LineComment',
value: ' comment',
inline: false
}]
Which is similar for:
For example
const parsed = parse(`
"foo" /* comment */
`)
Which is equivalent to
const parsed = new String('foo')
parsed[Symbol.for('after-all')] = [{
type: 'BlockComment',
value: ' comment ',
inline: true
}]
But there is one exception:
const parsed = parse(`
// comment
null
`)
console.log(parsed === null)
stringify()
stringify(object: any, replacer?, space?): string
The arguments are the same as the vanilla JSON.stringify
.
And it does the similar thing as the vanilla one, but also deal with extra properties and convert them into comments.
console.log(stringify(parsed, null, 2))
space
If space is not specified, or the space is an empty string, the result of stringify()
will have no comments.
For the case above:
console.log(stringify(result))
console.log(stringify(result, null, 2))
License
MIT