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

Posted

技术标签:

【中文标题】visual studio typescript“未捕获的ReferenceError:未在...定义导出” [重复]【英文标题】:visual studio typescript "Uncaught ReferenceError: exports is not defined at...." [duplicate] 【发布时间】:2017-07-27 17:10:30 【问题描述】:

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

我已将模块系统从 CommonJs 更改为 system 我已经安装了 npm systemJs 尝试用“import”代替“/// ...引用路径..../”

还是同样的错误“Uncaught ReferenceError: exports is not defined at...”

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>

我还没有做什么?!?!

【问题讨论】:

你是如何将你的类型脚本构建成一个 js 文件的? 首先我下载并安装visual typeScript插件,然后我的项目是一个Web应用程序的空模板,我添加了ts文件。当我保存该文件时,它会自动构建 js 文件以及 js.map 文件。 &lt;script src="address.js"&gt;&lt;/script&gt;&lt;script src="Customer.js"&gt;&lt;/script&gt;:你的错误就在这里。也许你应该关注a tutorial for SystemJS? 我会试试的。谢谢 【参考方案1】:

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

为什么你得到'exports is undefined'是由于Visual Studio转译为使用commonjs模块。我看了几天尝试不同的东西,消息似乎是 commonjs 是默认设置,应该“正常工作”(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&lt;TypescriptModuleKind&gt; 配置为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 模块格式。它工作正常(在开发者控制台中没有看到错误)。

首先是文件布局(来自博文)。我所拥有的是相同的,只是我将我的文件称为index.html,因为default.htm 让我想起了糟糕的过去。您可以从http://requirejs.org/ 获取require.js。和require.d.ts 来自https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/requirejs(将index.d.ts 保存为require.d.ts)。

Greeter.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);
    


AppConfig.ts

import  AppMain  from "./AppMain"

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

AppMain.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();
    
;

或使用:

        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'.

app.ts

不再使用

index.html

<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>

【讨论】:

我知道已经有一段时间了,但我只是没看到。|感谢您的深入解释和帮助。 @HankCa 不用担心@user24136! 能否提供此工作源代码的下载链接?【参考方案2】:

不需要 CommonJs。将所有打字稿包装在一个公共命名空间中,然后导出其他命名空间、类等。是否提供智能感知:

MyClass1.ts

namespace GlobalNamespace 
     export class MyClass1 
         prop1:string;
     

MyClass2.ts

namespace GlobalNamespace 
     export class MyClass2 
          prop2:string;
     

划分命名空间单元:

SubClasses.ts

namespace GlobalNamespace 
     export namespace SubNamespace1 
        export class SubClass1 
             myClass1: MyClass1;
        
     


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

实例化子类2

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

【讨论】:

太棒了!谢谢!!!只需要澄清一下 - 每个namespace XXexport namespaceYY... 可能位于一个单独的 TS 文件中

以上是关于visual studio typescript“未捕获的ReferenceError:未在...定义导出” [重复]的主要内容,如果未能解决你的问题,请参考以下文章

Visual Studio - 引擎盖下(NPM/Typescript)

Typescript visual Studio项目属性

在 Visual Studio Code 中销毁 TypeScript

从 Visual Studio 捆绑 AngularJs TypeScript 应用程序

打造TypeScript的Visual Studio Code开发环境

Visual Studio Code 中的 TypeScript 运行构建任务失败