通过typescript 开发jint js 插件

以前简单讲过开发机制以及设计,以下是集成typescript 方便进行开发的似乎以及简单示例代码

项目依赖的包

为了方便处理使用了tsup进行构建,同时基于ts 类型定义提供types 支持

代码简单说明

包含了对于公共部分的type 定义,以及插件部分代码引用

  • 代码结构
├── loginplugin
│   ├── app.json
│   ├── myconfig.ts
│   └── userlogin.ts
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── types
│   ├── global.d.ts
│   └── platform.d.ts
└── yarn.lock
  • package.json
{
  "name": "modules",
  "version": "1.0.0",
  "license": "MIT",
  "devDependencies": {
    "tsup": "^8.5.0",
    "typescript": "^5.8.3"
  },
  "type": "module",
  "main": "dist/userlogin.js",
  "module": "dist/userlogin.js",
  "types": "dist/userlogin.d.ts",
  "files": [
    "dist",
    "README.md",
    "LICENSE",
    "types/platform.d.ts",
    "types/global.d.ts"
  ],
  "exports": {
    ".": "./dist/userlogin.js",
    "./package.json": "./package.json"
  },
  "scripts": {
    "build": "tsup",
    "pack": "npm pack"
  }
}
  • tsconfig.json
{
  "compilerOptions": {
    "types": [
      "./types/platform.d.ts",
      "./types/global.d.ts"
    ],
    "resolveJsonModule": true,
    "target": "es2017",
    "module": "commonjs",
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "skipLibCheck": true
  }
}
  • tsup.config.ts
import { defineConfig } from 'tsup'

export default defineConfig({
    entry: ['loginplugin/userlogin.ts'],
    splitting: false,
    sourcemap: true,
    minify: false,
    format:"esm",
    dts: true,
    external:["@scope/platform-common"], // @scope/platform-common 作为外部
    clean: true,
})
  • common 定义

包含了模块以及require 以及importNamespace

global.d.ts 属于公共定义,方便支持强类型定义,主要是类型定义

export {}

class Shortid {
    static Generate(): string
}
type ShortIdModule = {
    ShortId: typeof Shortid
}

interface ModuleMap {
  shortid: ShortIdModule;
}

interface  Platform {
        funcs: {
            queryDb: (name: string) => Promise<string>;
            add: (name: string) => Promise<string>;
            init: () => Promise<void>;
        };
        name: string;
        version: string;
        description: string;
}

type PlatformModule = {
  "@scope/platform-common":  {
    platform: Platform
  }
}


type PlatformTypes = "@scope/platform-common" | "platform-login"

type ModuleTypes = "shortid"
// 包装的global, 方便require 以及importNamespace 使用强类型,注意改写了node 的require(兼容jint),importNamespace 是jint 提供的
declare  global {
    function require<K  extends  PlatformTypes>(name: K): PlatformModule[K]
    function importNamespace<K extends ModuleTypes>(name: K): ModuleMap[K]
}
  • platform.d.ts 模块定义
declare  module  "@scope/platform-common" {
    export  interface  Platform {
        funcs: {
            queryDb: (name: string) => Promise<string>;
            add: (name: string) => Promise<string>;
            init: () => Promise<void>;
        };
        name: string;
        version: string;
        description: string;
    }
    export  const platform: Platform;
}

declare module "shortid" {
    export class ShortId {
        static Generate(): string;
    }
}
namespace System {
    namespace  IO {
        export class StreamWriter {
            constructor(fileName: string);
            WriteLine(line: string): void;
            Dispose(): void;
        }
    }
}
  • loginplugin/userlogin.ts

简单插件定义,会使用common 以及通过系统clr 暴露的三方库

import  {platform} from  "@scope/platform-common"
import   conf from  "./myconfig";
import appJson from  "./app.json";  
async function getNames(name:string):Promise<string> {
    console.log("getNames "+name)
    return  await platform.funcs.queryDb(name);
}
function po(ob:string):string {
    console.log(JSON.stringify(ob))
    let ob_new  = JSON.parse(ob);
    ob_new.Login = (name:string)=> name;
    ob_new.Name = "dddddddddddd" + Math.random()*100;
    let  token = ob_new.Login(ob_new.Name);
    console.log("token"+token);
    return JSON.stringify(ob_new);
}

function  fs_op() {
    let file = new System.IO.StreamWriter(`log-${Math.random()*100}.txt`);
    file.WriteLine("Hello World");
    file.Dispose();
}


function my_id():void {
    console.log("my_conf"+ JSON.stringify(conf));
    let platform = require("@scope/platform-common");
    console.log("appJson"+JSON.stringify(appJson));
    console.log(platform.platform.description);
    let shortid = importNamespace("shortid");
    let id = shortid.ShortId.Generate();
    console.log("myid: "+id);
}
const   queryUser = {
    name: "dalong demo",
    qv2: platform.funcs.queryDb,
    add: platform.funcs.add,
    init: platform.funcs.init,
    getNames: getNames,
    po: po,
    fs_op: fs_op,
    id:my_id,
    qv2Async:platform.funcs.queryDb
}

export  default  queryUser
  • c# 代码使用

实际上就是通过engine 引用模块,调用模块里边的方法

var ns = _engine.Modules.Import("./dist/userlogin.js").Get("default").AsObject();
var fn = ns.Get("id").AsFunctionInstance();
n.Call().UnwrapIfPromise();
  • 打包

对于打包我们实际上可以直接复用npm 的,对于使用方基于npm 周边生态的玩法就可以了,平台部分提供调用npm api 的下载,解压,解析等

说明

以上是一个简单示例,比较粗糙,实际上对于common 部分的types 使用通用的包,对于插件部分使用更加明确的生命周期方法开发就会清晰不少,对于开发者也就比较友好了,后边抽象一个通用的模型

参考资料

https://github.com/egoist/tsup

https://tsup.egoist.dev/#typescript--javascript

https://www.npmjs.com/package/@types/k6?activeTab=code

https://github.com/grafana/k6-template-typescript/tree/main

posted on 2025-07-25 08:00  荣锋亮  阅读(21)  评论(0)    收藏  举报

导航