Thom
Thom

Reputation: 553

Requiring a JSON with comments in node.js

If you use typescript you can init a default tsconfig.json, and that json will have javascript // and /* */ comments in it. I've encountered a situation with ts-jest where I need to require my tsconfig and parse it, but jest is not parsing it because json doesn't allow comments. see this I'm not sure how typescript handles it, but it seems to deviate from the rule.

// this fails if tsconfig has comments
const tsconfig = require('./tsconfig')

I want to keep the comments because they are really helpful to understand and maintain my tsconfig.json, and I want to require my config to be able to avoid duplicating code and make things more dynamic.

Is there a way to require a json file with comments using nodejs?

Upvotes: 4

Views: 4912

Answers (3)

Tom Hale
Tom Hale

Reputation: 46805

require-json5 is purpose-built for this:

const requireJSON5 = require('require-json5');
const tsconfig = requireJSON5('./tsconfig.json');

Or even more simply:

require('require-json5').replace();
var tsconfig = require("./tsconfig");

Upvotes: 3

Michael Veksler
Michael Veksler

Reputation: 8475

json5 can do the trick. Install JSON5 and then:

const JSON5 = require('json5');
const tsconfig = JSON5.parse(jsontxt);

Note that removing comments by yourself is possible but has several pitfalls, and that's why it's not recommended. You should look for:

  • Strings may contain sequences that look like comments, only they are not.
  • Comments may contain sequences that look like string beginning, only they are not.
  • Strings may contain " that don't mark string end such as "foo\"bar". It's more confusing with "foo\\", where the second " does end the string.
  • A // comment may contain /*, but that does not start a multi line comment.
  • A // in a multi line comment does not start a single-line comment, such that removing comments in /* // */ "hi" results with "hi".
  • Does a \ continue a single-line to the next line? Does a \*/ end a multi line comment, or does the \ make the * act differently? (Neither are supported in JavaScript).
  • are multi line strings supported (they are in JavaScript)? How are they declared/dealt with.

Upvotes: 9

Thom
Thom

Reputation: 553

I managed to do it by pre-processing the json to strip the comments. The following code is doing the job for me:

const fs = require('fs')
const stripForwardSlashForwardSlashComment = new RegExp('//(.*)', 'g')
const stripForwardSlashStarComment = new RegExp('[/][*](.*)[*][/]', 'gm')
let jsontxt = fs.readFileSync('./tsconfig.json', 'utf8')
jsontxt = jsontxt.replace(stripForwardSlashForwardSlashComment,'').replace(stripForwardSlashStarComment, '')
const tsconfig = JSON.parse(jsontxt)

Self answer note: Posting to keep this public and get some feedback

Upvotes: 0

Related Questions