问题描述
从我想要做的节点应用程序中:
var typeScript = require('typescript');
typeScript.compile('...')
我是希望将编译器实现到构建系统但无法访问公共API(typescript.compile等),这是不可能的。
这是我想要做的更完整的例子,不过下面是针对LiveScript而不是TypeScript,在为Brunch.io构建的插件中使用的 - system:
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
回调错误,结果
包括:[
(sysPath.join __dirname,'..','vendor','prelude-browser-0.6.0.js')
]
好奇,如果有人找到了解决办法吗?
更新
我最终为上面和其他地方列出的各种问题实施了我自己的解决方案。有关更多信息和用法,请参阅。
这个有点hacky但它会起作用。
昨天我才这样想,我正在查看他们的代码。如果你从他们的源代码中检查bin / typscript.js(它是一个非常大的文件,有近21k行代码),你会看到它创建了TypeScript.TypeScriptCompiler,然后你会发现这个DOES暴露了一种编译方式。
var compiler = new TypeScript.TypeScriptCompiler(outfile,errorfile,
new TypeScript.NullLogger(),settings) ;
现在,您需要一种简单的方法来公开它。要做到这一点,你将不得不修改他们的代码,这就是为什么这是hacky。为此,您可以通过添加以下内容来修改typescript.js:
module.exports = exports = 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 = {
写:function(str){
fs.writeSync(fd,str);
},
WriteLine:function(str){
console.log(fd,str);
fs.writeSync(fd,str +'\\\\ n');
},
关闭:function(){
fs.closeSync(fd);
fd = null;
}
};
var createFile = function(path){
function mkdirRecursiveSync(path){
var stats = fs.statSync(path);
if(stats.isFile()){
throw\+ path +\存在但不是目录。;
} 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 {
写:function(str){
fs.writeSync(fd,str);
},
WriteLine:function(str){
fs.writeSync(fd,str +'\\\\'n');
},
关闭:function(){
fs.closeSync(fd);
fd = null;
}
};
};
var stderr = {
写:function(str){
process.stderr.write(str);
},
WriteLine:function(str){
process.stderr.write(str +'\ n');
},
关闭: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,Close和Write,实际上只是包装器。您可以获得必须添加此功能的开销,但您必须修改模块中的大量代码,这是不值得的。我认为最好有一个类来扩展(或者如果你还在JS上,继承原型)并让它为你做,让它干。
非常好的是,如果你想翻译500个TypeScript文件并将它们全部放入一个.js文件中,你可以调用compiler.addUnit(anothercontent,anotherpath); 500次,然后看到它们都进入一个文件:)
关注更好的事情:如果检查tsc.js代码,你会发现一个批处理编译器类。如果你想在构建过程中使用它,那么使用类似它的更强大的东西可能会更好。它提供了观看文件等等。
浏览完代码后,我想我只会向开发团队提交一张票,要求他们提供更清晰的API¬¬
注意:此处的所有文件读取都是以同步方式完成的。就性能而言,这是糟糕的,非常糟糕的。我不确切地知道你打算做什么,但是如果可能的话,我不能建议你找到一种方法使这种异步。
From within a node app I would like to do:
var typeScript = require('typescript');
typeScript.compile('...')
I'm looking to implement the compiler into a build system but without access to a public API (typescript.compile, etc) this is impossible.
Here's a more complete example of what I would like to do, though the below is for LiveScript, not TypeScript, utilitized in a plugin written for the Brunch.io build-system:
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')
]
Curious if anyone found a work-around?
Update
I ended up implementing my own solution to a variety of the problems listed above and elsewhere. Please see https://github.com/damassi/TypeScript-Watcher for more information and usage.
This one is a bit hacky but it will work.
I thought about this very same just yesterday and I was checking their code. If you check bin/typscript.js from their sourcecode (It is a very very large file, with nearly 21k lines of code), you will see it creates TypeScript.TypeScriptCompiler, and then you will find that this DOES expose a way of compiling.
var compiler = new TypeScript.TypeScriptCompiler(outfile, errorfile,
new TypeScript.NullLogger(), settings);
Now, you need an easy way to expose it. To do this, you will have to modify their code, which is why this is hacky. To do this, you could modify typescript.js by adding:
module.exports = exports = TypeScript;
Right at the end of the file.
Then, you can create an index.js file in the root of the module (notice: install the module in a local scope for all of this: "npm install typescript"), which exposes the object.
exports.TypeScript = require("bin/typescript");
And ready! Now you can just call it and compile your code using it. You can check how to use the API for compilation in the tsc.js file.
I apologize in advance for the horrible code ahead:
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();
For some reason whoever wrote the code was a real fan of C# and proceeded to go ahead and use methods called WriteLine, Close and Write, which are in fact just wrappers. You could get this of the overhead of having to add this functions, but you would have to modify a lot of code in the module and it isn't worth it. I think it is best to have a class to extend (or if you are still on JS, inherit the prototype) and let it do that for you, to make it DRY.
Something really nice is that if you want to translate 500 TypeScript files and put them all into a single .js file, you can just call compiler.addUnit(anothercontent, anotherpath); 500 times and then see it all go into a single file :)
Focusing on better things: if you check tsc.js code, you will find a batch compiler class. If you want this for a build process, it might be better to use something more robust like it. It provides watching files and more.
Having browsed the code, I think I will just submit a ticket to the development team and ask them to provide a clearer API ¬¬
Note: All file reads in here are done in a synchronous way. This is bad, very bad, in terms of performance. I don't know exactly what you plan to do, but I couldn't recommend more that you find a way to make this async if possible.
这篇关于TypeScript是否为NodeJS模块访问提供了明确的公共API?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!