Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the optimal way to execute a nodejs script from golang, that returns a string, and then communicate that string back to a golang variable?

I'm currently doing it with os/exec and Stdout on golang's side, and console.log("string") on nodejs's side.

Basically I need to generate a string but can only do so within nodejs but the majority of my code is in golang, so I'm trying to make this little blip in my code as seamless, secure, and reliable as possible and I'm a little uneasy about resting such an important part of my program on "console.log" and reading from shell output.

In short: I'm wondering if there exists a better and more standard communication line between my node and go code then console.log + shell output, or is that perhaps optimal enough?

Oh and the function of this particular part of my program is to take a markdown text file and convert it to HTML using markdown-it.

Some ideas:

  • Communicate through HTTP (send the data/string to a golang http listener)
  • Communicate through the filesystem (write the string to a temporary file and read it with golang)
  • Communicate through "something similiar to HTTP but specific to local application data sharing"

P.S.

I can't use otto, since markdown-it doesn't run there.

Actual code:

parser.go

package main

import (
    "os"
    "os/exec"
    "fmt"
    "bytes"
)

func main() {
    cmd := "node"
    args := []string{"parser.js", "/home/user1/dev/current/wikis/Bob's Pain/markup/index.md"}
    process := exec.Command(cmd, args...)
    stdin, err := process.StdinPipe()
    if err != nil {
        fmt.Println(err)
    }
    defer stdin.Close()
    buf := new(bytes.Buffer) // THIS STORES THE NODEJS OUTPUT
    process.Stdout = buf
    process.Stderr = os.Stderr

    if err = process.Start(); err != nil {
        fmt.Println("An error occured: ", err) 
    }

    process.Wait()
    fmt.Println("Generated string:", buf)
}

parser.js

var md = require('markdown-it')();
var yaml = require('js-yaml');
var fs = require('fs');

if (process.argv.length < 3) {
  console.log('Usage: node ' + process.argv[1] + ' FILENAME');
  process.exit(1);
}

var filename = process.argv[2];
fs.readFile(filename, 'utf8', function(err, data) {
  if (err) {
    throw err;
  }
  parse(data)
});

function parse(data) {
    data = data.split("---")
    yamlData = data[1];
    markData = data[2];
    y = yamlProcess(yamlData);
    markData = "# "+y.title+"\n\n"+markData
    html = markdownToHTML(markData);
    console.log(html) // SEND THE DATA BACK TO GOLANG
}

function yamlProcess(data) {
    try {
      var doc = yaml.safeLoad(data);
      return doc;
    } catch (e) {
      console.log(e);
      return {};
    }
}

function markdownToHTML(data) {
    return md.render(data);
}
like image 838
01AutoMonkey Avatar asked Oct 11 '15 17:10

01AutoMonkey


People also ask

Which is faster Node js or Golang?

Raw Performance ComparisonGolang is a better alternative for raw computation and performance when compared to Node JS. Compared to other programming languages, Node JS is more powerful since it comes from JavaScript. Node JS is unable to provide smooth CPU or memory-bound job execution due to its flaws.

Which statement is true about Node js and threads?

Explanation. True! Node js is a single threaded application but it support concurrency via concept of event and callbacks.

Which object holds all arguments passed after executing a script with the Node command?

In Node. js, as in C and many related environments, all command-line arguments received by the shell are given to the process in an array called argv (short for 'argument values'). There you have it - an array containing any arguments you passed in.

Which Node js module should you use when you need to decode raw data into strings?

The String Decoder module provides a way of decoding Buffer objects into strings.


1 Answers

The easiest way to do this with os/exec:

command := "node parser.js /path/to/some/file.md"
parts := strings.Fields(command)        
data, err := exec.Command(parts[0], parts[1:]...).Output()
if err != nil {
    panic(err)
}

output := string(data)

"output" is the data that is printed from your NodeJS script. "command" is any command as a string.

like image 74
jrkt Avatar answered Sep 25 '22 15:09

jrkt