打字稿:从导入单独模块的UMD模块执行IIFE
Typescript: execute IIFE from UMD module that imports separate module
我有一个 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>
两种方式都不执行脚本,也不打印日志语句。我做错了什么?
原来你需要使用 requirejs 来执行 typescript 生成的 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 文件。您不需要单独加载 class 脚本,require.js 会为您完成。
这让我很震惊,因为使用 gulp-wrap-umd
包时,它提供的包装器不会为包含的脚本创建隔离范围,它实际上是全局的,而打字稿生成的 UMD 包装脚本具有隔离范围。
在此实现中,我的引导脚本 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。
我有一个 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>
两种方式都不执行脚本,也不打印日志语句。我做错了什么?
原来你需要使用 requirejs 来执行 typescript 生成的 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 文件。您不需要单独加载 class 脚本,require.js 会为您完成。
这让我很震惊,因为使用 gulp-wrap-umd
包时,它提供的包装器不会为包含的脚本创建隔离范围,它实际上是全局的,而打字稿生成的 UMD 包装脚本具有隔离范围。
在此实现中,我的引导脚本 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。