MorkJs docs
Guide

快速上手

最常用的工作流:编译核心库、执行脚本、输出模板、暴露 .NET 类型以及处理模块导入。

准备环境

编译与引用

  • 目标框架:.NET Framework 4.0(见 MorkJs/ShenGu.Script/ShenGu.Script.csproj)。
  • 直接在解决方案 MorkJs/ScriptTest.sln 中编译,或单独编译 ShenGu.Script 项目后引用生成的 DLL。
  • 没有 NuGet 包,按需将源码添加为子项目或本地引用。

示例入口

  • ScriptTestForm.cs 展示脚本、模板运行流程。
  • DefaultScripts.cs 提供类型映射、代理、import/export 的完整示例。
  • html/testhtml/build 目录包含脚本、组件化模板样例。

执行脚本

解析 JavaScript 语法并执行,结果通过 ScriptContext.Result 获取。

using ShenGu.Script;

// 缓存解析结果,MorkJs 支持多线程复用
var parser = MorkJs.Parse("var i = 0; return i + inc;");

// 准备上下文:添加变量或映射
var context = new ScriptContext();
context.AddValue("inc", 100);

// 执行并读取结果
parser.Execute(context);
var result = context.Result;   // 100

若不需要缓存 Parser,可使用 ScriptUtils.ExecuteScript(context, script) 一步到位。

执行模板

模板标签会被转换为脚本后执行,适合动态生成文本/HTML。

var context = new ScriptContext();
context.AddValue("status", 2);

var template = @"
状态码:
<@switch code=""status"">
  <@case code=""1"">正常</@case>
  <@case code=""2"">冻结</@case>
  <@default>其他状态</@default>
</@switch>";

var output = ScriptUtils.ExecuteTemplate(context, template);

使用 @{expr} 内联输出表达式;用 @@{expr} 时,null/undefined 也会被写出。

.NET 类型与对象映射

暴露成员到脚本

  • 在类型或成员上使用 [ObjectMember][ScriptObject] 控制可见成员;可通过 ObjectMemberFlags 指定公开范围。
  • 通过 context.RegisterTypes(typeof(User)) 注册类型后,脚本可直接 new User()
  • context.AddMappings(this) 遍历带 [ScriptMapping] 的方法/属性,作为全局函数或值注入脚本(参见 ScriptTestForm.Alert)。

代理与特殊类型

  • [ScriptProxy] 可为系统类型提供安全代理,例如 FormProxy 映射 WinForms Form,脚本端仍以 Form 名称使用。
  • DataTable 已内置代理:将 DataTableDataRow 加入上下文,脚本可通过 table.rows[i] 访问。
  • 需要自定义转换时,可设置 ScriptUtils.ObjectConverter 或使用 ScriptUtils.ToValue/ToScriptObject 手动转换。

处理 import / export

实现 IImportSourceManager 以自定义模块来源,例如从文件、数据库或内存读取。示例见 DefaultScripts.ImportExportExecutor

class ImportSourceManager : IImportSourceManager {
    public IImportSource GetSource(ScriptContext context, string path) {
        // 返回包含 Parser 或 Result 的 IImportSource
        return TemplateImportSource.CreateByScript(path, MorkJs.Parse(Read(path)));
    }
}

var ctx = new ScriptContext { ImportManager = new ImportSourceManager() };
ctx.AddValue("entry", "export.js");
var result = ScriptUtils.ExecuteScript(ctx, "import * as utils from entry; return utils.userId;");

模板中同样支持 <@import code="head" from="component/head.html"/><@export>

暂停与恢复

  • 脚本可调用 ScriptContext.Pause() 进入暂停,MorkJs.Execute 返回。
  • 外部逻辑完成后调用 context.Continue() 恢复,保持上下文栈与变量。
  • 配合 SetCacheValue/GetCacheValue 传递状态,适合批量任务或需要异步等待的场景。

模板组件与插槽

  • 在组件文件中定义:<@component export :siteName="'默认'" :menu="[]">...</@component>,可选 export(默认导出)或 id 指定命名导出。
  • 在使用处先声明可识别的组件标签:<@component define="head,foot" />,再用 <@head :siteName="'Demo'" :menu="menu"> 调用。
  • 使用 <@slot id="custom">...</@slot> 在组件中定义插槽;调用方用 <@template id="custom">...</@template> 覆盖。
  • 示例:MorkJs/ScriptTest/html/build/index.htmlcomponent/head.html