2013-09-26 21 views
6

我尝试使用ClearScript加载编译器TypeScript以编译一些基本的TypeScript代码。将TypeScript编译器加载到ClearScript中,“WScript未定义”,不可能的任务?

不幸的是,在执行打字稿编译器源代码,当我得到这个错误:

'WScript' is undefined

这是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

我已经试过什么:

  1. 我第一次尝试执行此代码:

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

    这只能产生这样的错误:Automation server can't create object

    我没有看到WSH.WScript注册表在HKEY_CLASSES_ROOT下,这可能是它。

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

+0

请注意,我不知道如果调用编译打字稿代码是正确的,也许它返回结果的JavaScript代码,但程序在该步骤之前失败。 –

+0

WScript对象不是可创建的,尽管您可以用C#类很容易地模拟它。 tsc.js脚本还需要ActiveXObject,它是一个JScript-ism,但如果你想使用V8(我假设你这样做,因为你要经历安装ClearScript的V8 DLLs),也可能被模拟出来。尽管如此,所有的工作都是有点工作的,所以我会推荐Ela的方法如下。 – BitCortex

回答

5

在用了一点ClearScript后,这个想法实际上很酷,实际上它运行起来非常酷。

要把代码至少多一点点运行: 而不是使用tsc.js的,只需使用typescript.js其自带的SDK,并应在同一文件夹中。

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类。

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

+0

谢谢你,我一定会在今天晚些时候尝试,我会发表评论或任何必要的反映我发现的内容。 –

+0

Ela在这里的正确轨道上。 typescript.js脚本是核心的便携式TypeScript代码,它在V8中完美运行。但是,上面的编译器包装看起来过时了;例如,TypeScriptCompiler在最近的drop中没有addUnit()方法。上面的代码也使用了一个'console'对象,它必须在某个地方定义。 – BitCortex

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

4年后,使用打字稿2.7服务在https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js 它是一种双内胆的现在:

  • 初始化你最喜欢的JS引擎,这个脚本
  • 装入* .TS的字符串内容资源
  • 得到ts.transpile
  • 函数引用
  • 将其作为字符串提供给类型脚本并取回带有传输源的字符串

使用例如一个ClearScript engine在C#中使用字符串src在TS源代码,这将是:

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