将TypeScript编译器加载到ClearScript中,“WScript未定义”,不可能完成任务?

我尝试使用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

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

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

在使用ClearScript玩一下之后,实际上让它运行起来非常酷。

要使代码至少运行一点:不要使用tsc.js ,只需使用SDK附带的typescript.js ,它们应该在同一个文件夹中。

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

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

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

但无论如何,这意味着您必须编写一些JavaScript来实际包装TypeScript.TypeScriptCompiler函数。

所以这意味着你必须像在自定义html页面中使用TypeScriptCompiler一样(就像游乐场一样)。 到目前为止,我找不到任何关于如何使用编译器的文档……但是我发现了一个页面也试图实现这个http://10consulting.com/2012/10/12/introduction-to-typescript-演示文稿/如果您查看演示文稿的来源,您将找到一个编译器类。

 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包,它还为您提供所需的所有编译器服务。

这是使用当前版本的typescript.js的骨架样本。 请注意,TypeScript API是反向工程的; 据我所知,唯一的官方界面是在tsc命令行。 另请注意,这是一个没有error handling或报告的最小样本:

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

4年后,使用https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js上的TypeScript 2.7服务,它现在是一种双线程:

  • 使用此脚本初始化您最喜欢的JS引擎
  • 加载* .ts资源的字符串内容
  • 获取ts.transpile的函数引用
  • 将类型脚本作为字符串提供给它,并获取带有转换源的字符串

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

 dynamic transpile = engine.Evaluate("ts.transpile"); var js = transpile(src); // now feed the string js into a different JS engine