1

I'm in the process of converting a Grunt file to a Gulp file. My Grunt file contains the following line

var config = grunt.file.readJSON('json/config.json');

What this line is doing is that it is setting some variables which it then injects into the html it generates, specifically related to languages.

I tried converting the file automatically with grunt2gulp.js but it always fails with config being undefined. How would I write grunt.file.readJSON using gulp?

Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
Ali Samii
  • 1,672
  • 4
  • 28
  • 49

2 Answers2

4

The easiest way to load a JSON file in node/io.js is to use require directly:

var config = require('json/config.json');

This can substitute any readJSON calls you have and also works generally. Node/io.js have the ability to synchronously require json files out of the box.

Community
  • 1
  • 1
Benjamin Gruenbaum
  • 270,886
  • 87
  • 504
  • 504
  • Note that this won't work for files that don't end in `.js` or `.json` (like critical files such as `.jshintrc`, `.jsbeautifyrc` and `.jscsrc`). Node.js is hardcoded to accept-on-extension only, instead of just trying to parse it. – Mike 'Pomax' Kamermans Mar 05 '15 at 18:13
  • Yes that's true - but usually file extension is indicative of a type. It's super easy to teach `require` to deal with other extensions. – Benjamin Gruenbaum Mar 05 '15 at 18:14
  • usually, but certain automation-critical files that are perfectly valid json do not use that extension (rc files most notably), so for those `grunt.file.readJSON` was a blessing. I was looking for a `gulp` alternative to that, too – Mike 'Pomax' Kamermans Mar 05 '15 at 18:15
0

Since this is a .json file, Benjamin's answer works just fine (just require() it in).

If you have any configs that are valid JSON but not stored in files that end in a .json extension, you can use the jsonfile module to load them in, or use the slightly more verbose

JSON.parse(require('fs').readFileSync("...your file path here..."))

(if you have fs already loaded, this tends to be the path of least resistance)

The one big difference between require (which pretty much uses this code to load in json files) and this code is that require uses Node's caching mechanism, so multiple requires will only ever import the file once, and then return points to the parsed data, effectively making everything share the same data object. Sometimes that's great, sometimes it's absolutely disastrous, so keep that in mind

(If you absolutely need unique data, but you like the convenience of require, you can always do a quick var data = require("..."); copied = JSON.parse(JSON.stringify(data));)

Mike 'Pomax' Kamermans
  • 49,297
  • 16
  • 112
  • 153
  • It's super easy to add these hooks to `require` for other file extensions. There are advantages to using `require` (it's cached, and native) IMO. – Benjamin Gruenbaum Mar 07 '15 at 13:33
  • Interesting, do you have a link to docs? I've been using Node.js for a few years but have never seen anything but Node itself do that. As for native, [the code for loading .json](https://github.com/joyent/node/blob/ed7fb149a20ee5e7aa9a0574a242a193d7acd761/lib/module.js#L471-L480) is pretty much this code, the only real difference is the caching that you get with `require`, so that's a good point: will edit to mention that! – Mike 'Pomax' Kamermans Mar 07 '15 at 18:38
  • `Module._extensions['. jscsrc']= Module._extensions['j.son']` , this is how CofeeScript and Babel and everything else that hooks on node does it :) – Benjamin Gruenbaum Mar 07 '15 at 18:39