导出未定义

时间:2017-09-07 10:01:48

标签: angular typescript systemjs

我试图根据我的第一个应用制作一个Angular应用,这给了我一些麻烦。

以下是我所拥有的:

的index.html

<!DOCTYPE html>
<html>
<head>
    <base href="/"/>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>FiveRX 2.0 Management</title>
    <meta charset="utf-8"/>

    <!-- Dependencies -->
    <script src="/node_modules/core-js/client/shim.min.js"></script>
    <script src="/node_modules/systemjs/dist/system.js"></script>
    <script src="/node_modules/zone.js/dist/zone.js"></script>

    <!-- Init Application -->
    <script src="/app/config/system.config.js"></script>
    <script src="/app/config/system.init.js"></script>

</head>
<body>
<div class="header">
    <div class="title">Troubleshooting</div>
</div>
<layout></layout>
</body>
</html>

system.config.js

(function (global) {
    System.config({
        paths: {
            "npm:": "node_modules/"
        },

        map: {
            "app": "app",
            "@angular/core": "npm:@angular/core/bundles/core.umd.js",
            "@angular/common": "npm:@angular/common/bundles/common.umd.js",
            "@angular/compiler": "npm:@angular/compiler/bundles/compiler.umd.js",
            "@angular/platform-browser": "npm:@angular/platform-browser/bundles/platform-browser.umd.js",
            "@angular/platform-browser-dynamic": "npm:@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js",
            "@angular/http": "npm:@angular/http/bundles/http.umd.js",
            "@angular/router": "npm:@angular/router/bundles/router.umd.js",
            "@angular/forms": "npm:@angular/forms/bundles/forms.umd.js",
            "@angular/animations": "npm:@angular/animations/bundles/animations.umd.js",
            "@angular/animations/browser": "npm:@angular/animations/bundles/animations-browser.umd.js",
            "@angular/platform-browser/animations": "npm:@angular/platform-browser/bundles/platform-browser-animations.umd.js",
            "rxjs": "npm:rxjs",
        },
        packages: {

            app: {
                main: "bootstrap.js"
            },
            rxjs: {
                defaultExtension: "js"
            },
            scripts: {
                format: "register",
                defaultExtension: "js",
                scriptLoad: true
            }
        },
        meta: {
            "*": {
                authorization: true
            }
        }
    });
})(this);

system.init.js

System.import('app')
    .catch(function(err) {
         console.error(err);
    });

bootstrap.ts

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false,
        "lib": [ "es5", "es6", "es2015", "dom" ]
    }
}

如您所见,bootstrap文件除了导入platform-b​​rowser-dynamic之外不包含任何内容。我尝试运行时遇到以下错误:

Error: exports is not defined
  Evaluating http://localhost:55549/app/bootstrap.js
  Loading app
    at eval (:55549/app/bootstrap.js:2)
    at eval (<anonymous>)
    at _e (evaluate.js:106)
    at instantiate.js:414
    at R (register-loader.js:684)
    at E (register-loader.js:631)
    at O (register-loader.js:540)
    at register-loader.js:128
    at ZoneDelegate.invoke (zone.js:365)
    at Zone.run (zone.js:125)
    at zone.js:760
    at ZoneDelegate.invokeTask (zone.js:398)
    at Zone.runTask (zone.js:165)
    at drainMicroTaskQueue (zone.js:593)
    at <anonymous>

现在,我可以通过定位ES6而不是ES5来实现这一目标,但这既不是解释也不是选项。 有什么想法在这里?

1 个答案:

答案 0 :(得分:2)

你遇到了一个相当特殊的情况。

使用您的配置,tsc会将模块编译为CommonJS格式,如果您的目标不是 es6,则这是默认模式。因此,您的bootstrap.ts代码会编译为此JavaScript:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
//# sourceMappingURL=bootstrap.js.map

SystemJS通常能够识别模块是CommonJS模块,并将自动提供适合此情况的执行环境。 不幸的是,上面生成的代码不足以让SystemJS识别出你的模块是CommonJS格式,因此它默认为其本机模块格式,并因Object.defineProperty而失败,因为{{1} }}不存在。

在上面的代码中,您会注意到没有exports调用与您的require语句相对应。那是因为import检测到在运行时不需要tsc调用,因此不会发出它。如果您只是将TypeScript代码更改为此,那么require将发出tsc调用(否则require调用将失败)并且SystemJS可以检测模块格式:

platformBrowserDynamic()

如果SystemJS仍无法检测格式,请记住您可以使用SystemJS配置中的format option告诉SystemJS使用特定格式。

当您将目标更改为import { platformBrowserDynamic } from "@angular/platform-browser-dynamic"; platformBrowserDynamic(); 时,默认模块格式也会更改为es6,这就解释了为什么您不再出现该错误。