2012-10-03 20 views
11

從節點的應用程序中我想這樣做:TypeScript是否爲NodeJS模塊訪問提供了明確的公共API?

var typeScript = require('typescript'); 

typeScript.compile('...') 

我期待落實到編譯器構建系統,但沒有訪問公共API(typescript.compile等),這是不可能的。

這裏是我想怎麼做一個更完整的例子,雖然下面是LiveScript,或者沒有打字稿,utilitized在爲Brunch.io構建系統編寫的插件:

LiveScript = require 'LiveScript' 
sysPath = require 'path' 

module.exports = class LiveScriptCompiler 
    brunchPlugin: yes 
    type: 'javascript' 
    extension: 'ls' 

    constructor: (@config) -> 
    null 

    compile: (data, path, callback) -> 
    try 
     result = LiveScript.compile data, bare: yes 
    catch err 
     error = err 
    finally 
     callback error, result 

    include: [ 
    (sysPath.join __dirname, '..', 'vendor', 'prelude-browser-0.6.0.js') 
    ] 

好奇,如果任何人找到解決辦法?

更新

我最終實現自己的解決方案,以多種上面和其他地方列出的問題。請參閱https://github.com/damassi/TypeScript-Watcher瞭解更多信息和用法。

回答

8

這是一個有點hacky,但它會工作。

我昨天就想到了這一點,我正在檢查他們的代碼。如果你從他們的源代碼中檢查bin/typscript.js(這是一個非常大的文件,有近21k行代碼),你會看到它創建了TypeScript.TypeScriptCompiler,然後你會發現這樣做會暴露一種編譯方式。

var compiler = new TypeScript.TypeScriptCompiler(outfile, errorfile, 
    new TypeScript.NullLogger(), settings); 

現在,您需要一種簡單的方法來公開它。要做到這一點,你將不得不修改他們的代碼,這就是爲什麼這是hacky。就在文件的結尾

module.exports = exports = TypeScript; 

:要做到這一點,你可以通過添加修改typescript.js。

然後,您可以在模塊的根目錄中創建一個index.js文件(注意:將模塊安裝在本地作用域中的所有內容:「npm install typescript」),它將公開該對象。

exports.TypeScript = require("bin/typescript"); 

準備好了!現在你可以調用它並使用它編譯你的代碼。您可以檢查如何在tsc.js文件中使用API​​進行編譯。

我提前道歉提前可怕代碼:

var fs = require("fs"); 
var TypeScript = require("typescript"); 
var path = "test.ts"; 
var pathout = "test.js"; 
var content = fs.readFileSync(path, "utf-8"); 
var fd = fs.openSync(pathout, 'w'); 
var outFile = { 
    Write: function (str) { 
     fs.writeSync(fd, str); 
    }, 
    WriteLine: function (str) { 
    console.log(fd, str); 
     fs.writeSync(fd, str + '\r\n'); 
    }, 
    Close: function() { 
     fs.closeSync(fd); 
     fd = null; 
    } 
}; 
var createFile = function (path) { 
    function mkdirRecursiveSync(path) { 
     var stats = fs.statSync(path); 
     if(stats.isFile()) { 
      throw "\"" + path + "\" exists but isn't a directory."; 
     } else { 
      if(stats.isDirectory()) { 
       return; 
      } else { 
       mkdirRecursiveSync(_path.dirname(path)); 
       fs.mkdirSync(path, 509); 
      } 
     } 
    } 
    mkdirRecursiveSync(_path.dirname(path)); 
    console.log(path) 
    var fd = fs.openSync(path, 'w'); 
    return { 
     Write: function (str) { 
      fs.writeSync(fd, str); 
     }, 
     WriteLine: function (str) { 
      fs.writeSync(fd, str + '\r\n'); 
     }, 
     Close: function() { 
      fs.closeSync(fd); 
      fd = null; 
     } 
    }; 
}; 
var stderr = { 
    Write: function (str) { 
     process.stderr.write(str); 
    }, 
    WriteLine: function (str) { 
     process.stderr.write(str + '\n'); 
    }, 
    Close: function() { 
    } 
} 
var compiler = new TypeScript.TypeScriptCompiler(outFile, outFile); 
compiler.setErrorOutput(stderr); 
compiler.addUnit(content, path); 
compiler.typeCheck(); 
compiler.emit(false, createFile); 
outFile.Close(); 

出於某種原因,誰寫的代碼是C#的一個真正的球迷,並着手繼續前進,所謂的WriteLine,關閉和寫入使用方法,其其實只是包裝。你可能會得到這個不得不添加這個函數的開銷,但是你必須修改模塊中的很多代碼,這是不值得的。我認爲最好有一個類來擴展(或者如果你仍然使用JS,繼承原型)並讓它爲你做這件事,讓它變幹。

真的很不錯,如果你想翻譯500個TypeScript文件並把它們放到一個單一的.js文件中,你可以直接調用compiler.addUnit(anothercontent,anotherpath); 500次,然後看到這一切,去到一個單一的文件:

着眼於更好的事情:如果你檢查tsc.js代碼,你會發現一個批處理編譯器類。如果你想要這樣做的構建過程,可能會更好地使用像它更強大的東西。它提供了觀看文件等等。

已經瀏覽過的代碼,我想我會剛剛提交票證給開發團隊,並要求他們提供更清晰的API¬¬

注意:所有文件在這裏讀取同步的方式進行。在性能方面,這是糟糕的,非常糟糕的。我不知道你打算做什麼,但我不能推薦更多,如果可能的話,你會找到一種方法來實現這種異步。

+0

優秀的答案。期待你的榜樣。 – cnp

+0

完成!你可以玩它,只需改變文件名(它是test.js和test.ts),並給它其他的文件名,它會起作用。現在,錯誤輸出將被髮布到process.stderr,但您可以隨心所欲地執行任何操作。你也可以添加一個處理函數作爲compiler.setErrorCallback,這樣你就可以編譯生成錯誤報告了! – Mamsaac

2

目前只有通過require和calling編譯才能實現編譯。如果你可以看一下harness.ts,有一個編譯器模塊提供了一個相當簡單的方法,但我建議你在外部調用tsc。

///<reference path='node.d.ts'/> 
import exec = module('child_process'); 

var child = exec.exec('tsc foo.ts', 
    function (error, stdout, stderr) { 
    if (error !== null) { 
     console.log('exec error: ' + error); 
    } 
}); 

我相信這會做這項工作。

+0

真棒。會做。 – cnp

+0

你可能想要刪除這個答案 –

1

檢查this github project通過niutech,它可以在瀏覽器中打字稿代碼轉換爲JS代碼在運行,但我想它可以很容易地進行修改node.js中工作

+0

感謝您提及我的項目! – niutech

1

better-require可以幫助你做到這一點,如果你想要在執行/訪問將輸出文件。

它可以讓你需要()打字稿文件 - 無預編譯需要 - 和一堆其他文件格式(CoffeeScript中,clojurescript,YAML,XML等)

require('better-require')(); 
var myModule = require('./mymodule.ts'); 

披露:我寫的更好-要求。

+0

真棒util - 我現在試着嘗試將它修補到Brunch.io彙編器中。 – cnp

+0

謝謝!隨意拉取請求;)它非常簡單。 –

1

你可以嘗試https://github.com/sinclairzx81/typescript.api。該項目執行require()擴展,但也有一些功能可以手動編譯ts源代碼。應該可以用它創建一個自動構建系統。

注壽其內置的打字稿0.9編譯器,所以你可能會或可能不會有成功的編制給予各種更新到0.8.3語言源。

相關問題