如何将IIFE包裹的JS文件导入TS

How to import JS file wrapped in IIFE into TS

我有一个 TS 文件,我想导入一个封装在 IIFE 中的 JS 库的功能。该库目前通过在 window 对象上设置属性来公开其功能。如何将此库导入 TS?我尝试在每个函数前添加 exports,但出现错误 file is not a module。是不是硬着头皮手动把代码复制过来?

为了避免XY问题,我正在做一个网站,前端和后端都有一些共同的功能需要执行。我正在研究使用 TS 的无服务器后端。如果这是一个反模式,我应该完全做其他事情,我也会接受它作为答案。

我没有找到一个特别优雅的方法来做到这一点,但我通过从匿名函数返回我需要的特定函数并导出 IIFE 的结果得到了我想要的功能。 像这样:

JS 库(我添加了 export defaultreturn { ... }

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()

我的 tsconfig.json 文件中也有 "esModuleInterop": true

我通过发布和安装包含库的自定义定义的 NPM 包然后调整 tsconfig.json 以允许它来完成此操作。

  1. 在与 IIFE 库 .js 文件相同的目录中创建一个 index.d.ts 文件
  2. index.d.ts中添加单行:declare var libname = require('libname'); 例如:
declare var identikon_cljs = require('identikon_cljs');
  1. 将其发布为 npm 组织或用户范围的包:https://docs.npmjs.com/creating-and-publishing-scoped-public-packages
  2. 在您的项目中安装包(例如 npm i @mpm/identikon --save
  3. 添加以下 compilerOptions 或将其设置为 true 以防止 TypeScript 编译错误指出“环境上下文中不允许使用初始化程序”:
{
    "compilerOptions": {
        "allowJs": true,
        "allowSyntheticDefaultImports": true,
        "skipLibCheck": true
    }
}
  1. 像这样在您的组件中导入库:
import '@mpm/identikon';
  1. 然后您可以访问库的属性和方法,就好像它是作为模块导出的一样。这是我制定的指令示例:
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) { }

}
  1. 然后我可以像这样在 Ionic 2/3 项目中轻松绑定它:
<ion-avatar [identikon]="user.avatar" [width]="32" [height]="32" item-end></ion-avatar>