Ala*_*nut 12 module typescript systemjs typescript2.0 es6-modules
我最近一直在用TypeScript研究和做简单的"hello worlds".有些事我认为我无法解决这个问题,那就是如何将System.js与TypeScript一起使用.互联网上的每一个教程或演示都是关于Angular2的,我还不想参与Angular 2.
举个例子,我有以下项目结构:
RootFolder
|
| _lib
| ...... ts (where .ts files are)
|
| components (where compiled .js files are)
| libraries
| ......... systemjs (where system.js is)
|
| index.html
| tsconfig.json
Run Code Online (Sandbox Code Playgroud)
我的tsconfig.json文件看起来像:
{
"compileOnSave": true,
"compilerOptions": {
"noImplicitAny": true,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "es5",
"module": "system",
"moduleResolution": "node",
"outDir": "./components"
},
"exclude": [
"node_modules",
"wwwroot"
],
"include": [
"./_lib/ts/**/*"
]
}
Run Code Online (Sandbox Code Playgroud)
TypeScript编译按预期工作,没有问题.我创建了一个名为"Alerter"的简单类,其中包含以下代码:
//alerter.ts
class Alerter {
showMessage(): void {
alert("Message displayed.");
}
}
export default Alerter
Run Code Online (Sandbox Code Playgroud)
和app.ts(这是我的"主要"应用程序文件),代码如下:
//app.ts
import Alerter from "./alerter";
console.log("app.js included & executed");
function test() {
console.log("test called");
const alt = new Alerter();
alt.showMessage();
};
Run Code Online (Sandbox Code Playgroud)
在我的index.html中,我只想用System.js导入这个app.js,只想从控制台调用"test"函数.但它不起作用.无论我做了什么,我根本无法访问该功能.我看到第一个console.log行正在执行,但是当我尝试从chrome控制台调用test()时,它是未定义的.
如果我从main.ts中删除"alerter"类依赖项,一切正常.因为编译后的app.js只包含console.log调用和函数定义.
这是我在index.html中的System.js调用
System.config({
packages: {
"components": {
defaultExtension: "js"
}
}
});
System.import("components/app");
Run Code Online (Sandbox Code Playgroud)
我现在非常绝望,并认为我应该回到Jquery的日子.这很简单但不能使它工作.
我看到这里发生了什么.这与正确使用TypeScript export关键字和SystemJS有关.
从您的描述中,您基本上希望使用SystemJS导入JavaScript文件,类似于仅使用<script>标记,然后使用其全局定义的函数.
但这意味着您需要了解TypeScript如何编译文件.https://www.typescriptlang.org/docs/handbook/modules.html上的文档说:
在TypeScript中,就像在ECMAScript 2015中一样,任何包含顶级导入或导出的文件都被视为模块.
这就是你正在做的事情.该app.ts文件有一个import,alerter.ts文件有一个export语句,所以这两个语句都将被编译为模块.然后从你的tsconfig.json我看到你正在使用system格式(但是,这里没关系).
模块的一个主要好处是它们不会泄漏任何超出其范围的全局对象.所以,当你打电话System.import("components/app")的test()存在,只在该模块的功能.但您可以导出该函数并在加载模块后调用它:
这意味着您需要先导出该函数:
// app.ts
export function test() {
...
};
Run Code Online (Sandbox Code Playgroud)
然后System.import()返回一个使用模块导出对象解析的Promise,以便我们可以在test()那里调用该方法.
System.import("components/app").then(function(m) {
m.test();
});
Run Code Online (Sandbox Code Playgroud)
这真的像你期望的那样工作.
但是,看起来您想要定义test()globaly函数.在这种情况下,您需要window自己在全局对象上定义函数:
// app.ts
function test() {
...
}
declare const window;
window.test = test;
Run Code Online (Sandbox Code Playgroud)
现在,您可以在导入包后随时使用它:
System.import("components/app").then(function(m) {
test();
});
Run Code Online (Sandbox Code Playgroud)
SystemJS有多种方法可以使用全局对象进行操作,但是当导入的包具有需要解析的依赖项时,我认为没有更简单的方法可以使用它们(否则看看这个但是它不是你的用例https ://github.com/systemjs/systemjs/blob/master/docs/module-formats.md#exports).
| 归档时间: |
|
| 查看次数: |
4342 次 |
| 最近记录: |