JSIL vs Script#vs SharpKit

时间:2012-07-18 17:56:43

标签: c# javascript .net asp.net-mvc

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

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

我的项目是使用剃须刀引擎和C#的MVC4项目,如果重要的话。

5 个答案:

答案 0 :(得分:21)

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

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

我将尝试总结一下您可能想要考虑JSIL而非其他替代方案的原因 - 我无法对这些替代方案的优缺点进行真正的评论,因为我没有&#39 ;使用它们:


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

dynamicyieldStructsref / outDelegatesGenericsNullablesInterfaces ,和Enums

上面的一些内容当然没有完整的支持 - 为了了解绝对可行的事情,你可以look at the test cases - 每个人都是经过测试以确保JSIL和本机C#产生相同输出的小型自包含.cs文件。

这种广泛支持的原因是我的目标是让JSIL能够将完全未修改的 C#应用程序转换为工作JS。对于JSIL网站上的所有演示,这是真的,我有几个近乎完成的大型真实游戏的端口,这也是如此。


另一个原因是JSIL让你的C#和你的JavaScript相对简单。

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

当你想从C#调用JS时,可以通过以下几种方式实现:

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

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

例如,in this code snippet,JSIL能够静态地确定尽管代码隐含暗示的结构副本数量,但代码中没有任何副本实际上是正常运行的。 The resulting JavaScript最终没有任何不必要的副本,因此如果您天真地翻译原始C#的语义,它的运行速度比您获得的速度快得多。这是编写基于结构的天真事物(Vector2s无处不在!)和去completely nuts with named return value optimization by hand之间的良好中间地带,as I've described in the past, is pretty error-prone


好的,现在有一些缺点。不要将此列表详尽无遗:

  • .NET BCL的大部分内容都没有为JSIL提供的实现。在将来,可以通过将整个Mono mscorlib翻译成JavaScript来解决这个问题,但是我没有足够的工作来提倡它作为一个直接的解决方案。 (这对于游戏到目前为止都很好,因为他们不会使用大部分BCL。)这个问题主要是由于与翻译微软的mscorlib有关的IP问题 - 如果我能合法地做到这一点,我和#39; d现在正在做 - 它是我最后一次测试它。
  • 如上所述,没有视觉工作室集成。 JSIL 非常容易使用 - 您可以将.sln文件提供给它以自动获取一堆.js输出,并使用项目旁边的配置文件自动配置它 - 但它'就像脚本#。
  • 那样,它没有像抛光或整合那么近
  • 没有供应商或支持人员。如果您想要在昨天修复错误或者您遇到问题,我现在几乎是您唯一的赌注(尽管有一些多产的贡献者帮助您做得更好,而且总是欢迎更多!)
  • JavaScript表现是一个充满无形地雷的该死的迷宫。如果你只想让应用程序运行,你可能不会在这里遇到任何问题,但如果像我一样,你试图让真实游戏在浏览器中快速运行,{{3} }。我能说的唯一好处就是我正在研究它。 :)
  • 明确不支持JavaScript minifiers和优化器(如Closure),因为它们需要您的代码生成器来跳过一堆箍。我可以看到这是一个真正的阻止,取决于你打算如何使用你的代码。
  • 静态分析仪仍然很脆弱,语言支持仍有差距。我使用JSIL移植的每个大型应用程序通常会在JSIL中显示一两个错误 - 不是巨大的游戏破坏者,而是那些肯定会破坏某个功能或使得运行缓慢的错误。

希望这些信息有用!谢谢你的兴趣。

答案 1 :(得分:12)

脚本#sros:

  • 开源
  • 生成干净的JavaScript

脚本#cons:

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

SharpKit专业人士:

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

SharpKit缺点:

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

JSIL专业人士:

  • 开源

JSIL缺点:

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

反馈答案:

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

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

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

脚本#需要.NET 4才能运行,但它不支持完整的C#4.0语法,如Generics,ref和out参数,名称空间别名等......

答案 2 :(得分:8)

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

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

支持的显着语言功能:

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

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

它的缺点是什么?

  • Javascript并不打算"漂亮"。它显然是由机器生成的,但通过查看它们应该很容易推理出各种方法。
  • 由于其对核心库和反射的广泛支持,生成的输出不是块中最小的。缩小应该产生~100k的JS文件,但是还不支持缩小。
  • WootzJs毫不掩饰地污染了本机类型,其功能是封装那些只能在C#中找到的类型的行为。例如,System.String的所有方法都会添加到原生Javascript String类型中。
  • 目前存在对第三方Javascript库绑定的很少支持。 (目前只有jQuery)

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

  • 脚本#非常稳定,并且与第三方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应用程序的上下文,并且开始所需的工作量有点令人生畏。

    此工具包也实现了自定义mscorlib,再次允许您了解可用的功能。但是,它的Visual Studio集成很差,迫使您创建调用编译器并将输出复制到所需位置所需的所有自定义构建步骤。

  • SharpKit :此商业产品致力于为大多数C#4.0语言功能提供支持。一般来说 成功,这个产品很有可能满足您的需求。它是轻量级的(小.JS文件),支持现代C#语言功能(泛型,LINQ等)并且通常是可靠的。它还为第三方Javascript图书馆提供了大量绑定。但是,有一些令人惊讶的边缘情况,您将不可避免地遇到这些边缘情况。

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

答案 3 :(得分:5)

我们有两年SharpKit,我必须说我们编写代码的方式已经升级。 我看到他们的专业人士:

  • 代码更加结构化 - 我们现在可以开发基础设施,就像我们在C#中所做的那样,没有用原型“敲打头脑”。
  • 很容易重构
  • 我们可以使用代码片段来提高工作效率和缩短开发时间
  • 您可以控制JS的呈现方式(您可以选择多种模式)。
  • 我们可以在浏览器中调试我们的C#代码(目前仅支持Chrome,但仍然: - &gt;)
  • 很大的支持!如果您向他们发送查询,您会非常快速地收到回复。
  • 支持大量图书馆和易于扩展

缺点:

  • 文档有点差,但是一旦掌握了它,你就会促进开发。

答案 4 :(得分:2)

很高兴,如果这可以帮助!

对于ScriptSharp,此stackoverflow链接可能有所帮助 What advantages can ScriptSharp bring to my tool kit?

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