从 golang 执行 nodejs 脚本的最佳方式是 returns 一个字符串,然后将该字符串传回 golang 变量?

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?

我目前在 golang 方面使用 os/execStdout,在 nodejs 方面使用 console.log("string")

基本上我需要生成一个字符串,但只能在 nodejs 中生成,但我的大部分代码都在 golang 中,所以我试图让我的代码中的这个小问题尽可能无缝、安全和可靠可能,我对将程序中如此重要的部分放在 "console.log" 上并从 shell 输出中读取感到有点不安。

简而言之:我想知道在我的节点和 go 代码然后 console.log + shell 输出之间是否存在更好和更标准的通信线路,或者这是否足够优化?

哦,我程序的这个特定部分的功能是获取降价文本文件并使用 markdown-it.

将其转换为 HTML

一些想法:

P.S.

我不能使用 otto,因为那里没有 markdown-运行。

实际代码:

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);
}

我用两种方法都达到了类似的要求。

对于构建管道扩展,我会编写一个 Python 脚本,该脚本从命令行获取参数并将结果输出到标准输出。这是一个简单的界面,用于 "run once"、"everything succeeds otherwise fail fast" 用法。如果您的情况相同,我会保持原样实施。

对于 Web 应用程序,我有 Java 服务用于特定功能(在我的例子中,Natty 来自自然语言字符串的日期识别)。这样做的好处是应用程序在调用时已经 "warmed up",并且肯定会更快地响应而不是每次请求进入时都启动。随着时间的推移,使用 rest 接口可能会显示出更多好处 -例如更简单的客户端实现、监控、部署选项、切换实现而不改变客户端等。只是这种方式更常规。

使用 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" 是从您的 NodeJS 脚本打印的数据。 "command" 是字符串形式的任何命令。