Loading the TypeScript compiler into ClearScript, “WScript is undefined”, impossible task?

*爱你&永不变心* 提交于 2019-12-03 14:39:06

After playing around a little bit with ClearScript, the idea is pretty cool actually to get it running.

To get your code at least a little bit more running: Instead of using the tsc.js, simply use the typescript.js which comes with the SDK and should be in the same folder.

var typeScriptSource = File.ReadAllText("typescript.js");

typescript.js is the plain javascript compiler where tsc is using WSH and other com objects...

This way, you could also use the V8 engine!

But anyways, this means your would have to code some JavaScript to actually wrap the TypeScript.TypeScriptCompiler functions.

So this means you would have to do the same as if you would use the TypeScriptCompiler within your custom html page (like the playground does). I couldn't find any documentation of how to use the compiler so far though... But I found one page which also tries to implement this http://10consulting.com/2012/10/12/introduction-to-typescript-presentation/ If you look at the source of the presentation, you'll find a Compiler class.

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;

This looks pretty promising but unfortunately, if I try to use it with ClearScript it throws strange errors, maybe I'm doing something wrong...

At least, if I debug through the code, the js.Scripts.TypeScript is defined and contains all the TypeScript objects!

Anyways, I guess this should bring you a step further ;) let me know if you had success!

As an alternative, you could of cause use the command line tool to simply invoke the compiler instead of doing it from within the C# directly. I guess this should be way easier to implement... Or play around with the node.js package which also provides you all the compiler services you need.

Here's a skeletal sample using the current version of typescript.js. Note that the TypeScript API is reverse-engineered; as far as I can tell the only official interface is at the tsc command line. Also keep in mind that this is a minimal sample that does no error handling or reporting:

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

After 4 years, using the TypeScript 2.7 Services at https://rawgit.com/Microsoft/TypeScript/master/lib/typescriptServices.js it's kind of a two-liner now:

  • initialize your favorite JS engine with this script
  • load the string contents of your *.ts resource
  • get a function reference of ts.transpile
  • feed it the type script as a string and get back a string with the transpiled source

Using e.g. a ClearScript engine in C# with TS sourcecode in the string src this would be:

dynamic transpile = engine.Evaluate("ts.transpile");
var js = transpile(src);
// now feed the string js into a different JS engine
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!