8

我尝试使用ClearScript加载TypeScript编译器以编译一些基本的 TypeScript 代码。

不幸的是,在执行 TypeScript 编译器源时,我收到此错误:

'WScript' 未定义

这是我使用的LINQPad程序,将 ClearScript dll 和TypeScript 编译器文件放在 .linq 程序旁边:

void Main()
{
    using (var js = new Microsoft.ClearScript.Windows.JScriptEngine(Microsoft.ClearScript.Windows.WindowsScriptEngineFlags.DisableSourceManagement))
    {
        var typeScriptSource = File.ReadAllText(Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), "tsc.js"));
        js.Execute(typeScriptSource);
        const string typeScriptCode = @"
            class Greeter {
                greeting: string;
                constructor(message: string) {
                    this.greeting = message;
                }
                greet() {
                    return ""Hello, "" + this.greeting;
                }
            }
            function test()
            {
                var greeter = Greeter(""world"");
                return greeter.greet();
            }
        ";
        js.Script.TypeScript.Compile(typeScriptCode);

        object result = js.Script.test();
        result.Dump();
    }
}

#region Copy ClearScript to correct location

static UserQuery()
{
    foreach (var filename in new[] { "ClearScriptV8-32.dll", "ClearScriptV8-64.dll", "v8-ia32.dll", "v8-x64.dll" })
    {
        try
        {
            string sourcePath = Path.Combine(Path.GetDirectoryName(Util.CurrentQueryPath), filename);
            string targetPath = Path.Combine(Path.GetDirectoryName(typeof(Util).Assembly.Location), filename);

            File.Copy(sourcePath, targetPath, true);
        }
        catch (IOException ex)
        {
            unchecked
            {
                const int fileInUseHresult = (int)0x80070020;
                if (ex.HResult != fileInUseHresult)
                    throw;
            }
        }
    }
}

#endregion

错误发生在这一行:

js.Execute(typeScriptSource);

我已经创建了一个包含所有内容的 .zip 文件,您需要LINQPad来加载 .linq 文件并进行实验。ClearScript dll 是从未经修改的源创建的,但如果您不相信我,您应该能够自己复制这些(如果您没有它们的话)。

可在此处获得:Dropbox 链接到 SO19023498.zip

我试过的:

  1. 我尝试先执行此代码:

    var WScript = new ActiveXObject("WSH.WScript");
    

    这只产生了这个错误:Automation server can't create object

    我没有WSH.WScript在 HKEY_CLASSES_ROOT 下的注册表中看到,所以可能就是这样。

  2. 我试图弄清楚如何从 .NET 创建对象并将其设置到脚本上下文中,但我显然没有找对地方。

4

3 回答 3

7

4 年后,在https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js使用 TypeScript 2.7 服务, 现在它有点像两行:

  • 用这个脚本初始化你最喜欢的 JS 引擎
  • 加载 *.ts 资源的字符串内容
  • 获取函数引用ts.transpile
  • 将类型脚本作为字符串提供给它,并用转译的源返回一个字符串

在 C# 中使用 ClearScriptengine和字符串中的 TS 源代码,src这将是:

dynamic transpile = engine.Evaluate("ts.transpile");
var js = transpile(src);
// now feed the string js into a different JS engine
于 2018-02-15T20:34:15.903 回答
5

在用 ClearScript 玩了一会儿之后,这个想法实际上很酷,可以让它运行。

为了让您的代码至少运行更多一点:不要使用tsc.js,只需使用SDK 附带的typescript.js并且应该在同一个文件夹中。

var typeScriptSource = File.ReadAllText("typescript.js");

typescript.js 是纯 javascript 编译器,其中 tsc 使用 WSH 和其他 com 对象...

这样,您也可以使用 V8 引擎!

但无论如何,这意味着您必须编写一些 JavaScript 代码才能真正包装 TypeScript.TypeScriptCompiler 函数。

因此,这意味着您必须执行与在自定义 html 页面中使用 TypeScriptCompiler 相同的操作(就像 Playground 一样)。到目前为止,我找不到任何关于如何使用编译器的文档......但我发现一页也试图实现这个 http://10consulting.com/2012/10/12/introduction-to-typescript-演示文稿/ 如果您查看演示文稿的源代码,您会发现一个 Compiler 类。

Compiler.prototype.compile = function (src) {
    var outfile = {
        source: "",
        Write: function (s) {
            this.source += s;
        },
        WriteLine: function (s) {
            this.source += s + "\n";
        },
        Close: function () { }
    };

    var compiler = new TypeScript.TypeScriptCompiler(outfile);

    try {
        compiler.parser.errorRecovery = true;
        compiler.setErrorCallback(function (start, len, message, block) {
            console.log('Compilation error: ', message, '\n Code block: ', block, ' Start position: ', start, ' Length: ', len);
        });
        compiler.addUnit(Compiler.libfile, 'lib.d.ts');
        compiler.addUnit(src, '');

        compiler.typeCheck();

        compiler.emit(false, function createFile(fileName) {
            console.log(outfile);
            return outfile;
        });

        console.log('compiled: ' + outfile.source);
        return outfile.source;
    } catch (e) {
        console.log('Fatal error: ', e);
    }
    return '';
};
return Compiler;

这看起来很有希望,但不幸的是,如果我尝试将它与 ClearScript 一起使用,它会引发奇怪的错误,也许我做错了什么......

至少,如果我通过代码进行调试,js.Scripts.TypeScript就会定义并包含所有 TypeScript 对象!

无论如何,我想这应该会让你更进一步;)如果你成功了,请告诉我!

作为替代方案,您当然可以使用命令行工具来简单地调用编译器,而不是直接在 C# 中执行它。我想这应该更容易实现......或者使用 node.js 包,它还为您提供所需的所有编译器服务。

于 2013-09-26T10:37:04.240 回答
5

这是使用当前版本的typescript.js. 请注意,TypeScript API 是逆向工程的;据我所知,唯一的官方界面是tsc命令行。另请记住,这是一个不进行错误处理或报告的最小示例:

using System;
using System.IO;
using Microsoft.ClearScript;
using Microsoft.ClearScript.V8;

namespace Test
{
    public class TypeScriptCompiler
    {
        private readonly dynamic _compiler;
        private readonly dynamic _snapshot;
        private readonly dynamic _ioHost;

        public TypeScriptCompiler(ScriptEngine engine)
        {
            engine.Evaluate(File.ReadAllText("typescript.js"));
            _compiler = engine.Evaluate("new TypeScript.TypeScriptCompiler");
            _snapshot = engine.Script.TypeScript.ScriptSnapshot;
            _ioHost = engine.Evaluate(@"({
                writeFile: function (path, contents) { this.output = contents; }
            })");
        }

        public string Compile(string code)
        {
            _compiler.addSourceUnit("foo.ts", _snapshot.fromString(code));
            _compiler.pullTypeCheck();
            _compiler.emitUnit("foo.ts", _ioHost);
            return _ioHost.output;
        }
    }

    public static class TestApplication
    {
        public static void Main()
        {
            using (var engine = new V8ScriptEngine())
            {
                var compiler = new TypeScriptCompiler(engine);
                Console.WriteLine(compiler.Compile("class Foo<T> {}"));
            }
        }
    }
}
于 2013-11-05T12:09:04.263 回答