更新时间:2022-04-26 GMT+08:00
分享

脚本的模块使用限制

TypeScript执行引擎没有自带模块管理,需要嵌入引擎时,开发人员则需要手动引用。

模块管理机制类似Node.js,但因为平台是基于数据库存放脚本,没有目录与路径的概念,所以下面的module管理只是一个简化版本的Node.js模块管理,也不支持npm的整套机制。

脚本文件和模块是一一对应的,每个脚本被视为一个独立的模块。

例子,假设有一个名为foo的脚本:

import * as circle from './命名空间__circle';
console.log(`半径为 4 的圆的面积是 ${circle.area(4)}`);

在第一行中,foo加载circle模块。

circle脚本的内容为:

const { PI } = Math;

exports.area = (r) => PI r *2;

exports.circumference = (r) => 2 PI r;

circle模块导出了area() 和circumference()两个函数。 通过在特殊的exports对象上指定额外的属性,函数和对象可以被添加到模块的根部。

模块内的本地变量是私有的,因为模块被装在一个函数中。 在这个例子中,变量PI是circle私有的。

import语法

Typescript模块import语法,请参考typescrip官方网站

标准库模块

AppCube中有些模块会被编译成二进制,预先加载到内存中了。例如decimal、context都是系统预置的标准库模块。

AppCube优先加载标准库模块, 例如:

import * as http from 'http';

始终返回内置的HTTP模块,即使有同名自定义模块。

如果需要返回自定义的模块,请使用相对路径语法:

import * as http from './http';

标准库模块的详细介绍,请参见什么是脚本

扩展名

因为脚本实际上是存在数据库中,脚本没有路径的概念,扩展名也没有特别的意义。

导入模块时,尽量采用不带扩展的方式。例如:

import * as circle from './circle';

平台只允许.ts扩展名文件存在,不允许包含.js后缀的模块。如下方式等同上面的举例,但不推荐。

import * as circle from './circle.ts';

尽量不要使用带扩展名的导入方式。

循环依赖

当循环调用模块时,一个模块可能在未完成执行时被返回。因此,需要仔细的规划模块间调用,以允许循环模块依赖在应用程序内正常工作。

例如以下情况:

脚本a:

console.log('a 开始');
exports.done = false;
import * as b from 'b';
console.log('在 a 中,b.done = ', b.done);
exports.done = true;
console.log('a 结束');

脚本b:

console.log('b 开始');
exports.done = false;
import * as a from 'a';
console.log('在 b 中,a.done = ', a.done);
exports.done = true;
console.log('b 结束');

脚本main:

console.log('main 开始');
import * as a from 'a';
import * as b from 'b';
console.log('在 main 中,a.done = ', a.done ',b.done = ', b.done);

当main加载a时,a又加载b。 此时,b又会尝试去加载a。 为了防止无限的循环,会返回一个a的exports对象的未完成的副本给b模块。

然后b完成加载,并将exports对象提供给a模块。

当main加载这两个模块时,它们都已经完成加载。 因此,该程序的输出会是:

main 开始
a 开始
b 开始
在 b 中,a.done = false
b 结束
在 a 中,b.done = true
a 结束
在 main 中,a.done=true,b.done=true
分享:

    相关文档

    相关产品

关闭导读