如何在 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 = {}'。
我正在尝试将 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 = {}'。