20

我正在将 Script#、JSIL 和 SharpKit 作为用于将 C# 编译为 Javascript 的工具,因此我可以在 Visual Studio 中使用 C# 对 AJAX 的客户端功能进行编程。

每个 JSIL、Script# 和 SharpKit 的优缺点是什么?

我的项目是一个使用 razor 引擎和 C# 的 MVC4 项目,如果重要的话。

4

5 回答 5

21

如果您希望直接与 MVC 项目集成,那么像 Script# 或 SharpKit 之类的东西可能是您最好的选择 - 我知道 Script# 有内置的东西可以使这种集成更容易,所以我会从那里开始。

如果您确实想尝试使用 JSIL,它可能具有您需要的核心功能,但您可能想要的东西 - 如 Visual Studio 集成、自动部署等 - 不存在。目前它主要针对应用程序的交叉编译,所以它在这方面做得很好,但在其他用例方面做得不好。

我将尝试总结您可能想要考虑 JSIL 而不是其他替代方案的原因 - 我无法深入评论这些替代方案的优缺点,因为我没有使用它们:


JSIL 对 C# 4 中可用的功能提供了极其广泛的支持。值得注意的(因为其他工具不支持它们,或者它们很复杂)包括:

dynamic yield Structs ref / out Delegates Generics Nullables InterfacesEnums

当然,上面的一些内容没有完全的支持——要了解绝对可行的东西,你可以查看测试用例——每个都是一个小的独立的 .cs 文件,经过测试以确保JSIL 和本机 C# 产生相同的输出。

这种广泛支持的原因是我的目标是让 JSIL 使您能够将完全未修改的C# 应用程序转换为工作 JS。对于 JSIL 网站上的所有演示,这是真的,而且我还有一些即将完成的大型真实游戏的移植,这也是真的。


另一个原因是 JSIL 使您的 C# 和 JavaScript 对话变得相对简单。

您的所有 C# 类型和方法都通过一个尽可能对 javascript 友好的接口公开。JS 版本具有基本的重载解析和分派,因此本机 C# 接口可以从脚本代码调用,就像在大多数情况下它们是本机 JS 一样。除非您愿意,否则您不必采取任何步骤来专门标记您希望公开给 JS 的方法,或者给它们特殊的名称,或类似的东西。

当您想从 C# 调用到 JS 时,可以通过以下几种方式进行:

  • JSIL.Verbatim.Expression允许您将原始 javascript 直接插入到函数的翻译版本中。
  • JSIL.Builtins.Global可以与dynamicvar结合使用,直接在 C# 函数体中编写类似 JavaScript 的代码。
  • JSReplacement 属性可用于将 C# 函数的调用替换为参数化的 JavaScript 表达式。
  • 以上所有功能都可以与 JSIL 的更改类型信息的机制(称为代理)结合使用,即使您没有源代码,也可以更改您使用的库的类型信息,以便将它们的方法映射到 JavaScript你写过。
  • 最后,未转换为 JS 的 C# 方法会生成一个名为 External 的空方法,然后您可以在运行时将其替换为 JavaScript 以使其再次工作。您尚未替换的任何外部方法都会在运行时产生清晰的警告消息,以便您知道缺少什么。

JSIL 积极使用类型信息以及您提供的元数据,以尝试并安全地优化它为您生成的 JavaScript。在某些情况下,这可以产生比您手工编写的更好的等效 JavaScript - 目前主要的领域是使用结构的代码,但它也可以应用于其他情况。

例如,在这个代码片段中,JSIL 能够静态地确定,尽管代码暗示了结构副本的数量,但实际上没有一个副本对于代码的正确运行是必需的。生成的 JavaScript最终没有任何不必要的副本,因此它的运行速度比您天真地翻译原始 C# 的语义所得到的要快得多。这是编写简单的基于结构的东西(Vector2s 无处不在!)和完全疯狂地手动进行命名返回值优化之间的一个很好的中间地带,正如我过去所描述的那样,这很容易出错


好的,现在来说一些缺点。不要认为此列表详尽无遗:

  • .NET BCL 的大部分没有 JSIL 为您提供的实现。将来,这可能会通过将整个 Mono mscorlib 转换为 JavaScript 来解决,但我没有足够好的工作来提倡它作为一个直接的解决方案。(到目前为止,这对游戏来说很好,因为它们不使用太多 BCL。)这个问题主要是由于与翻译 Microsoft 的 mscorlib 相关的 IP 问题 - 如果我能合法地这样做,我会做对的现在 - 我上次测试它时它工作了。
  • 如上所述,没有视觉工作室集成。JSIL容易使用——你可以给它一个 .sln 文件来自动获得一堆 .js 输出,并使用项目旁边的配置文件自动配置它——但它远没有脚本那么完善或集成#.
  • 没有供应商或支持人员。如果您想在昨天修复错误或遇到问题,我几乎是您目前唯一的选择(尽管有一些多产的贡献者帮助改善事情,而且总是欢迎更多!)
  • JavaScript 性能是一个充满隐形地雷的该死迷宫。如果你只是想让应用程序工作,你可能不会有任何问题,但如果你像我一样试图让真正的游戏在浏览器中快速运行,JavaScript 会让你的生活变得更糟,在某些情况下,JSIL 会让情况变得更糟. 我在这里唯一能说的就是我正在努力。:)
  • 明确不支持像 Closure 这样的 JavaScript 压缩器和优化器,因为它们需要您的代码生成器跳过一堆麻烦。根据您打算如何使用代码,我可以看到这是一个真正的障碍。
  • 静态分析器仍然有点脆弱,在语言支持方面仍然存在差距。我使用 JSIL 移植的每个大型应用程序通常都会揭示 JSIL 中的一两个错误 - 不是严重的游戏破坏者,而是肯定会破坏功能或使事情运行缓慢的错误。

希望这些信息有帮助!感谢您的关注。

于 2012-07-19T06:58:01.877 回答
12

脚本#优点:

  • 自由的
  • 开源
  • 生成干净的 JavaScript

脚本# 缺点:

  • 仅支持 C# 2.0 语言的子集
  • 只能在单独的项目中编译,不能在客户端和服务器之间混合/重用代码
  • 版本更新频率低
  • 不提供支持
  • 有限的第 3 方库支持,C# API 与 JavaScript API 不同。
  • 不开源
  • 仅在 JavaScript 中调试

SharpKit 优点:

  • 商业产品
  • 支持完整的 C# 4.0 语言
  • 版本更新频率高
  • 支持可用
  • 客户端/服务器代码可以在同一个项目中混合和重用
  • 广泛的 3rd 方库支持,作为开源维护 - C# API 与 JavaScript API 完全匹配
  • 支持 Chrome 浏览器的基本 C# 调试
  • 生成干净的 JavaScript

SharpKit 缺点:

  • 有免费版本,没有时间限制,但仅限于小型/开源项目
  • 非开源(只有库是开源的)

JSIL 优点:

  • 自由的
  • 开源

JSIL 缺点:

  • 从 IL(中间语言)转换,而不是从 C# 转换,这意味着较低的抽象层,因为代码已经是低级的。
  • 生成复杂的 JavaScript 代码 - 几乎像 IL,难以阅读和调试

对反馈的答复:

Kevin:JSIL 输出还不错,它只是为了实现完整的 .NET 行为而生成的,很像 SharpKit 的 CLR 模式。另一方面,SharpKit 支持本机代码生成,其中任何本机 JavaScript 代码都可以从 C# 生成,就像手写一样。

SharpKit 干净生成的 JavaScript 代码示例: http ://sharpkit.net/Wiki/Using_SharpKit.wiki

开发人员可以选择创建更复杂的代码生成并获得更多功能,例如支持编译时方法重载。指定时,SharpKit 为重载方法生成方法后缀。

Script# 需要 .NET 4 才能运行,但它不支持完整的 C# 4.0 语法,如泛型、ref 和 out 参数、命名空间别名等...

于 2012-07-18T19:17:20.137 回答
8

另一种选择是WootzJs。完全披露,我是它的作者。

WootzJs 是开源的,并致力于成为一个相当轻量级的交叉编译器,它允许所有主要的 C# 语言功能。

支持的显着语言功能:

  • yield语句(作为高效状态机生成)
  • async/await方法(生成为像 C# 编译器一样的状态机)
  • refout参数
  • 表达树
  • lambdas 和代表(正确捕获this
  • 编译器和运行时都支持泛型(无效转换为T将引发转换异常)
  • 封闭变量的 C# 语义(相对于 Javascript 语义)

它是使用 Roslyn 实现的,这意味着它将率先利用未来的语言改进,因为这些现在将通过 Roslyn 本身实现。它提供了一个自定义版本,mscorlib因此您可以准确了解脚本中实际可用的库功能。

它的缺点是什么?

  • Javascript 并不是为了看起来“漂亮”。它显然是机器生成的,尽管通过查看单个方法应该很容易推理出来。
  • 由于其对核心库和反射的广泛支持,生成的输出并不是块上最小的。缩小应该产生一个 ~100k 的 JS 文件,但还不支持缩小。
  • WootzJs 毫不掩饰地使用函数来污染本机类型,以封装那些只能在 C# 中找到的类型的行为。例如,所有的方法System.String都添加到原生 JavascriptString类型中。
  • 目前很少支持绑定到 3rd-party Javascript 库。(目前只有 jQuery)

与其他交叉编译器的比较:

  • Script#非常稳定,并与 3rd 方 Javascript 库广泛集成。此外,它具有出色的 Visual Studio 集成,并提供了mscorlib. 这意味着您可以准确地知道在工具级别实际实现了哪些功能。例如,如果Console.Write()未实现,则该方法在您的编辑器中将不可用。

    但是,由于它的自定义解析器,它仍然停留在 C# 2.0 中(甚至没有在该版本的 C# 中找到的泛型)。这意味着现代 C# 开发人员正在放弃我们大多数人毫无保留地依赖的大量语言特性——尤其是除了 lambda 和 LINQ 之外的上述泛型。这使得 Script# 对于许多开发人员来说基本上是一个非入门者。

  • JSIL是一项非常令人印象深刻的工作,它将 IL 交叉编译成 Javascript。它非常强大,可以轻松处理大型 3D 视频游戏的交叉编译。缺点是由于其完整性,生成的 Javascript 文件非常庞大。如果您只需要 mscorlib.dll 和 System.dll,则下载量约为 50MB。此外,这个项目实际上并不是为在 Web 应用程序的上下文中使用而设计的,而且开始所需的工作量有点令人生畏。

    这个工具包也实现了一个 custom mscorlib,再次让您知道您可以使用哪些功能。但是,它的 Visual Studio 集成很差,迫使您创建调用编译器所需的所有自定义构建步骤并将输出复制到所需位置。

  • SharpKit:这个商业产品致力于为大多数 C# 4.0 语言特性提供支持。它通常会成功,并且该产品很有可能满足您的需求。它是轻量级的(小的 .JS 文件),支持现代 C# 语言功能(泛型、LINQ 等)并且通常是可靠的。它还为 3rd 方 Javascript 库提供了大量绑定。但是,您总是会遇到数量惊人的不受支持的边缘情况。

    例如,类型系统很浅,不支持表示泛型或数组(即typeof(Foo[]) == typeof(Bar[])typeof(List<string>) == typeof(List<int>))。对反射的支持有限,各种成员类型无法支持属性。表达式树支持不存在,yield 实现效率低下(没有状态机)。此外,自定义mscorlib不可用,脚本 C# 文件和普通 C# 文件混合在您的项目中,迫使您使用属性装饰每个脚本文件,[JsType]以将它们与正常编译的类区分开来。

于 2014-02-05T15:22:55.947 回答
5

We have SharpKit for two years and I must say that's upgraded the way we write code. The pros as I see them:

  • The code is much more structured - we can now developed infrastrcture just like we did in C# without "banging our heads" with prototype.
  • It is very easy to refactor
  • We can use Code Snippets which results in better productivity and less development time
  • You can control the way the JS is rendered (you have several modes to choose from).
  • We can debug our C# code in the browser (Currently supported on Chrome only, but still :->)
  • Great support! If you send them a query you get a response very fast.
  • Support a large number of libraries & easily extensible

The cons:

  • The documentation is a bit poor, however once you get a hang of it you'll boost your development.
于 2013-02-20T07:45:02.960 回答
2

很高兴这能有所帮助!

对于 ScriptSharp,这个 stackoverflow 链接可能会有所帮助。
ScriptSharp 能为我的工具包带来哪些优势?

如果您有任何 SVN 工具,请从https://github.com/kevingadd/JSIL下载示例,这是一个有效的源代码,可以帮助您走好几步。

于 2012-07-18T18:02:54.150 回答