我尝试使用ClearScript加载TypeScript编译器以编译一些基本的TypeScript代码。
不幸的是,在执行TypeScript编译器源时出现此错误:
'WScript'未定义
这是我使用的LINQPad程序,将ClearScript dll和TypeScript compiler file放在.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 Link to SO19023498.zip。
我尝试了什么:
我首先尝试执行此代码:
var WScript = new ActiveXObject("WSH.WScript");
这只会产生此错误:Automation server can't create object
我在HKEY_CLASSES_ROOT下的注册表中没有看到WSH.WScript
,所以可能就是这样。
我试图弄清楚如何从.NET创建对象并将其设置到脚本上下文中,但我显然没有找到正确的位置。
答案 0 :(得分: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一样(就像游乐场一样)。 到目前为止,我找不到任何关于如何使用编译器的文档...... 但我发现一个页面也试图实现这一点 http://10consulting.com/2012/10/12/introduction-to-typescript-presentation/ 如果你看一下演示文稿的来源,你会发现一个编译器类。
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包,它还为您提供所需的所有编译器服务。
答案 1 :(得分:4)
这是使用当前版本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> {}"));
}
}
}
}
答案 2 :(得分:3)
4年后,在https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js使用TypeScript 2.7服务 现在它有点像两个班轮:
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