JSIL vs Script#vs SharpKit

Kyl*_*yle 20 .net javascript c# asp.net-mvc

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

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

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

Kat*_*add 21

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

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

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


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

dynamic, yield, Structs, ref/out, Delegates, Generics, Nullables, Interfaces Enums.

当然,上面的一些内容并没有完全的支持 - 为了了解绝对可行的事情,你可以查看测试用例 - 每个都是一个小的自包含的.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属性可用于使用参数化JavaScript表达式替换C#函数的调用.
  • 所有上述功能都可以与JSIL用于更改类型信息的机制(称为Proxies)相结合,以允许您更改所使用的库的类型信息,即使您没有源代码,也可以将其方法映射到JavaScript你写的.
  • 最后,未转换为JS的C#方法会生成一个名为External的空方法,然后您可以在运行时用JavaScript替换它以使其再次工作.您尚未替换的任何外部方法都会在运行时生成明确的警告消息,以便您知道缺少什么.

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

例如,在此代码段中,JSIL能够静态地确定尽管代码隐含了结构副本的数量,但代码中没有一个副本实际上是正常运行所必需的.由此产生的JavaScript最终没有任何不必要的副本,因此它的运行速度远远超过了你天真翻译原始C#的语义所能获得的速度.这是一个很好的中间点,在编写基于结构的天真的东西(Vector2s无处不在!)和完全疯狂的手工命名返回值优化,正如我在过去所描述的那样,它非常容易出错.


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

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

希望这些信息有用!谢谢你的关注.


小智 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支持本机代码生成,其中任何本机JavaScript代码都可以从C#生成,就像它手工编写的一样.

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

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

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


Kir*_*oll 8

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

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

支持的显着语言功能:

  • yield 语句(作为有效的状态机生成)
  • async/await 方法(生成为像C#编译器一样的状态机)
  • refout参数
  • 表达树
  • lambdas和代表(适当捕获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]属性装饰每个脚本文件,以区别于正常编译的类.


nad*_*avy 5

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

  • 代码更加结构化 - 我们现在可以开发基础设施,就像我们在C#中所做的那样,没有用原型"敲打头脑".
  • 重构非常容易
  • 我们可以使用Code Snippets,从而提高生产力并缩短开发时间
  • 您可以控制JS的呈现方式(您有多种模式可供选择).
  • 我们可以在浏览器中调试我们的C#代码(目前仅支持Chrome,但仍然: - >
  • 很大的支持!如果您向他们发送查询,您会非常快速地收到回复.
  • 支持大量库并且易于扩展

缺点:

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