以编程方式在C#中编译打字稿?

mpe*_*pen 17 c# compilation typescript tsc

我正在尝试在C#中编写一个函数,该函数接收包含typescript代码的字符串并返回包含JavaScript代码的字符串.这有库函数吗?

Bru*_*oLM 12

您可以使用它Process来调用编译器,指定--out file.js临时文件夹并读取已编译文件的内容.

我做了一个小应用程序来做到这一点:

用法

TypeScriptCompiler.Compile(@"C:\tmp\test.ts");
Run Code Online (Sandbox Code Playgroud)

得到的 JS string

string javascriptSource = File.ReadAllText(@"C:\tmp\test.js");
Run Code Online (Sandbox Code Playgroud)

完整源代码和评论:

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)
        {

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我遇到了一个带有 Win32Exception 的“找不到文件”,但我的 TS 文件路径是正确的。我认为这是不正确的 TSC 编译器的路径。你有没有遇到过这个问题?编辑:我直接为我的 TSC 编译器指定了路径,现在我收到以下消息:“指定的可执行文件不是此操作系统平台的有效应用程序。” (2认同)

Ric*_*ers 5

也许您可以使用像JavaScriptDotNet这样的JavaScript解释器来运行C#中的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);
}
Run Code Online (Sandbox Code Playgroud)

显然,代码需要一些认真的工作.如果这确实可行,我肯定会对结果感兴趣.

您可能还想修改tsc它以便它可以在内存中的字符串上操作而不需要文件IO.

  • 是的,抱歉没有更清楚.一次谈论三种语言很困难! (2认同)