2013-09-26 23 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 
相關問題