如何在 Duktape 中使用打字稿模块

How to use typescript modules with Duktape

我正在尝试将 JS 用作游戏引擎中的脚本语言,并在顶部使用 TypeScript。作为运行时,我使用 Duktape。关于 JavaScript,我完全是个菜鸟,目前我正在努力思考如何启用一个工作流程,让人们可以#include(需要等)其他文件。

出于测试目的,我从两个简单的 TypeScript 文件开始:

Foo.ts

declare function Print(text : string) : void;

export module Foo 
{
    export function GetFoo(): string 
    {
        return "Foo"
    }

    Print("Foo: " + GetFoo())
}

Bar.ts

import { Foo } from "./Foo"

declare function Print(text: string): void;

Print("Bar: " + Foo.GetFoo())

现在我将两者都通过 TypeScript 的 Transpile 函数(来自 typescriptServices.js)并得到:

Foo.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Foo;
(function (Foo) {
    function GetFoo() {
        return "Foo";
    }
    Foo.GetFoo = GetFoo;
    Print("Foo: " + GetFoo());
})(Foo = exports.Foo || (exports.Foo = {}));

Bar.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Foo_1 = require("./Foo");
Print("Bar: " + Foo_1.Foo.GetFoo());

然后我想通过 Duktape 执行 Bar.js。我读过 this 所以我的理解是有多种方法可以使包含其他文件工作,但是这个似乎专门使 'require' 函数工作,所以对于 TypeScript 的 JS 代码来说听起来是正确的为我生成。所以我创建了一个 Duktape 上下文,我在其上调用 duk_module_duktape_init 并注册了一个 'modSearch' 函数等。但是在它实际到达 Bar.js 的 'require' 部分之前,Duktape已经失败并显示消息 "ReferenceError: identifier 'exports' undefined".

如前所述,我对 JS 和 TS 真的很陌生,可能对这整个努力有错误的想法,所以请随意提出完全不同的方法。我所关心的是用户可以将代码拆分成多个文件,并以某种方式引用这些文件,以便 VS Code 等工具可以找出这些引用并提供它们的功能来开发代码。我不在乎我最终是使用 'require' 还是 'import' 以及我是否可以使用所有 TS 功能或只是一些子集。

长话短说,我做错了什么,我该如何解决这个问题?

昨晚深夜我弄清楚了我的问题所在,我会post在这里以防有人遇到类似的问题。

问题是 TypeScript 生成了代码来为两个文件设置“__esModule”属性。只有 Foo.ts 导出任何东西并在 'require' 调用中使用,但是对于 Bar.ts 转译的 JS 代码也想访问 'exports' 对象。

在 Duktape 中,当您使用 duk_module_duktape_init 启用对 'require' 函数的支持时,它将生成一个 'exports' 对象,但只有在您通过实际的 'require()'当然只调用要加载的模块。

这里的问题是顶层文件(不是通过 require-call 加载的)已经尝试访问一个 'exports' 这个文件不存在的对象。

解决方案非常简单,就是创建一个虚拟对象,即。通过在顶级脚本文件前添加 'var exports = {}'。