前几天我在做一个副项目,意识到我需要使用一些JavaScript功能。再次与Node.js和npm打交道的想法让我彻底放弃了,所以我决定研究在.NET应用程序中运行JavaScript的可能性。疯了吧?实际上,这出奇地容易。1.你为什么要这样做?尽管我喜欢.NET生态系统,但JavaScript生态系统在某些方面做得更好。其中之一是为几乎任何东西寻找一个库,尤其是在网络方面。以语法高亮为例。这可以直接在C#中完成,但并不是特别流畅的体验。例如,TextMateSharp项目为TextMate语法提供了解释器。这些文件是VSCode用于向语言添加基本语法突出显示的文件。但是,如果您要部署应用程序,它会包装一个本地依赖项,这会增加一些复杂性。相比之下,JavaScript拥有大量成熟的语法高亮库。仅举几例,有highlight.js、Prism.js(在本博客中使用)和shiki.js。特别是前两个,非常成熟,有多个插件和主题,并且有简单的API。作为.NET开发人员,JavaScript的一个明显问题是您需要学习并选择与Node.js和NPM一起工作的完整独立工具链。这似乎只是为了使用一个小功能而产生的大量开销。所以我们陷入了困境。我们要么走C#(+本机)路线,要么必须切换到JavaScript。或者...我们直接从我们的.NET应用程序调用JavaScript。2.在.NET中运行JavaScript一旦决定在.NET代码中运行JavaScript,您将考虑多种选择。您可以借用一个JavaScript引擎并让它为您运行JavaScript,但您并没有真正解决问题,您仍然需要安装Node.js。另一种选择是将JavaScript引擎直接捆绑在您的库中。这并不像听起来那么疯狂,有几个NuGet包采用这种方法,然后公开一个C#层以与引擎交互。以下是您可以使用的一些软件包的列表。库Jering.Javascript.NodeJS采用上面的第一种方法。它不在包中包含Node.js。相反,它提供了一个C#API来执行JavaScript代码和调用安装在您机器上的Node.js。这在您知道两者都已安装的环境中可能很有用,但它并不能真正解决我想避免的问题。ChakraCoreChakraCore是Edge在切换到基于Chromium的引擎之前使用的原始JavaScript引擎。根据GitHub项目的介绍:ChakraCore是一个带有C语言API的JavaScript引擎,您可以使用它为任何C语言或C语言兼容项目添加JavaScript支持。它可以针对LinuxmacOS和Windows上的x64处理器进行编译。而x86和ARM仅适用于Windows。因此,ChakraCore包含本机依赖项,??但由于C#可以P/Invoke到本机库中,这本身不是问题。但它会带来一些部署挑战。ClearScript(V8)Node.JS、Chromium、Chrome和最新的Edge都使用V8JavaScript引擎。Microsoft.ClearScript包为这个库提供了一个包装器,提供了一个调用V8库的C#接口。与ChakraCore一样,V8引擎本身也是原生依赖。ClearScript库负责P/Invoke调用并提供一个很好的C#API,但您仍然必须确保在目标平台上部署正确的本机库。JintJint很有趣,因为它是一个完全在.NET中运行的JavaScript解释器,没有任何本机依赖项!它完全支持ECMAScript5.1(ES5),并且支持.NETStandard2.0,所以你可以使用它!JurassicJurassic是另一个JavaScript引擎的.NET实现,类似于Jint。同样类似于Jint,它支持所有ES5,似乎也部分支持ES6。与Jint不同,Jurassic不是解释器,它将JavaScript编译为IL,这使得它非常快,并且没有原生依赖。那么,在所有这些选项中,您应该选择哪一个?3.JavaScriptEngineSwitcher:还有一个很棒的项目可以让你在一个JS引擎不够用的时候简单地尝试上面的任何一个库。虽然所有库都允许您运行JavaScript,但它们都具有略微不同的C#API来与之交互。这会使比较它们变得有点痛苦,因为您必须为每个库学习不同的API。JavaScriptEngineSwitcher这个库为我提到的所有库提供包装器以及更多:Jering.Javascript.NodeJSChakraCoreMicrosoftClearScript.V8JintJurassicMSIEJavaScriptEnginefor.NETNiL.JSVroomJsenginerequiresanadditionalnativepackage),还有一个Core包,它提供了一个通用的API。即使您不打算切换JS引擎,我也倾向于尽可能使用JavaScriptEngineSwitcher包装器库,这样您以后需要切换引擎时就不必弄清楚新的API。在我看来,完全有可能更改.NET项目中使用的JavaScript引擎。例如,我开始使用Jint,但当我需要执行更大的脚本时,我遇到了性能问题并切换到Jurassic。JavaScriptEngineSwitcher使这就像向我的项目添加一个新包并更改一些初始化代码一样简单。我最近才发现JavaScriptEngineSwitcher库,但最新版本的下载量已接近一百万,并且已在.NET静态站点构建器Statiq中使用。在本文的最后部分,我将举例说明最基本的用法。4.案例:使用JavaScriptEngineSwitcher在控制台应用程序中运行prism.js在本文的开头,我讨论了一个具体的场景——代码块的语法高亮。在本节中,我将展示如何使用prism.js突出显示一小段代码并在控制台应用程序中运行它。在开始之前,添加对JavaScriptEngineSwitcher.JurassicNuGet包的引用。dotnetaddpackageJavaScriptEngineSwitcher.Jurassic接下来,下载要运行的JavaScript文件。比如我从Prism.js网站下载了prism.js文件,在默认支持高亮的语言集中加入了C#。将文件放入项目文件夹的根目录后,我将文件更新为嵌入式资源。你可以在你的IDE中操作,也可以手动编辑工程文件:启用
