visual studio typescript“未捕获的ReferenceError:导出未定义在....”

时间:2017-03-07 13:10:38

标签: javascript html visual-studio typescript import

我正在使用visual studio学习typeScript并尝试进行简单的类导出。我已多次看到这个问题,但没有一个解决方案对我有帮助。我做错了什么?

  • 我已将模块系统从CommonJs更改为system
  • 我安装了npm systemJs
  • 尝试代替“import”来编写“/// ... reference path .... /”

仍然是相同的错误“未捕获的ReferenceError:导出未定义在......”

import { Address } from "./address";

class Customer {
  protected name: string = "";
  public addressObj: Address = new Address();
  private _CustomerName: string = "";
  public set CustomerName(value: string) {
    if (value.length == 0) {
      throw "Customer name is requaierd"
    }
    this._CustomerName = value;
  }
  public get CustomerName(): string {
    return this._CustomerName;
  }
}
export class Address {
        public street1: string = "";
    }
<!doctype html>
<html>

<head>
  <title></title>
  <meta charset="utf-8" />
</head>

<body>
  <script src="address.js"></script>
  <script src="Customer.js"></script>
  <script>
    try {
      cust = new Customer();
      cust.CustomerName = "doron";
      cust.addressObj.street1 = "test"
    } catch (ex) {
      alert(ex);
    }
  </script>
</body>

</html>

我还在做什么?!?!

2 个答案:

答案 0 :(得分:7)

我刚刚解决了这个问题。或者更确切地说,我找到了https://blorkfish.wordpress.com/2012/10/23/typescript-organizing-your-code-with-amd-modules-and-require-js/的博文。为了遵循正确的SO指南,我将在此处重现。

为什么你的出口未定义&#39;是由于Visual Studio转换为使用commonjs模块。我看了几天尝试不同的事情,而且消息似乎是普通人是默认的,应该只是工作&#34; (TM值)。但不是。我不知道缺少什么 - 也许VS需要一些包括。我无法解决问题。

使用commonjs的转换后的类将在.js文件的顶部和底部包含这样的行:

Object.defineProperty(exports, "__esModule", { value: true });
...
exports.SpeciesClass = SpeciesClass;

这是你的错误。

对我有用的解决方案是使用requirejs。它是AMD的实现(http://requirejs.org/docs/whyamd.html)。它仍然使用exports,但将其包含在define

define(["require", "exports"], function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    ...
    exports.SpeciesClass = SpeciesClass;

以下是博客文章https://blorkfish.wordpress.com/2012/10/23/typescript-organizing-your-code-with-amd-modules-and-require-js/。对最新版本的Typescript进行了一些修改。不幸的是,在我工作的地方,我无法访问github(或类似的东西)所以我只能在这里粘贴我的文件。

我还必须考虑Visual Studio的一些问题。我发现尽管将project.csproj <TypescriptModuleKind>配置为AMD,但似乎始终默认为commonjs。所以我手动编写并希望找到一个解决方案来阻止VS默认。

我创建了一个tsconfig.json文件(tsc --init)并将module设置为amd。我添加了"Files": ["*.ts"]

{
  "compilerOptions": {
    /* Basic Options */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
    "module": "amd",                     /* Specify module code generation: 'none', commonjs

    /* ... */

    /* Strict Type-Checking Options */
    "strict": true                            /* Enable all strict type-checking options. */
  },
  "Files" : ["*.ts"]
}

已删除注释掉的行(默认值)。

启动服务器后,Visual Studio将转换文件(使用commonjs模块格式)。要求我运行tsc强制文件转换为使用amd模块格式。它起作用(在开发者控制台中没有看到任何错误)。

首先是文件布局(来自blogpost)。我所拥有的是相同的,除了我已经将我的文件index.html称为default.htm,因为require.js让我想起了糟糕的日子。您可以从http://requirejs.org/获取require.d.ts。来自https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/requirejsindex.d.ts(将require.d.ts保存为export class Greeter { element: HTMLElement; span: HTMLElement; timerToken: number; constructor(element: HTMLElement) { this.element = element; this.element.innerText += "The time is: "; this.span = document.createElement('span'); this.element.appendChild(this.span); this.span.innerText = new Date().toUTCString(); } start() { this.timerToken = setInterval(() => this.span.innerText = new Date().toUTCString(), 500); } stop() { clearTimeout(this.timerToken); } } )。

files layout

Greeter.ts

import { AppMain } from "./AppMain"

require(['AppMain'], 
    (main: any) => {
        var appMain = new AppMain();
        appMain.run();
    }
);

AppConfig.ts

import { Greeter } from "./classes/Greeter"

export class AppMain {
    public run() {
        // code from window.onload
        var dummyEl: HTMLElement = document.createElement('span');
        var theEl: HTMLElement | null = document.getElementById('content');;
        var el: HTMLElement = theEl !== null ? theEl : dummyEl;
        var greeter: Greeter = new Greeter(el);
        greeter.start();
    }
};

AppMain.ts

        var theEl: HTMLElement = document.getElementById('content');
        var greeter: Greeter = new Greeter(theEl);

或使用:

app/AppMain.ts(7,13): error TS2322: Type 'HTMLElement | null' is not assignable to type 'HTMLElement'.
    Type 'null' is not assignable to type 'HTMLElement'.

只是意识到所谓的错误&#39;当你转变只是一个警告!:

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title>TypeScript HTML App</title>
        <link rel="stylesheet" href="app.css" type="text/css" />
        <!--
            <script type="text/javascript" src="app/classes/Greeter.js"></script>
            <script src="app.js"></script>
        -->
        <script data-main="app/AppConfig" type="text/javascript" src="lib/require.js"></script>
    </head>
    <body>
        <h1>TypeScript HTML App</h1>

        <div id="content"></div>
    </body>
</html>

app.ts

不再使用

的index.html

T

答案 1 :(得分:0)

不需要CommonJs。将所有打字稿都包装在一个通用名称空间中,然后导出其他名称空间,类等。确实提供了智能感知功能:

namespace GlobalNamespace {
     export class MyClass1 {
         prop1:string;
     }
}

namespace GlobalNamespace {
     export class MyClass2 {
          prop2:string;
     }
}

Divide into namespace units:
namespace GlobalNamespace {
     export namespace SubNamespace1 {
        export class SubClass1 {
             myClass1: MyClass1;
        }
     }
}

namespace GlobalNamespace {
     export namespace SubNamespace2 {
        export class SubClass2 {
             subClass1:SubNamespace1.SubClass1;
        }
     }
}

实例化SubClass2

var subClass2 = new GlobalNamespace.SubNamespace2.SubClass2();