Typescript ReferenceError:未定义exports

时间:2017-03-27 09:39:13

标签: typescript module

尝试在official handbook之后实现模块,我收到以下错误消息:

  

未捕获的ReferenceError:未定义导出

     

at app.js:2

但我的代码中没有使用名称exports

我该如何解决这个问题?

文件

app.ts

let a = 2;
let b:number = 3;

import Person = require ('./mods/module-1');

模块1.T

 export class Person {
  constructor(){
    console.log('Person Class');
  }
}
export default Person;

tsconfig.json

{
   "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true,
        "outDir": "scripts/"
    },
    "exclude": [
        "node_modules"
    ]
}

25 个答案:

答案 0 :(得分:22)

此问题的其他解决方案很少

  • 在对Javascript的其他引用之前添加以下行。这是一个不错的小黑客。
var numberInputs = $('[type="number"]');
$.each(numberInputs, function(index, item){
    if ($(this).data('val-range')) {
        var min = $(this).data('val-range-min');
        var max = $(this).data('val-range-max');
        $(this).attr('min', min);
        $(this).attr('max', max);
    }
})
  • 使用最新版本的TypeScript会出现此问题,可以通过引用typescript版本2.1.6来消除此错误。

答案 1 :(得分:21)

编辑:

如果你不再定位es5,这个答案可能无效,我会尝试让答案更完整。

原始答案

如果未安装CommonJS(which defines exports),则必须从tsconfig.json中删除此行:

 "module": "commonjs",

根据评论,仅此一项可能不适用于tsc的更高版本。如果是这种情况,您可以安装像CommonJS,SystemJS或RequireJS这样的模块加载器,然后指定它。

注意:

查看main.js生成的tsc文件。你会在最顶层找到这个:

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

它是错误消息的根,在删除"module": "commonjs",后,它将消失。

答案 2 :(得分:17)

我通过从"type": "module"中删除package.json字段来解决了这个问题。

答案 3 :(得分:3)

对于仍有此问题的人,如果您的编译器目标设置为ES6,则需要告知babel跳过模块转换。为此,请将其添加到您的.babelrc文件

{
  "presets": [ ["env", {"modules": false} ]]
}

答案 4 :(得分:1)

对我来说,从tsconfig.json中删除"esModuleInterop": true就可以了。

答案 5 :(得分:1)

几周前我遇到了这个问题,并在短期内使用了 the exports hack above,但最终找到了另一种对我有用的方法。

因此与上面的其他一些回复不同,我实际上希望我正在编译的代码成为一个模块。通过设置 "target": "es6", "module": "esnext" 然后使用 type="module" 而不是 type="text/javascript" 链接到我编译的 JS 文件,我编译的代码不再有 Object.defineProperty(exports, "__esModule", { value: true }); 行,它仍然是一个模块?

我的 tsconfig:

{
  "compilerOptions": {
    "target": "es6",
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "esnext",
    "moduleResolution": "node",
    "lib": ["es2016", "esnext", "dom"],
    "outDir": "build",
    "strict": true,
    "strictNullChecks": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "declaration": true,
  },
  "include": ["src/index.ts"],
  "exclude": ["build"]
}

我在 HTML head 标签中编译代码的链接:

<script src="../build/index.js" type="module" defer></script>

作为奖励,现在我还可以在主 HTML type="module" 代码下方的单独 body 脚本中导入我在 index.js 文件中导出的任何内容:

 <script type="module">
   import { coolEncodingFunction, coolDecodingFunction } from "../build/index.js";
   /* Do stuff with coolEncodingFunction and coolDecodingFunction */
   /* ... */
</script>

答案 6 :(得分:1)

我遇到了与问题的原始海报类似的问题:

我最好告诉你我犯了什么错误以及我是如何纠正它的,这可能会对某人有所帮助。

我有一个 javascript nodejs 项目并将其转换为打字稿。

以前在 package.json 中,当我在 JavaScript 中运行时,我有 "type":"module"。

当我将其转换为 TypeScript 项目并开始转换 .ts 文件中的文件并使用以下命令开始运行时:

npx tsc test.ts && node test.ts

我会得到上述错误。

我通过简单地从 package.json 中删除 "type":"module" 来消除错误

我的 tsconfig.json 如下所示:

{
    "compilerOptions": {
        "target": "esnext",
        "lib": ["es6", "es5", "es7", "dom"],
        "allowJs": true,
        "esModuleInterop": true,
        "allowSyntheticDefaultImports": true,
        "strict": true,
        "forceConsistentCasingInFileNames": true,
        "module": "es6",
        "outDir": "./build",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "skipLibCheck": true
    },
    "exclude": ["node_modules", "build"]

我正在使用节点 14 和 TypeScript 4.2.4

答案 7 :(得分:1)

注意:这可能不适用于OP的答案,但是我遇到了这个错误,这也是我如何解决的。

所以我面临的问题是,当我从特定的CDN中检索“ js”库时遇到此错误。

我做的唯一错误的事情是从CDN的cjs目录中导入,如下所示: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js

注意到dist/cjs部分吗?那就是问题所在。

就我而言,我回到CDN(jsdelivr)并导航到umd文件夹。我可以找到另一套popper.min.js,这是要导入的正确文件: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/umd/popper.min.js

答案 8 :(得分:1)

通过将module编译器选项设置为es6可以解决此问题:

{
  "compilerOptions": {     
    "module": "es6",
    "target": "es5",    
  }
}

答案 9 :(得分:1)

像这样简单地添加libraryTarget: 'umd'

const webpackConfig = {
  output: {
    libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
  }
};

module.exports = webpackConfig; // Export all custom Webpack configs.

答案 10 :(得分:1)

npm install @babel/plugin-transform-modules-commonjs

并添加到.babelrc插件解决了我的问题。

答案 11 :(得分:1)

接受的答案并没有为我解决问题。相反,我设置使用RequireJS(AMD实现)。我在https://stackoverflow.com/a/48436147/1019307写了我的解决方案。

答案 12 :(得分:0)

尝试上面@iFreilicht建议的内容。如果在安装完webpack以及所有内容后仍不起作用,则可能是刚从在线某个地方复制了webpack配置,然后在该位置配置了您希望输出错误地支持CommonJS的配置。确保在webpack.config.js中不是这种情况:

module.exports = {
  mode: process.env.NODE_ENV || "development",
  entry: { 
    index: "./src/js/index.ts"
  },
  ...
  ...
  output: {
    libraryTarget: 'commonjs',         <==== DELETE THIS LINE
    path: path.join(__dirname, 'build'),
    filename: "[name].bundle.js"
  }
};

答案 13 :(得分:0)

对于某些ASP.NET项目,importexport可能根本不在您的打字稿中使用。

当我尝试这样做时出现问题的错误,后来我才发现只需要将生成的JS脚本添加到 View 中,就像这样:

<script src="~/scripts/js/[GENERATED_FILE].Index.js" asp-append-version="true"></script>

答案 14 :(得分:0)

我也有同样的错误。就我而言,这是因为我们在TypeScript AngularJS项目中有一个老式的import语句,如下所示:

import { IAttributes, IScope } from "angular";

被编译成如下所示的JavaScript:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });

这在过去很需要,因为我们然后在代码中使用了IAttributes,否则TypeScript将不知道如何处理它。 但是在删除导入语句并将IAttributes转换为ng.IAttributes之后,这两行JavaScript行消失了,错误消息也消失了。

答案 15 :(得分:0)

我的解决方案是上述所有内容的总结,并添加了一些小技巧,基本上我将此添加到了html代码中

<script>var exports = {"__esModule": true};</script>
<script src="js/file.js"></script>

这甚至允许您在使用电子或其他东西时使用import而不是require,它与打字稿3.5.1(目标:es3-> esnext)配合使用。

答案 16 :(得分:0)

有同样的问题,并通过更改JS包的加载顺序来解决。

检查所需软件包的调用顺序,并以适当的顺序加载它们。

在我的特定情况下(不使用模块捆绑器),我需要先加载Redux,然后加载Redux Thunk,然后加载React Redux。在React Redux之前加载Redux Thunk会给我exports is not defined

答案 17 :(得分:0)

我遇到了同样的问题,但是我的设置需要不同的解决方案。

我正在将create-react-app-rewired软件包与config-overrides.js文件一起使用。以前,我使用的是addBabelPresets中的override()导入(在customize-cra方法中),并决定将这些预设抽象到一个单独的文件中。巧合的是,这解决了我的问题。

我在useBabelRc()的{​​{1}}方法中添加了override(),并创建了一个config-overrides.js文件,其内容如下:

babel.config.js

答案 18 :(得分:0)

要解决此问题,请将这两行放在您的 index.html 页面中。

<script>var exports = {"__esModule": true};</script>
<script type="text/javascript" src="/main.js">

确保检查您的 main.js 文件路径。

答案 19 :(得分:0)

我在 SSR 客户端部分遇到了这样的错误,因为它使用了一个使用 tsconfig.json compilerOptions 构建的库作为 target: ES5 使用 CommonJS对于模块分辨率 tsc CLI Options Compiler Optionstarget === "ES3" or "ES5" ? "CommonJS" : "ES6"。虽然它使用了目标 ESNext

答案 20 :(得分:0)

由于 ES5/ES2009 不支持 客户端 / 浏览器 上的模块(导入/导出/要求),您必须使用库,将模块捆绑到一个文件中,可以通过 <script> 标签包含,例如

另见this answer

答案 21 :(得分:0)

编译器选项中的“module”选项和“target”选项之间存在关系(如文档here所示):

  

- 模块   -m

     

string

     

目标===“ES3”或“ES5”? “CommonJS”:“ES6”

     

指定模块代码生成:“无”,“CommonJS”,“AMD”,“系统”,“UMD”,   “ES6”,“ES2015”或“ESNext”。 ►只能使用“AMD”和“System”   与--outFile结合使用。 ►可以使用“ES6”和“ES2015”值   当定位“ES5”或更低时。

作为模块的默认值,以目标为条件,您必须考虑这两个选项以及用于加载模块的方式,以获得适合您代码的正确选项。

如果您定位ES5,则必须考虑另一个选项而不是默认值,并相应地更改加载模块的方式。

答案 22 :(得分:0)

我遇到了同样的问题并解决了添加&#34; es5 &#34;库到tsconfig.json像这样:

{
    "compilerOptions": {
        "target": "es5", //defines what sort of code ts generates, es5 because it's what most browsers currently UNDERSTANDS.
        "module": "commonjs",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true, //for angular to be able to use metadata we specify in our components.
        "experimentalDecorators": true, //angular needs decorators like @Component, @Injectable, etc.
        "removeComments": false,
        "noImplicitAny": false,
        "lib": [
            "es2016",
            "dom",
            "es5"
        ]
    }
}

答案 23 :(得分:-1)

  {
    "compileOnSave": false,
    "compilerOptions": {
      "baseUrl": "./",
      "outDir": "./dist",
      "sourceMap": true,
      "declaration": false,
      "module": "esnext",
      "moduleResolution": "node",
      "emitDecoratorMetadata": true,
      "experimentalDecorators": true,
      "target": "es5",
      "typeRoots": ["node_modules/@types"],
      "lib": ["es2018", "dom"]
    }
  }

答案 24 :(得分:-1)

如果您仅使用类型的接口,请省略export关键字,并且ts可以选择类型而无需导入。他们的关键是您无法在任何地方使用import / export

export interface Person {
   name: string;
   age: number;
}

进入

interface Person {
   name: string;
   age: number;
}