如何实现一个简单的基于Node.js的代码运行方法

Feb 26

需要的工具

  • Node.js环境
  • 一个代码编辑器,推荐VS Code

方法

这两天研究怎么把文言文编程语言的运行过程本地化,通过@wenyan/core模块可以将文言文代码编译成JavaScript,PythonRuby。为了不在同一项目中同时使用Node和Python,就直接用JS代码了,接下来就是重点,怎么拿到console.log的结果?

昨天研究了半天,发现JS很难拿到process.stdout流中输出的文本,所以就只能曲线救国了:

将编译后的JS写入一个.js后缀的文件,然后使用node的exec函数运行文件,即可获得stdout的文本。 这个方法的灵感来源于glot.io这个在线运行代码的网站。通过对网站核心模块代码(开源,可以在这里找到)的观察,发现也是通过文件的方式拿到输出流文本的。

所以就有了以下的代码:(目前该代码已经集成到我的私人API上)

import { exec } from 'node:child_process'
import fs from 'node:fs'
import path from 'node:path'
import { fileURLToPath } from 'node:url'

const __filename = fileURLToPath(import.meta.url)
const __dirname = path.dirname(__filename)

// 这里是为了扩展做准备
export enum Language {
  JavaScript,
}

export function run(lang: Language, code: string): Promise<string> {
  switch (lang) {
    case Language.JavaScript:
      return new Promise((resolve, reject) => {
        fs.writeFile(`${__dirname}/main.js`, code, (err) => {
          if (err)
            reject('Write file error!')

          exec(`node ${__dirname}/main.js`, (err, stdout, stderr) => {
            if (stdout) {
              resolve(stdout)
            }
            if (stderr)
              reject(stderr)
          })
        })
      })
    default:
      break
  }
}

使用Promise可以确保当文件完成写入后,运行代码获取到stdout的文本之后再运行后续代码,防止因异步而导致拿不到输出结果。


>
CC BY-NC-SA 4.0 2023-PRESENT © Vincent-the-gamer | Version: v1.1.1