0

I've got the following simple scenario:

  1. I parse manifest.json (a JSON file)
  2. I add some paths to an array field of this JSON object
  3. I stringify the object back to JSON and write back to the file

An issue appears somewhere inbetween: when I add a relative path to the array and then output the array I'm getting double backslashes in my output.

This is part of the code:

var entry = manifest['content_scripts'][0]['js'] = [];
    routines.forEach(function(routine) {
        var rel = path.relative(sourcePath, routine);
        console.log('rel %s', rel);
        entry.push(rel);        
        console.log('added rel %s', entry[entry.length-1]);
        console.log('total array %a', entry);
    });

This returns:

rel routines\boot.js
added rel routines\boot.js
total array %a [ 'routines\\boot.js' ]

How is this possible? The first entry in the "total array output" is not equal to the output of directly logging this last entry.

May JSON.stringify be causing issues here?

Extra: for those interested, this is the entire build script:

var path            = require('path'),
    fs              = require('fs'),
    findit          = require('findit'),
    sourcePath      = path.resolve('./src'),
    manifestPath    = path.join(sourcePath, 'manifest.json'),
    routinesDir     = path.join(sourcePath, 'routines');

//find routines
var routines = findit.sync(routinesDir);
if (!Array.isArray(routines) || routines.length === 0) throw new Error('no routines found');

//get file
fs.readFile(manifestPath, 'utf8', function(err, data) {
    if (err) throw err;

    //get manifest
    var manifest = JSON.parse(data);

    //flush and reset js entry
    var entry = manifest['content_scripts'][0]['js'] = [];
    routines.forEach(function(routine) {
        var rel = path.relative(sourcePath, routine);
        console.log('rel %s', rel);
        entry.push(rel);        
        console.log('added rel %s', entry[entry.length-1]);
        console.log('total array %a', entry);
    });

    //get string back
    var manifestStr = JSON.stringify(manifest, null, 4);

    console.log('new manifest: ' + manifestStr);

    //update file
    fs.writeFile(manifestPath, manifestStr, 'utf8', function(err) {
        if (err) throw err;

        //done
        console.log('build done');
    });
});

With manifest.json:

{ "name": "Name", "version": "0.0.1", "description": "", "content_scripts": [ { "matches": [ "http://www.example.com" ], "js": [ "routines\boot.js" ], "css": [ "prime.css" ], "run_at": "document_start" } ] }

Finally, I'm running this on Windows 7.

2

You’re using %a in the formatting string, which has no meaning, so console.log inspects the array instead. Probably %a is just a typo and you really meant %s.

  • The purpose is to inspect the array, because that's when the issue arises. When stringifying the same issue appears. How should I log an array? – Tom Dec 17 '11 at 21:32
  • What I mean is that when you give console.log anything other than a string, it will "inspect" the object rather than just stringify it using toString. So this means that your array will be "inspected", and the string inside the array will also be inspected. Now, when you inspect a string, Node formats it the same way you would have to format it as a string literal. And since backslashes need to be escaped, that’s how Node formats it. Try changing your total array %a to total array %s and you’ll see what I mean. – Daniel Brockman Dec 17 '11 at 21:42
  • What I’m trying to say is, %a is just wrong. You made a mistake writing it, and you meant %s. – Daniel Brockman Dec 17 '11 at 21:47
  • Isn't %s for strings? I'm not trying to output a string, I'm trying to output an array with strings. Anyway, the problem is still there when using JSON.stringify (this is probably also internally used by console.log). – Tom Dec 17 '11 at 21:58
  • That’s the correct behavior. "foo\\bar" is the correct JSON representation of the string consisting of "foo" followed by a backslash followed by "bar". – Daniel Brockman Dec 17 '11 at 22:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.