我有一个TS文件,我想导入一个封装在IIFE中的JS库的功能。该库目前通过在窗口对象上设置属性来公开其功能。如何将此库导入TS?我试过在每个函数之前添加exports
,但我得到了错误file is not a module
。我应该咬紧牙关手动复制代码吗?
为了避免XY问题,我正在制作一个网站,并且前端和后端都有一些需要执行的通用功能。我正在研究一个使用TS的无服务器后端,如果这是一个反模式,我应该做一些其他的事情,我也会接受这个答案。
我没有找到一种特别优雅的方法来做到这一点,但是通过从匿名函数返回我需要的特定函数并导出IIFE的结果,我获得了我想要的功能。像这样:
JS库(我添加了export default
和return { ... }
)
export default (function () {
function foo() { ... }
function bar() { ... }
function baz() { ... }
...
// the library makes some functions available to the window
window['baz'] = baz
// I manually export the functions I need
return {
'foo': foo
'bar': bar
}
})()
TS文件:
import lib from './library.js'
lib.bar()
我也有"esModuleInterop": true
在我的tsconfig.json
文件
我通过发布和安装一个包含库自定义定义的NPM包,然后调整tsconfig来实现这一点。
- 在与IIFE库.js文件相同的目录下创建一个
index.d.ts
文件 - 在
index.d.ts
中,添加一行:declare var libname = require('libname');
例如:
declare var identikon_cljs = require('identikon_cljs');
- 将其发布为npm组织或用户范围的包:https://docs.npmjs.com/creating-and-publishing-scoped-public-packages
- 在你的项目中安装包(例如
npm i @mpm/identikon --save
) - 添加或设置以下compilerOptions为true,以防止TypeScript编译错误声明&;在ambient context中不允许初始化&;
{
"compilerOptions": {
"allowJs": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true
}
}
- 在组件中导入库,如下所示:
import '@mpm/identikon';
- 您可以访问库的属性和方法,就像它作为一个模块导出一样。下面是我做的一个指令的例子:
import { Directive, ElementRef, Input, } from '@angular/core';
import '@mpm/identikon';
@Directive({
selector: '[identikon]'
})
export class Identikon {
@Input() width: number = 64;
@Input() height: number = 64;
@Input() set identikon(value: string) {
if (value) {
let id = 'identikon-' + value + '-' + new Date().getTime().toString();
this.el.nativeElement.setAttribute('id', id);
identikon_cljs.core.make_identikon('#' + id, this.width, this.height, value);
}
};
constructor(private el: ElementRef) { }
}
- 然后我可以轻松地将它绑定在Ionic 2/3项目中,如下所示:
<ion-avatar [identikon]="user.avatar" [width]="32" [height]="32" item-end></ion-avatar>