2012-10-03 16 views
11

Od wewnątrz aplikacji węzła chciałbym zrobić:Czy TypeScript udostępnia jawny publiczny interfejs API dla dostępu do modułu NodeJS?

var typeScript = require('typescript'); 

typeScript.compile('...') 

szukam do wdrożenia kompilator do systemu kompilacji, ale bez dostępu do API publicznego (typescript.compile, etc) jest to niemożliwe.

Oto bardziej kompletny przykład tego, co chciałbym zrobić, choć jest poniżej, a nie dla LiveScript maszynopis, utilitized w wtyczki napisane dla systemu budowania-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') 
    ] 

ciekawy, czy ktoś znalazł jakieś obejście?

Aktualizacja

skończyło się na wdrażaniu własne rozwiązania różnych problemów wymienionych powyżej i gdzie indziej. Więcej informacji i użycie można znaleźć pod numerem https://github.com/damassi/TypeScript-Watcher.

Odpowiedz

8

Ten jest nieco hacky, ale będzie działać.

Myślałem o tym bardzo wczoraj i sprawdzałem ich kod. Jeśli zaznaczysz bin/typscript.js ze swojego kodu źródłowego (jest to bardzo duży plik, z prawie 21-krotnie liniami kodu), zobaczysz, że tworzy TypeScript.TypeScriptCompiler, a potem przekonasz się, że to WYDAJE sposób kompilacji .

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

Teraz potrzebny jest łatwy sposób na ich odsłonięcie. Aby to zrobić, będziesz musiał zmodyfikować swój kod, dlatego jest to zhakowane. Aby to zrobić, możesz zmodyfikować plik typescript.js, dodając:

module.exports = exports = TypeScript; 

Na samym końcu pliku.

Następnie można utworzyć plik index.js w katalogu głównym modułu (uwaga: zainstaluj moduł w zakresie lokalnym dla wszystkich: "npm install maszynopis"), który udostępnia obiekt.

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

I gotowe! Teraz możesz po prostu zadzwonić i skompilować swój kod za pomocą tego. Możesz sprawdzić, jak korzystać z interfejsu API do kompilacji w pliku tsc.js.

Przepraszam z góry za okropny kodu przyszłość:

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(); 

Z jakiegoś powodu ten, kto napisał kod był prawdziwym fanem C# i zaczął iść do przodu i wykorzystują metody zwanej WriteLine, Zamknij i napisać, który w rzeczywistości są tylko opakowaniami. Możesz mieć to na uwadze konieczności dodania tych funkcji, ale będziesz musiał zmodyfikować wiele kodu w module i nie jest to tego warte. Myślę, że najlepiej jest mieć klasę do rozszerzenia (lub jeśli nadal jesteś na JS, odziedzicz prototyp) i pozwól, że zrobisz to za Ciebie, aby uczynić to DRY.

Coś naprawdę fajnego jest to, że jeśli chcesz przetłumaczyć 500 plików TypeScript i umieścić je wszystkie w jednym pliku .js, możesz po prostu wywołać kompilator.addUnit (anothercontent, anotherpath); 500 razy, a potem zobacz, jak wszystko idzie w jeden plik :)

Skupiając się na lepszych rzeczach: jeśli sprawdzisz kod tsc.js, znajdziesz klasę kompilatora wsadowego. Jeśli chcesz to dla procesu kompilacji, lepiej użyć czegoś bardziej odpornego. Zapewnia oglądanie plików i więcej.

Po przeglądałem kod, myślę, że po prostu przesłać zgłoszenie do zespołu projektowego i poprosić ich, aby zapewnić jaśniejsze API ¬¬

UWAGA: Wszystkie pliki czyta tutaj odbywa się w sposób synchroniczny. To jest złe, bardzo złe pod względem wydajności. Nie wiem dokładnie, co masz zamiar zrobić, ale nie mogę zalecić więcej, aby znaleźć sposób na asynchroniczne, jeśli to możliwe.

+0

Doskonała odpowiedź. Czekam na twój przykład. – cnp

+0

Zrobione! Możesz się z nim bawić, wystarczy zmienić nazwę pliku (to jest test.js i test.ts) i nadać mu inne nazwy plików, a to zadziała. Tak jak jest teraz, wyjście błędów zostanie wydane na process.stderr, ale możesz zrobić z nim co chcesz. Możesz również dodać funkcję obsługi jako compiler.setErrorCallback, dzięki czemu możesz tworzyć raporty błędów kompilacji! – Mamsaac

2

Obecnie nie jest możliwe uzyskanie kompilacji tylko poprzez kompilację wymagającą i wywołującą. Jeśli możesz spojrzeć na uprząż.ts jest moduł kompilatora, który zapewnia dość prosty sposób robienia tego, ale sugerowałbym, żebyś zadzwonił do tsc z zewnątrz.

///<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); 
    } 
}); 

Wierzę, że to by się spełniło.

+0

Awesome. Zrobi to. – cnp

+0

możesz usunąć tę odpowiedź. –

1

Sprawdź this github project przez niutech, może konwertować kod maszynopis do kodu JS w locie w przeglądarce, ale myślę, że można być łatwo modyfikowane do pracy w node.js.

+0

Dziękuję za wzmiankę o moim projekcie! – niutech

1

better-require może pomóc w osiągnięciu tego celu, jeśli wszystko, czego chcesz, to wykonywanie/uzyskiwanie dostępu do pliku maszynopisu.

Pozwala require() plików maszynopisu - no pre-kompilacji potrzebne - i kilka innych formatów (coffeescript, clojurescript, YAML, XML, itp)

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

Odsłonięcie: pisałem lepiej -wymagać.

+0

Awesome util - spróbuję teraz dodać go do asemblera Brunch.io. – cnp

+0

Dzięki! Zapraszam do wyciągnięcia wniosku;) To całkiem proste. –

1

Możesz wypróbować https://github.com/sinclairzx81/typescript.api. Ten projekt robi stuff require(), ale ma także pewną funkcjonalność do ręcznego kompilowania źródła ts. Powinno być możliwe stworzenie z nim zautomatyzowanego systemu kompilacji.

Zauważ, że jest zbudowany na kompilatorze maszynopis 0.9, więc możesz lub nie możesz osiągnąć kompilacji źródła 0.8.3 przy różnych aktualizacjach tego języka.

Powiązane problemy