Программно компилировать typescript в С#? - программирование

Программно компилировать typescript в С#?

Я пытаюсь написать функцию в С#, которая принимает строку, содержащую код typescript, и возвращает строку, содержащую код JavaScript. Есть ли библиотека для этого?

4b9b3361

Ответ 1

Вы можете использовать Process для вызова компилятора, указать --out file.js во временную папку и прочитать содержимое скомпилированного файла.

Я сделал небольшое приложение, чтобы сделать это:

Использование

TypeScriptCompiler.Compile(@"C:\tmp\test.ts");

Чтобы получить JS string

string javascriptSource = File.ReadAllText(@"C:\tmp\test.js");

Полный источник с примером и комментариями:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // compiles a TS file
                TypeScriptCompiler.Compile(@"C:\tmp\test.ts");

                // if no errors were found, read the contents of the compile file
                string javascriptSource = File.ReadAllText(@"C:\tmp\test.js");
            }
            catch (InvalidTypeScriptFileException ex)
            {
                // there was a compiler error, show the compiler output
                Console.WriteLine(ex.Message);
            }

            Console.ReadKey();
        }
    }

    public static class TypeScriptCompiler
    {
        // helper class to add parameters to the compiler
        public class Options
        {
            private static Options @default;
            public static Options Default
            {
                get
                {
                    if (@default == null)
                        @default = new Options();

                    return @default;
                }
            }

            public enum Version
            {
                ES5,
                ES3,
            }

            public bool EmitComments { get; set; }
            public bool GenerateDeclaration { get; set; }
            public bool GenerateSourceMaps { get; set; }
            public string OutPath { get; set; }
            public Version TargetVersion { get; set; }

            public Options() { }

            public Options(bool emitComments = false
                , bool generateDeclaration = false
                , bool generateSourceMaps = false
                , string outPath = null
                , Version targetVersion = Version.ES5)
            {
                EmitComments = emitComments;
                GenerateDeclaration = generateDeclaration;
                GenerateSourceMaps = generateSourceMaps;
                OutPath = outPath;
                TargetVersion = targetVersion;
            }
        }

        public static void Compile(string tsPath, Options options = null)
        {
            if (options == null)
                options = Options.Default;

            var d = new Dictionary<string,string>();

            if (options.EmitComments)
                d.Add("-c", null);

            if (options.GenerateDeclaration)
                d.Add("-d", null);

            if (options.GenerateSourceMaps)
                d.Add("--sourcemap", null);

            if (!String.IsNullOrEmpty(options.OutPath))
                d.Add("--out", options.OutPath);

            d.Add("--target", options.TargetVersion.ToString());

            // this will invoke `tsc` passing the TS path and other
            // parameters defined in Options parameter
            Process p = new Process();

            ProcessStartInfo psi = new ProcessStartInfo("tsc", tsPath + " " + String.Join(" ", d.Select(o => o.Key + " " + o.Value)));

            // run without showing console windows
            psi.CreateNoWindow = true;
            psi.UseShellExecute = false;

            // redirects the compiler error output, so we can read
            // and display errors if any
            psi.RedirectStandardError = true;

            p.StartInfo = psi;

            p.Start();

            // reads the error output
            var msg = p.StandardError.ReadToEnd();

            // make sure it finished executing before proceeding 
            p.WaitForExit();

            // if there were errors, throw an exception
            if (!String.IsNullOrEmpty(msg))
                throw new InvalidTypeScriptFileException(msg);
        }
    }

    public class InvalidTypeScriptFileException : Exception
    {
        public InvalidTypeScriptFileException() : base()
        {

        }
        public InvalidTypeScriptFileException(string message) : base(message)
        {

        }
    }
}

Ответ 2

Возможно, вы могли бы использовать интерпретатор JavaScript, например JavaScriptDotNet для запуска компилятора typescript tsc.js из С#.

Что-то вроде:

string tscJs = File.ReadAllText("tsc.js");

using (var context = new JavascriptContext())
{
    // Some trivial typescript:
    var typescriptSource = "window.alert('hello world!');";
    context.SetParameter("typescriptSource", typescriptSource);
    context.SetParameter("result", "");

    // Build some js to execute:
    string script = tscJs + @"
result = TypeScript.compile(""typescriptSource"")";

    // Execute the js
    context.Run(script);

    // Retrieve the result (which should be the compiled JS)
    var js = context.GetParameter("result");
    Assert.AreEqual(typescriptSource, js);
}

Очевидно, что для этого кода потребуется серьезная работа. Если бы это оказалось возможным, я бы, конечно, был заинтересован в этом.

Возможно, вы также захотите изменить tsc так, чтобы он мог работать с строками в памяти, а не требовать файл IO.

Ответ 3

Файл компилятора TypeScript официально запускается либо на node.js, либо на Windows Script Host - он написан сам в TypeScript (и переводится на JavaScript). Для этого требуется хост Script, который может получить доступ к файловой системе.

Таким образом, вы можете запускать TypeScript с любого языка, пока вы можете его обернуть в движок Script, который поддерживает операции файловой системы.

Если вы хотите скомпилировать TypeScript в JavaScript только на С#, вы в конечном итоге напишите С# -компонент компилятора.