我想从 Node 应用程序中执行以下操作:

var typeScript = require('typescript');

typeScript.compile('...')

我正在寻求将编译器实现到构建系统中,但是如果无法访问公共(public)API(typescript.compile等),这是不可能的。

这是我要执行的操作的一个更完整的示例,尽管以下内容是在为Brunch.io构建系统编写的插件中使用的LiveScript(而非TypeScript):
LiveScript = require 'LiveScript'
sysPath = require 'path'

module.exports = class LiveScriptCompiler
  brunchPlugin: yes
  type: 'javascript'
  extension: 'ls'

  constructor: (@config) ->
    null

  compile: (data, path, callback) ->
    try
      result = LiveScript.compile data, bare: yes
    catch err
      error = err
    finally
      callback error, result

  include: [
    (sysPath.join __dirname, '..', 'vendor', 'prelude-browser-0.6.0.js')
  ]

好奇是否有人找到解决方法?

更新

我最终实现了自己的解决方案,以解决上面和其他地方列出的各种问题。有关更多信息和用法,请参见https://github.com/damassi/TypeScript-Watcher

最佳答案

这个有点hacky,但是可以用。

我昨天才想到了同样的事情,当时我正在检查他们的代码。如果从源代码中检查bin/typscript.js(这是一个非常大的文件,包含近21k行代码),您会看到它创建了TypeScript.TypeScriptCompiler,然后您会发现这确实提供了一种编译方式。

var compiler = new TypeScript.TypeScriptCompiler(outfile, errorfile,
    new TypeScript.NullLogger(), settings);

现在,您需要一种简单的方法来公开它。为此,您必须修改他们的代码,这就是为什么这很hacky。为此,您可以通过添加以下内容来修改typescript.js:
module.exports = exports = TypeScript;

就在文件末尾。

然后,您可以在模块的根目录中创建一个index.js文件(注意:将模块安装在本地范围内以供所有使用:“npm install typescript”),该对象将公开。
exports.TypeScript = require("bin/typescript");

准备好了!现在,您可以调用它并使用它来编译代码。您可以在tsc.js文件中检查如何使用API​​进行编译。

我为前面的可怕代码表示歉意:
var fs = require("fs");
var TypeScript = require("typescript");
var path = "test.ts";
var pathout = "test.js";
var content = fs.readFileSync(path, "utf-8");
var fd = fs.openSync(pathout, 'w');
var outFile = {
    Write: function (str) {
        fs.writeSync(fd, str);
    },
    WriteLine: function (str) {
    console.log(fd, str);
        fs.writeSync(fd, str + '\r\n');
    },
    Close: function () {
        fs.closeSync(fd);
        fd = null;
    }
};
var createFile = function (path) {
    function mkdirRecursiveSync(path) {
        var stats = fs.statSync(path);
        if(stats.isFile()) {
            throw "\"" + path + "\" exists but isn't a directory.";
        } else {
            if(stats.isDirectory()) {
                return;
            } else {
                mkdirRecursiveSync(_path.dirname(path));
                fs.mkdirSync(path, 509);
            }
        }
    }
    mkdirRecursiveSync(_path.dirname(path));
    console.log(path)
    var fd = fs.openSync(path, 'w');
    return {
        Write: function (str) {
            fs.writeSync(fd, str);
        },
        WriteLine: function (str) {
            fs.writeSync(fd, str + '\r\n');
        },
        Close: function () {
            fs.closeSync(fd);
            fd = null;
        }
    };
};
var stderr = {
    Write: function (str) {
        process.stderr.write(str);
    },
    WriteLine: function (str) {
        process.stderr.write(str + '\n');
    },
    Close: function () {
    }
}
var compiler = new TypeScript.TypeScriptCompiler(outFile, outFile);
compiler.setErrorOutput(stderr);
compiler.addUnit(content, path);
compiler.typeCheck();
compiler.emit(false, createFile);
outFile.Close();

出于某种原因,编写该代码的人都是C#的忠实拥护者,因此继续使用称为WriteLine,Close和Write的方法,这些方法实际上只是包装器。您可以不必添加此功能而获得额外的开销,但是您必须修改模块中的许多代码,这是不值得的。我认为最好有一个扩展类(或者如果您仍在JS上,则继承原型(prototype))并让它为您完成,以使其干燥。

真正令人高兴的是,如果您想转换500个TypeScript文件并将它们全部放入一个.js文件中,则只需调用compile.addUnit(anothercontent,anotherpath);即可。 500次,然后将其全部放入一个文件中:)

专注于更好的事情:如果您检查tsc.js代码,则会发现一个批处理编译器类。如果您希望在构建过程中使用它,最好使用更健壮的方法。它提供了观看文件等功能。

浏览了代码后,我想我将向开发团队提交一张票证,并要求他们提供更清晰的API。

注意:这里所有文件的读取都是以同步方式完成的。就性能而言,这很糟糕,非常糟糕。我不确切知道您打算做什么,但我不能推荐您在可能的情况下找到一种使这种异步方式的方法。

09-25 19:39
查看更多