Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >在 .NET 应用程序中运行 JavaScript

在 .NET 应用程序中运行 JavaScript

作者头像
独立观察员
发布于 2022-12-06 11:13:33
发布于 2022-12-06 11:13:33
2.8K00
代码可运行
举报
运行总次数:0
代码可运行

前几天我在做一个副业,意识到我需要使用一些 JavaScript 功能。一想到要再次处理 Node.js 和 npm,我就完全放弃了,所以我决定研究一下在 .NET 应用程序中运行 JavaScript 的可能性。很疯狂吧?实际上,这出乎意料的简单。

1你为什么要这样做?

尽管我很喜欢 .NET 生态系统,但有些事情,JavaScript 生态系统做得更好。其中之一就是任何事情都能找到一个库,特别是涉及到网络时。

以语法高亮为例。这可以直接用 C# 来做,但这不是一个特别流畅的体验。例如,TextMateSharp 项目为 TextMate 语法提供了一个解释器。这些文件是 VS Code 用来为一种语言添加基本语法高亮的。然而,如果你想部署应用程序,它包装了一个本地依赖,这就增加了一些复杂性。

相比之下,JavaScript 有大量成熟的语法高亮库。仅举几例,有 highlight.jsPrism.js(在本博客中使用)和 shiki.js。尤其是前两个,非常成熟,有多个插件和主题,而且有简单的 API

作为一个 .NET 开发者,JavaScript 的明显问题是,你需要学习并选择进入一个完整的独立工具链,与 Node.js 和 NPM 一起工作。这似乎是一个很大的开销,只是为了使用一个小功能。

因此,我们陷入了一个困境。我们要么走 C#(+ Native)路线,要么就得转用 JavaScript。

或者......我们直接从我们的 .NET 应用程序中调用 JavaScript 🤯

2在 .NET 中运行 JavaScript

一旦你决定在你的 .NET 代码中运行 JavaScript,你就会考虑几个选择。你可以借用 JavaScript 引擎,让它为你运行你的 JavaScript,但你并没有真正解决问题,你仍然需要安装 Node.js。

另一个选择是在你的库中直接捆绑 JavaScript 引擎。这并不像听起来那么疯狂,有几个 NuGet 包采用了这种方法,然后暴露出一个 C# 层来与引擎进行交互。

下面是你可以使用的一些包的列表。

Jering.Javascript.NodeJS

这个库采取了上述的第一种方法。它不包括包中的 Node.js。相反,它为执行 JavaScript 代码提供了一个 C# API,并调用了安装在你机器上的 Node.js。这在你知道两者都已安装的环境中可能很有用,但它并没有真正解决我想避免的问题。

ChakraCore

ChakraCore 是 Edge 转为基于 Chromium 引擎之前最初使用的 JavaScript 引擎。根据 GitHub 项目的介绍:

ChakraCore 是一个带有 C 语言 API 的 JavaScript 引擎,你可以用它来为任何 C 语言或 C 语言兼容项目添加对 JavaScript 的支持。它可以在 Linux macOS 和 Windows 上针对 x64 处理器进行编译。而 x86 和 ARM 只适用于 Windows。

因此,ChakraCore 包括一个本地依赖,但由于 C# 可以 P/Invoke 到本地库,这本身并不是一个问题。但它会带来一些部署方面的挑战。

ClearScript (V8)

Node.JS、Chromium、Chrome 和最新的 Edge 使用的都是 V8 JavaScript 引擎。Microsoft.ClearScript 包为该库提供了一个封装,为调用 V8 库提供了一个 C# 接口。就像 ChakraCore 一样,V8 引擎本身是一个本地依赖。ClearScript 库负责 P/Invoke 调用,提供了一个很好的 C# API,但你仍然要确保你在目标平台上部署了正确的本地库。

Jint

Jint 很有意思,因为它是一个完全在 .NET 中运行的 JavaScript 解释器,没有任何本地的依赖!它完全支持 ECMAScript 5.1 (ES5),并支持 .NET Standard 2.0,所以你可以在你的所有项目中使用它!

Jurassic

Jurassic 是另一个 JavaScript 引擎的 .NET 实现,类似于 Jint。也和 Jint 类似,它支持所有的 ES5,而且似乎也部分支持 ES6。与 Jint 不同的是,Jurassic 不是一个解释器,它将 JavaScript 编译成 IL,这使得它的速度非常快,而且它没有本地的依赖性。

那么,在所有这些选择中,你应该选择哪一个?

3JavaScriptEngineSwitcher:当一个 JS 引擎不够用的时候

还有一个伟大的项目可以让你简单地尝试上面其中的任何一个库。虽然所有的库都允许你运行 JavaScript,但它们都有略微不同的 C# API 来与之交互。这可能会使比较它们变得有点痛苦,因为你必须为每个库学习不同的 API。

JavaScriptEngineSwitcher 这个库为我提到的所有库和更多的库提供了封装:

  • Jering.Javascript.NodeJS
  • ChakraCore
  • Microsoft ClearScript.V8
  • Jint
  • Jurassic
  • MSIE JavaScript Engine for .NET
  • NiL.JS
  • VroomJs

每个库都在一个单独的包中(有本地依赖关系的引擎需要一个额外的本地包),还有一个 Core 包,它提供通用的 API。即使你不打算切换 JS 引擎,我也倾向于尽可能地使用 JavaScriptEngineSwitcher 封装库,这样你就不必在以后需要切换引擎时弄清楚一个新的 API 了。

在 .NET 项目中改变使用的 JavaScript 引擎在我看来是完全可能的。例如,我开始使用 Jint,但当我需要执行更大的脚本时,我遇到了性能问题,于是换成了 JurassicJavaScriptEngineSwitcher 让这一切变得很简单,只需在我的项目中添加一个新的包并改变一些初始化代码即可。

我最近才发现 JavaScriptEngineSwitcher 这个库,但最新版本的下载量已接近一百万,它被用于 .NET 静态网站建设Statiq 中。在这篇文章的最后部分,我将举一个最基本用法的例子。

4案例:用 JavaScriptEngineSwitcher 在控制台应用中运行 prism.js

在这篇文章的开头,我讨论了一个特定的场景--代码块的语法高亮。在本节中,我将展示如何使用 prism.js 高亮一小段代码,并在一个控制台应用程序中运行。

开始之前请添加 JavaScriptEngineSwitcher.Jurassic NuGet 包的引用。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
dotnet add package JavaScriptEngineSwitcher.Jurassic

接下来,下载你想运行的 JavaScript 文件。例如,我从 Prism.js 的官网下载了 prism.js 文件,并将 C# 添加到默认支持高亮的语言集。在把文件放到项目文件夹的根目录后,我把文件更新为嵌入资源。你可以在你的 IDE 中操作,也可以手动编辑项目文件:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="JavaScriptEngineSwitcher.Jurassic" Version="3.17.4" />
  </ItemGroup>

  <!-- 👇 Make prism.js an embedded resource -->
  <ItemGroup>
    <None Remove="prism.js" />
    <EmbeddedResource Include="prism.js" />
  </ItemGroup>

</Project>

剩下的就是编写代码,在我们的程序中运行脚本。下面的代码段设置了 JavaScript 引擎,从程序集中加载嵌入的 prism.js 库,并执行它。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
using JavaScriptEngineSwitcher.Jurassic;

// Create an instance of the JavaScript engine
IJsEngine engine = new JurassicJsEngine();

// Execute the embedded resource called JsInDotnet.prism.js from the provided assembly
engine.ExecuteResource("JsInDotnet.prism.js", typeof(Program).Assembly);

现在我们可以在同一个上下文中运行我们自己的 JavaScript 命令。我们可以通过使用 SetVariableNameExecuteEvaluate 从 C# 向 JavaScript 引擎传递数值:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// This is the code we want to highlight
string code = @"
using System;

public class Test : ITest
{
    public int ID { get; set; }
    public string Name { get; set; }
}";

// set the JavaScript variable called "input" to the value of the c# variable "code"
engine.SetVariableValue("input", code);

// set the JavaScript variable called "lang" to the string "csharp"
engine.SetVariableValue("lang", "csharp");

// run the Prism.highlight() function, and set the result to the "highlighed" variable
engine.Execute($"highlighted = Prism.highlight(input, Prism.languages.csharp, lang)");

// "extract the value of "highlighted" from JavaScript to C#
string result = engine.Evaluate<string>("highlighted");

Console.WriteLine(result);

当你把它们放在一起运行时,高亮的代码会被打印到控制台:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span>

<span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Test</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">ITest</span></span>
<span class="token punctuation">{</span>
    <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> ID <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
    <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Name <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
<span class="token punctuation">}</span>

渲染后,看起来像这样:

我对整个过程的简单程度感到惊讶。启动一个 JavaScript 引擎,加载 prism.js 文件,并执行我们的自定义代码是如此顺利。这是我面临问题的完美解决方案。

我显然不建议所有的应用程序都这样做。如果你需要运行大量的 JavaScript,那么直接使用 Node.js 生态系统及工具可能更容易。但如果你只是想利用一个小型的、独立的工具(如 prims.js),那么这是一个不错的选择。

5总结

在这篇文章中,我展示了如何使用 JavaScriptEngineSwitcher NuGet 包来在 .NET 应用程序中运行 JavaScript。这个包为许多不同的 JavaScript 引擎提供了一个一致的接口。其中一些引擎(如 Chakra CoreV8)需依赖一个本地组件,而其他引擎(如 JintJurassic)只使用托管代码。最后,我展示了你如何使用 JavaScriptEngineSwitcher 在 .NET 应用程序内部运行 Prims.js 代码高亮库。

原文:bit.ly/38awq7W 作者:Andrew Lock 翻译:精致码农

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 独立观察员博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
JavaScript 是怎么运行起来的?
JavaScript 的运行原理,是我面试的时候经常会问到的问题,但是根据过往的面试结果来看,这部分能理解的很清楚的不足 20%,大多数同学热衷于去学习一些 Vue、React 这样的框架,以及一些新的 API,却忽视了语言的根本,这是个非常不好的现象。
ConardLi
2022/02/18
6200
JavaScript 是怎么运行起来的?
SpringMVC【入门】篇(转载自https://blog.csdn.net/qq_40181435/article/details/105599178)
在WEB-INF下创建文件夹pages,并在pages中创建跳转页面success.jsp
_DIY
2020/06/11
1.5K0
SpringMVC【入门】篇(转载自https://blog.csdn.net/qq_40181435/article/details/105599178)
盘点2个.Net版本的JavaScript执行引擎
Jurassic是一个开源的托管JavaScript执行引擎,使用MS-PL授权协议。它的目标是成为.NET平台上功能最强,最为标准的JavaScript引擎。
郑子铭
2024/04/29
2240
盘点2个.Net版本的JavaScript执行引擎
Prism:轻量级的 Javascript 代码高亮库
代码高亮的程序或者 WordPress 插件有很多,但是在碰到 Prism 之前,我爱水煮鱼都没有使用代码高亮的程序,就是因为以前的那些代码高亮的程序或者插件太臃肿或者复杂,使用起来不方便。那么 Prism 有哪些地方吸引了我呢?
Denis
2023/04/14
8760
Prism:轻量级的 Javascript 代码高亮库
Vue项目兼容IE11
Vue 不支持 IE8 及以下版本,因为 Vue 使用了 IE8 无法模拟的 ECMAScript 5 特性。但对于 IE9+,Vue 底层是支持。
奋飛
2021/08/30
2.9K0
Vue项目兼容IE11
微软自家的.Net下的JavaScript引擎--- ClearScript
微软开源的 JavaScript引擎——ClearScript(当然,也支持VB Script):https://github.com/microsoft/ClearScript ,昨天做了一个大的改变,就是把C++/CLI代码移除了,这就意味着脱离Windows,可以在linux上运行了。
张善友
2020/10/28
1.8K0
微软自家的.Net下的JavaScript引擎--- ClearScript
通过ClearScript V8在.NET中执行复杂JavaScript逻辑
在现代网络开发中,爬虫技术已成为数据采集和分析的核心手段之一。通常,爬虫程序需要处理复杂的JavaScript逻辑,尤其是在面对动态加载的网页时。这时,传统的HTTP请求和HTML解析已经无法满足需求。为了应对这些挑战,我们可以在.NET中集成JavaScript引擎,通过ClearScript V8库执行复杂的JavaScript逻辑,从而更有效地抓取动态内容。
jackcode
2024/08/26
1620
利用 target=_blank 进行前端钓鱼
Phishing,攻击者利用欺骗性的电子邮件和伪造的 Web 站点来进行网络诈骗活动,受骗者往往会泄露自己的私人资料,如信用卡号、银行卡账户、身份证号等内容。诈骗者通常会将自己伪装成网络银行、在线零售商和信用卡公司等可信的品牌,骗取用户的私人信息。
奋飛
2021/08/30
5220
纯代码给 WordPress 文章编辑器上增加 Prism.js 代码高亮的快捷按钮
之前发过文章说过:使用 Prism.js 实现漂亮的代码语法高亮,本博客也使用的是它
沈唁
2018/12/12
2.4K0
VS Code、ATOM这些开源文本编辑器的代码实现中有哪些奇技淫巧?
最近看了一下文本编辑方面的算法,发现坑还挺多,富文本更是被称之为天坑,一个office word可以复杂到和操作系统、浏览器一样的程度,这其中现代化的文本编辑器非vscode莫属,本文和大家一起开开眼界,以后有意在文本编辑器方面进坑的可以研究一下。
ACM算法日常
2020/02/25
1.7K0
VS Code、ATOM这些开源文本编辑器的代码实现中有哪些奇技淫巧?
JavaScript 和 Python 代码也能结合使用?
最近在 Github 上发现一个非常有意思的项目 PythonMonkey ,它可以让我们直接在 JavaScript 中运行 Python 代码,也可以在 Python 中运行 JavaScript 和 WebAssembly 代码,而且几乎没有性能损失。
ConardLi
2023/08/23
6420
JavaScript 和 Python 代码也能结合使用?
Nginx 中运行 JavaScript
Nginx 作为市场占有率最高的Web服务器,主打高性能、可扩展。自带了很多核心功能模块,并且也有大量的第三方模块。
ConardLi
2021/08/10
2.8K0
Butterfly美化
最最最开始的,好不容易搭建了自己的个人博客,当然要写上自己的名字、签名…,证明身份。而且身为一个Chinese,还是中文舒服,所以主目录下_config.yml的配置文件:
张小驰出没
2021/04/15
3.5K0
Butterfly美化
深入理解 JavaScript 引擎
食堂老板:这块的知识不仅面试可能会问,学会了 JS 引擎的工作原理,可以更好的理解 JavaScript、更好的理解前端生态中 Babel 的词法分析和语法分析,ESLint 的语法检查原理以及 React、Vue 等前端框架的实现原理。总之,学习引擎原理可谓是一举多得。
ConardLi
2021/09/29
1K0
深入理解 JavaScript 引擎
基于 Django 的个人网站(3)
因为 django-ckeditor-5 里面默认是没有可以选择语言代码块插件的,所以我们需要自己定制这个插件,定制之前我们首先去 GitHub 把 django-ckeditor-5 下载下来,下面直接给出 GitHub 的项目地址:
不可言诉的深渊
2020/05/27
2.6K0
Edge.js:让.NET和Node.js代码比翼齐飞
通过Edge.js项目,你可以在一个进程中同时运行Node.js和.NET代码。在本文中,我将会论述这个项目背后的动机,并描述Edge.js提供的基本机制。随后将探讨一些Edge.js应用场景,它在这
张善友
2018/01/30
3.7K0
Javascript 是最好的语言,不服来辩
看到这个标题相信很多人就要开始跟我争论了,PHP 才是最好的语言,那就请原谅下,你说是就是,我们来看看就知道了。 有一条 Atwood 定律:any application that can be written in JavaScript, will eventually be written in JavaScript 翻译一下就是:任何可以用 JavaScript 来写的应用,最终都将用 JavaScript 来写 要是没看到过这句话的人可能又要开始说了,Atwood 是谁,他说最终会就会啊。 那我
桃翁
2018/06/27
2K0
从Javascript到Typescript到Node.js
最近看了点typescript的东西,加上以前看过的一点点Node.js,所以就想把他们系统地整理一下。
owent
2018/08/01
2.4K0
使用 Prism.js 实现漂亮的代码语法高亮
给大家推荐一个代码高亮显示的东东,直接使用一个 JavaScript 库 —— Prism 是一款轻量、可扩展的代码语法高亮库,使用现代化的 Web 标准构建。 为什么选择 Prism.js ? 极致易用引用 prism.css 和 prism.js,使用合适的 HTML5 标签(code.language-xxxx),搞定!天生伶俐语言的 CSS 类是可继承的,所以你只需定义一次就能应用到多个代码片段。轻如鸿毛代码压缩后只有 1.6KB。每添加一个语言平均增加 0.3-0.5KB,主题在 1KB 左右
沈唁
2018/05/24
4.4K0
.NET Core vs Node.js:你应该选择哪个?
本文最初发布于 inveritasoft.com 网站,经网站授权由 InfoQ 中文站翻译并分享。
深度学习与Python
2020/10/26
1.9K0
.NET Core vs Node.js:你应该选择哪个?
推荐阅读
相关推荐
JavaScript 是怎么运行起来的?
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验