如何将基于IIFE的JavaScript模块导入Angular TypeScript应用程序?

Zac*_*hal 5 javascript iife typescript webpack angular

因此,我有一个第三方SDK,写为基于Oldschool IIFE的模块。换句话说,它看起来像这样:

var ThirdPartySDK = (function() {
  var export = {};

  // Add some methods to export

  return export;
})();
Run Code Online (Sandbox Code Playgroud)

然后,您应该通过在全局范围内引用它来使用它,如下所示:

<html>
  <body>
    <script src="lib/ThirdPartySDK.js">
    <script>
      ThirdPartySDK.foo();
    <\script>
  <\body>
<\html>
Run Code Online (Sandbox Code Playgroud)

当然,我仍然可以以这种方式使用它,但这真的是Angular和TypeScript的最佳实践吗?有什么方法可以使用angular / TypeScript / webpack进行设置,以便可以使用正确的import语句?像这样:

import { ThirdPartySDK } from '../lib/ThirdPartySDK.js';
ThirdPartySDK.foo();
Run Code Online (Sandbox Code Playgroud)

Jef*_*amp 6

为 的实际提供正确的导入语句的最佳方法ThirdPartySDK是将脚本重构为导出该值的模块。以下代码片段允许您使用所示的导入语句:

export const ThirdPartySDK = {
    foo() { console.log('Doing foo'); }
};
Run Code Online (Sandbox Code Playgroud)

对于大型库来说,重构并不总是那么容易,所以我看到了两种不涉及太多重构的方法:


1.导出ThirdPartySDK变量

您可以简单地通过导出当前变量(由 IIFE 返回)来从 IIFE 文件创建一个模块IThirdPartySDK,然后按照所示导入它:

export const ThirdPartySDK = {
    foo() { console.log('Doing foo'); }
};
Run Code Online (Sandbox Code Playgroud)

请注意,如果您想获得一些有关形状的有用信息,则ThirdPartySDK必须在const声明中添加类型注释,如果SomeType(见下文)尚不存在,则必须自己编写:

export const ThirdPartySDK: SomeType = (function() {
// ...
Run Code Online (Sandbox Code Playgroud)

此时 Typescript 将开始抱怨 IIFE 表达式无法分配给 SomeType;告诉打字稿假装表达式计算为SomeType使用as关键字的类型值的快速“解决方案”:

export const ThirdPartySDK: SomeType = (function() {
    // ...
})() as SomeType;
Run Code Online (Sandbox Code Playgroud)

2.保留<script>标签并声明变量

另一种选择是保留脚本标签,不导入任何内容,并在打字稿中声明变量及其预期类型:

(但在这种情况下,您可能必须自己提供类型定义)

interface SomeType {
    // SDK type shape goes here...
}

declare const ThirdPartySDK: SomeType;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我有点不愿意用导出语句修改源文件,因为我希望能够在新版本出现时插入它。该声明可能是唯一的方法,但我希望我可以做一些聪明的事情,例如在单独的模块中隔离/导出 IIFE 的全局作用域或其他东西。 (2认同)