打字稿:从UMD模块执行IIFE,导入单独的模块

问题描述 投票:0回答:1

我有这样的tsconfig.json:

{
  "compilerOptions": {
    "lib": ["es2017", "dom"],
    "module": "umd",
    "outDir": "dist",
    "target": "es5",
    "declaration": true
  },
  "compileOnSave": true,
  "files": [
    "myClass.ts"
    "demo.ts"
  ]
}

我的打字稿,demo.ts

import { MyClass } from './myClass';

(() => {
  console.log('fired IIFE');
  document.onreadystatechange = function () {
    if (document.readyState === 'interactive') {
      console.log('hello world', MyClass);
    }
  };
})();

哪个被编译为:

(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "./myClass"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var myClass_1 = require("./myClass");
    (function () {
        console.log('fired IIFE');
        document.onreadystatechange = function () {
            if (document.readyState === 'interactive') {
                console.log('hello world', myClass_1.MyClass);
            }
        };
    })();
});

我的HTML:

<!DOCTYPE HTML>
<html>
<head>
  <title>Test</title>
  <script src="./dist/myClass.js"></script>
  <script src="./dist/demo.js"></script>
</head>
<body>
  <p>test</p>
</body>
</html>

我也尝试过:

<!DOCTYPE HTML>
<html>
<head>
  <title>Test</title>
</head>
<body>
  <p>test</p>
  <script src="./dist/myClass.js"></script>
  <script src="./dist/demo.js"></script>
</body>
</html>

两种方式都不执行脚本,也不打印日志语句。我究竟做错了什么?

typescript iife
1个回答
0
投票

事实证明,您需要使用requirejs来执行打字稿生成的UMD模块:

<!DOCTYPE HTML>
<html>
<head>
  <title>Test</title>
  <script data-main="dist/demo" type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.1/require.min.js"></script>
</head>
<body>
  <p>test</p>
</body>
</html>

这里发生的是data-main指向加载其他所有内容的.js文件。您不需要单独加载类脚本,require.js会为您执行此操作。

这让我感到震惊,因为使用gulp-wrap-umd包时,它提供的包装器不会为所附脚本创建隔离范围,它实际上是全局的,而typescript生成的UMD包装脚本具有隔离范围。

在这个实现中,我的bootstrapping脚本demo.js看起来像这样:

(function (factory) {
  if (typeof module === "object" && typeof module.exports === "object") {
      var v = factory(require, exports);
      if (v !== undefined) module.exports = v;
  }
  else if (typeof define === "function" && define.amd) {
      define(["require", "exports", "./myClass"], factory);
  }
})(function (require, exports) {
  "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  require(["./dist/myClass"], (myClassModule) => {

    console.log('my class:', myClassModule.MyClass);
  });

在日志语句所在的位置,您可以运行任何脚本而无需document.onready...或window.onload。

© www.soinside.com 2019 - 2024. All rights reserved.