大家好,很高興又見面了,我是" 高級前端進階 ",由我帶著大家一起關註前端前沿、深入前端底層技術,大家一起進步,也歡迎大家關註、點贊、收藏、轉發!
1.什麽是 Jint
Jint 是 .NET 的 Javascript 直譯器,可以在任何現代 .NET 平台上執行,支持 .NET Standard 2.0 和 .NET 4.6.2 目標(及更高版本)。在效能方面,Jint 也是非常優秀:
Jint 可以適應以下典型場景:
Jint 的一些使用者包括 RavenDB、EventStore、OrchardCore、ELSA Workflows、docfx、JavaScript Engine Switcher 等等。
目前 Jint 在 Github 透過 BSD-2-Clause 協定開源,有超過 3.7k 的 star,1k 的 fork、1.7k 的專案依賴量,是一個值得關註的開源專案。
2.如何使用 Jint
基礎範例
下面範例定義了一個名為 log 的新值,該值指向 Console.WriteLine,然後執行一個呼叫 log('Hello World!') 的指令碼。
var engine = new Engine() .SetValue("log", new Action<object>(Console.WriteLine));engine.Execute(@" function hello() { log('Hello World'); }; hello();");
變量 x 設定為 3,並且 x * x 在 JavaScript 中計算。結果直接返回到 .NET,在本例中為雙精度值 9。
var square = new Engine() .SetValue("x", 3) // define a new variable .Evaluate("x * x") // evaluate a statement .ToObject(); // converts the value to .NET
還可以直接傳遞 POCO 或匿名物件並從 JavaScript 使用。例如,在此範例中,一個新的 Person 例項是透過 JavaScript 操作的。
var p = new Person { Name = "Mickey Mouse"};var engine = new Engine() .SetValue("p", p) .Execute("p.Name ='Minnie'");Assert.AreEqual("Minnie", p.Name);
可以呼叫 JavaScript 函數參照:
var add = new Engine() .Execute("function add(a, b) { return a + b; }") .GetValue("add");add.Invoke(1, 2); // -> 3
或者透過函數名稱呼叫:
var engine = new Engine() .Execute("function add(a, b) { return a + b; }");engine.Invoke("add", 1, 2); // -> 3
存取 .NET 程式集和類
開發者可以透過如下配置引擎例項來允許引擎存取任何 .NET 類:
var engine = new Engine(cfg => cfg.AllowClr());
然後就可以將系統名稱空間作為全域值進行存取。以下是它在命令列實用程式上下文中的使用方式:
jint> var file = new System.IO.StreamWriter('log.txt');jint> file.WriteLine('Hello World !');jint> file.Dispose();
國際化
如果不想使用電腦的預設值,則可以在使用區域設定 JavaScript 方法時強制引擎應使用的時區或文化,下面範例強制將時區設定為太平洋標準時間。
var PST = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");var engine = new Engine(cfg => cfg.LocalTimeZone(PST));engine.Execute("new Date().toString()"); // Wed Dec 31 1969 16:00:00 GMT-08:00
下面範例使用法語作為預設區域性:
var FR = CultureInfo.GetCultureInfo("fr-FR");var engine = new Engine(cfg => cfg.Culture(FR));engine.Execute("new Number(1.23).toString()"); // 1.23engine.Execute("new Number(1.23).toLocaleString()"); // 1,23
使用模組
可以使用模組從多個指令碼檔匯入和匯出變量:
var engine = new Engine(options =>{ options.EnableModules(@"C:\Scripts");})var ns = engine.Modules.Import("./my-module.js");var value = ns.Get("value").AsString();
預設情況下,模組解析演算法將僅限於 EnableModules 中指定的基本路徑,並且沒有包支持。但是,開發者可以透過兩種方式提供自己的包。 使用 JavaScript 原始碼定義模組:
engine.Modules.Add("user", "export const name ='John';");var ns = engine.Modules.Import("user");var name = ns.Get("name").AsString();
或者使用模組構建器定義模組,其允許從 .NET 匯出 CLR 類和值:
// Create the module 'lib' with the class My class and the variable versionengine.Modules.Add("lib", builder => builder .ExportType<My class>() .ExportValue("version", 15));// Create a user-defined module and do something with 'lib'engine.Modules.Add("custom", @" import {My class, version} from 'lib'; const x = new My class(); export const result as x.doSomething();");// Import the user-defined module; this will execute the import chainvar ns = engine.Modules.Import("custom");// The result contains "live" bindings to the modulevar id = ns.Get("result").AsInteger();
3.Jint 的安全性
以下功能為開發者提供了一個安全的沙盒環境來執行使用者指令碼:
4.本文總結
本文主要和大家介紹 Jint ,其是 .NET 的 Javascript 直譯器,可以在任何現代 .NET 平台上執行,支持 .NET Standard 2.0 和 .NET 4.6.2 目標(及更高版本)。因為篇幅問題,關於 Jint 主題只是做了一個簡短的介紹,但是文末的參考資料提供了大量優秀文件以供學習,如果有興趣可以自行閱讀。如果大家有什麽疑問歡迎在評論區留言。
參考資料
https://github.com/sebastienros/jint
https://blog.devgenius.io/a-javascript-rules-engine-in-net-6-fb092cdc44c
https://github.com/topics/jint