【问题标题】:Typescript ReferenceError: exports is not definedTypescript ReferenceError:未定义导出
【发布时间】:2017-08-19 22:52:22
【问题描述】:

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

未捕获的引用错误:未定义导出

在 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"
    ]
}

【问题讨论】:

  • 您确定您输入的exports 末尾没有带有s 而不是export?这将解释错误消息,因为 s 是错误的。
  • 我输入 export 而不是 exports
  • 任何来自存储库的示例,它可以工作 10000%
  • 这是在哪里运行的?在网页上?在 node.js 服务器上?在最终运行 javascript 的运行时环境中,您将需要一个模块加载器。从编译器标志中,您正在使用 commonjs。我对 commonjs 不是很熟悉,但是您需要先设置 commonjs,然后 Typescript 模块才能工作,或者您需要更改为另一个模块加载器(如 require.js)并进行设置。

标签: typescript module


【解决方案1】:

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

  • 在其他对 Javascript 的引用之前添加以下行。这是一个不错的小技巧。
   <script>var exports = {};</script>

【讨论】:

  • @ChuckLeButt 希望这有助于stackoverflow.com/questions/19059580/…
  • 我讨厌这行得通!它绝对有效。有没有办法让 TypeScript 转换成 Node 期望的东西?甚至是 Node 都在抱怨吗?还是浏览器?我无法忍受不了解问题的实质。
  • 这就像一个魅力。打从心底:谢谢
  • 这感觉像是来自炼金术士的东西,谢谢
【解决方案2】:

编辑:

此答案可能不起作用,具体取决于您是否不再针对 es5,我会尽量使答案更完整。

原答案

如果没有安装 CommonJS (which defines exports),你必须从你的 tsconfig.json 中删除这一行:

 "module": "commonjs",

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

注意:

查看tsc 生成的main.js 文件。您会在最顶部找到它:

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

是错误信息的根源,去掉"module": "commonjs",后就消失了。

【讨论】:

  • 是的,我重新编译了我的 .ts 文件,注释掉 "module": "commonJs", 后错误仍然存​​在 :(
  • 如果安装 CommonJS 会让这个错误消失,那么如何实际安装 CommonJS?我花了一个小时的大部分时间在谷歌上搜索,但我找不到关于如何这样做的任何说明。有人可以解释一下吗?
  • @Sturm 我的回答可能措辞令人困惑。 CommonJS 只是一个规范。您可以在此处找到(不一定是详尽的)实现列表:en.wikipedia.org/wiki/CommonJS
  • 我有模块:amd,而不是模块:commonjs,我在转译的 .js 文件中有这一行。
  • 如果您的 tsconfig.json 中的目标是 ES3 或 ES5,那么 typescript 会自动将您的模块设置为 CommonJS(如果它没有定义)。删除模块是不够的,您需要设置其他内容 - 请参阅 typescriptlang.org/docs/handbook/compiler-options.html
【解决方案3】:

解决方案:

package.json 中删除"type": "module"

【讨论】:

  • 但这有什么帮助呢?
  • @DauleDK 因为我们使用 Webpack 来打包 app,这个字段在 node.js 引擎中有使用。在 webpack 配置中我们使用通用模块系统
【解决方案4】:

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

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

【讨论】:

    【解决方案5】:

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

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

    【讨论】:

    • 这是给我的。使用 Laravel Mix 和 Typescript。
    • 如果你使用nodejs你需要将"moduleResolution": "Node"添加到tsconfig.json
    【解决方案6】:

    我的解决方案是上面所有内容的总结以及我添加的小技巧,基本上我将其添加到我的 html 代码中

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

    这甚至允许你使用 import 而不是 require 如果你正在使用电子或其他东西,它适用于 typescript 3.5.1,目标:es3 -> esnext。

    【讨论】:

    • 这里有一些进展,错误刚刚改成app.js:3 Uncaught ReferenceError: require is not defined
    • 如果在创建窗口时将 nodeIntegration 设置为 false,则会发生这种情况,因为您更新了 electronJS 或者您正在关注一个过时的源。 nodeIntegration 默认为 true,现在为 false,因此如果要在渲染器进程中访问 nodeJS,则必须手动启用它。见[Electron require() 未定义][1] [1]:stackoverflow.com/questions/44391448/…
    • 我没有使用电子,无论如何我通过添加包裹来制作捆绑物品并删除了其他棘手的方法来解决我的问题
    【解决方案7】:

    我遇到了同样的问题并解决了它,将“es5”库添加到 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"
            ]
        }
    }
    

    【讨论】:

      【解决方案8】:

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

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

      【讨论】:

      • 谢谢你!我一直在尝试使用旧代码库,这些代码库全部转储到全局中,并且脚本包含在带有&lt;script&gt; 标签的浏览器中。我希望将模块与旧代码一起使用,但这似乎是不可能的。这至少让我可以使用 ES6 并让我稍后处理导出。
      • 这样做我得到了以下错误:使用删除的 Babel 5 选项:.modules - 在plugins 选项中使用相应的模块转换插件。查看babeljs.io/docs/plugins/#modules
      【解决方案9】:

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

      import { IAttributes, IScope } from "angular";
      

      像这样编译成 JavaScript:

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

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

      【讨论】:

      • 这对于 Typescript 类型如何工作?我必须导入它,所以 Typescript 编译它。
      • “Typescript 类型”是什么意思?如果它是 TypeScript 已知的整数类型 - 例如数字或字符串 - 那么您可以立即使用它。如果您在模块中定义自己的类型,请检查:typescriptlang.org/docs/handbook/modules.html
      • 我的意思是外部库的类型定义,例如来自 npmjs.com/package/@types/jquery 的 @types/jquery。为了使 $ 变量在我的 Typescript 代码中可用,我把它放在我的代码中: import * as $ from "jquery";
      • 我的目标是 es5,我是否需要另一个库,比如 requirejs 才能完成这项工作?
      【解决方案10】:

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

      【讨论】:

      • 只有在 esModuleInterop 设置为 true 的情况下才能使用 exports,所以删除它如何工作?
      • 这对我有用(删除了上述错误)。我正在将 ESM 与打字稿(带玩笑)一起使用,所以我不想要导出。
      【解决方案11】:

      只需添加libraryTarget: 'umd',就像这样

      const webpackConfig = {
        output: {
          libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
        }
      };
      
      module.exports = webpackConfig; // Export all custom Webpack configs.
      

      【讨论】:

        【解决方案12】:

        我遇到了与问题的原始发布者类似的问题:

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

        我有 javascript nodejs 项目并将其转换为 typescript。

        以前在 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

        【讨论】:

        • 感谢 Krunal,这也帮助了我!
        【解决方案13】:

        几周前我遇到了这个问题,并在短期内使用了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>
        

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

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

        【讨论】:

        • &lt;script Type="Module""module": "ES2020" 为我工作。
        • 错误:tsconfig.json(8,15):错误 TS6046:'--module' 选项的参数必须是:'none'、'commonjs'、'amd'、'system'、' umd','es6','es2015','esnext'。
        【解决方案14】:

        在 package.json 中添加 "type": "module" 在终端输入

        npx tsc --init
        

        它将创建一个 tsconfig.json 改变 "target": "es5""target": "es6"

        注释掉 //"module": "commonjs", 取消注释 "moduleResolution": "node",

        你应该很高兴 在 package.json 创建一个构建脚本

        "build": "tsc -p tsconfig.json"

        那么当你想要构建时,你只需编译 npm run build

        然后执行应该就好了

        【讨论】:

          【解决方案15】:

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

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

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

          【讨论】:

            【解决方案16】:

            注意:这可能不适用于 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.

            【讨论】:

              【解决方案17】:

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

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

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

              【讨论】:

              • 这仅在您的代码中没有任何 require() 语句时才有效。
              【解决方案18】:

              试试上面@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"
                }
              };
              

              【讨论】:

                【解决方案19】:

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

                检查您需要的包的调用顺序,并以适当的顺序加载它们。

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

                【讨论】:

                  【解决方案20】:

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

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

                  我在config-overrides.jsoverride() 方法中添加了useBabelRc(),并创建了一个babel.config.js 文件,其中包含以下内容:

                  module.exports = {
                      presets: [
                          '@babel/preset-react',
                          '@babel/preset-env'
                      ],
                  }
                  

                  【讨论】:

                    【解决方案21】:

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

                    【讨论】:

                      【解决方案22】:

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

                      另见this answer

                      【讨论】:

                        【解决方案23】:
                          {
                            "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"]
                            }
                          }
                        

                        【讨论】:

                        • 欢迎来到 StackOverflow。请在您的答案或解释中添加一些上下文,以便用户了解所做的事情。仅发布 JSON 可能没有帮助...
                        【解决方案24】:

                        如果你只是为类型使用接口,请忽略 export 关键字,ts 可以在不需要导入的情况下选择类型。他们的关键是你不能在任何地方使用import/export

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

                        进入

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

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2019-02-28
                          • 1970-01-01
                          • 2017-07-27
                          • 2017-09-14
                          • 1970-01-01
                          • 2019-07-07
                          • 2020-01-09
                          • 1970-01-01
                          相关资源
                          最近更新 更多