Typescript ReferenceError: exports is not defined

尝试在官方手册之后实现一个模块,我得到以下错误消息:

Uncaught ReferenceError:exports is not defined

在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"
]
}
401103 次浏览

编辑:

这个答案可能不起作用,这取决于你是否不再针对es5,我将尝试让答案更完整。

原来的答案

如果CommonJS没有安装(它定义了exports),你必须从你的tsconfig.json中删除这行:

 "module": "commonjs",

根据注释,仅这一点可能不适用于tsc的后续版本。如果是这样的话,你可以安装一个模块加载器,比如CommonJS, SystemJS或RequireJS,然后指定它。

注意:

查看由tsc生成的main.js文件。你会发现在最上面:

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

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

我有同样的问题,并解决了它添加“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"
]
}
}

在其他JavaScript引用之前添加以下行。这是一个不错的小hack。

<script>var exports = {};</script>

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

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

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

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

我的解决方案是上面所有东西的总和,我添加了一些小技巧,基本上我把这个添加到我的html代码中

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

这甚至允许你使用import而不是require,如果你使用electron或其他东西,它在typescript 3.5.1, target: es3 -> esnext中工作得很好。

我也犯了同样的错误。在我的例子中,这是因为我们在我们的TypeScript AngularJS项目中有一个老式的import语句,像这样:

import { IAttributes, IScope } from "angular";

它被编译成这样的JavaScript:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
这在以前是需要的,因为我们在代码中使用了IAttributes,否则TypeScript不知道该用它做什么。 但是在删除import语句并将IAttributes转换为ng.IAttributes之后,这两行JavaScript代码消失了——错误消息也消失了

对于一些ASP。NET项目importexport可能根本不会在Typescripts中使用。

当我试图这样做时,问题的错误出现了,我后来才发现,我只需要将生成的JS脚本添加到视图,如下所示:

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

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

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

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


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

对我来说,从tsconfig中删除"esModuleInterop": true。Json成功了。

这可以通过将module编译器选项设置为es6来解决:

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

有同样的问题,并通过改变JS包的加载顺序来修复它。

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

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

一个解决方案:

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

注意:这可能不适用于OP的答案,但我得到了这个错误,这就是我解决它的方式。

所以我面临的问题是,当我从一个特定的CDN检索一个'js'库时,我得到了这个错误。

我所做的唯一错误的事情是从CDN的cjs目录导入,就像这样: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/cjs/popper.min.js < / p >

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

我回到我的案例中的CDN (jsdelivr),并导航到umd文件夹。我可以找到另一组popper.min.js,这是要导入的正确文件: https://cdn.jsdelivr.net/npm/@popperjs/core@2.4.0/dist/umd/popper.min.js . < / p >
  {
"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"]
}
}

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

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

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

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

为了解决这个问题,把这两行放在你的index . html页面中。

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

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

如果只是为类型使用接口,则省略export关键字,ts可以在不需要导入的情况下拾取类型。关键是你不能在任何地方使用import/export

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

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

我在SSR客户端部分中遇到了这样的错误,因为它使用了一个用tsconfig.json compilerOptions作为target: ES5构建的库,从而使用CommonJS进行模块解析tsc CLI Options编译器选项: target === "ES3" or "ES5" ? "CommonJS" : "ES6"。而它使用的目标ESNext

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

另见这个答案

我有类似的问题,原来的海报的问题:

我最好告诉你我犯了什么错误以及我是如何改正的,这可能会帮助到别人。

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

之前的包装。我输入了"type":"module"当我用JavaScript运行时。

当我把它转换成TypeScript项目,并开始转换.ts文件中的文件,并使用以下命令开始运行:

npx tsc test.ts && node test.ts

我会得到上面的错误。

我通过简单地删除“类型”和“模块”来摆脱这个错误。从package.json

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

我在几周前遇到了这个问题,并在短期内使用了上面的出口hack,但最终找到了另一种适合我的方法。

因此,与上面的其他一些响应不同,我实际上希望我正在编译的代码是一个模块。通过设置"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 body代码下面的单独type="module"脚本中导入index.js文件中导出的任何内容:

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

package.json中添加"type": "module"

在终端中

npx tsc --init

它将创建一个tsconfig.json。

tsconfig.json,

  1. "target": "es5"改为"target": "es6"
  2. 注释出//"module": "commonjs",
  3. 取消"moduleResolution": "node",

你应该可以出发了。

package.json中,创建一个构建脚本:

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

然后,当你想要构建时,你只需要编译npm run build

然后执行,应该没问题

我认为问题可能是配置不匹配。

  1. 下面的工作解决方案1为您提供了ES模块的正确配置。
  2. 下面的工作解决方案2为您提供了正确的CommonJS配置。
  3. 混合解决方案1+2给你一个错误。
为了清晰起见,我只是在这里发布了部分内容。 Github项目https://github.com/jmmvkr/ts-express/ 用一套完整的文件演示解决方案1和解决方案2。

工作方案1,ES模块

/* Configuration for ES Module */


// tsconfig.json
{
"compilerOptions": {
"module": "es6", // or "esnext"
}
}
// package.json
{
"type": "module", // type is module
}

工作解决方案2,CommonJS

/* Configuration for CommonJS */


// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
}
}
// package.json
{
"type": "", // type is NOT module
}

混合,不工作

/* Mixed, got ReferenceError: exports is not defined in ES module scope */


// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
}
}
// package.json
{
"type": "module", // type is module
}

首先,在你的公共文件夹中找到你的index.html,找到脚本<script src="myScript.js"></script>的引用,并添加type="module"

像这样:

<script type="module" src="myScript.js"></script>

其次,在你的tsconfig.json中,确保目标被设置为es5模块被设置为es2015

 "compilerOptions": {
"target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
/* Modules */
"module": "es2015", /* Specify what module code is generated. */
}

重要的:确保使用.js扩展名导入,例如import Piece from './classes/piece.js'

没有直接回答这个问题,但是没有stackoverflow线程提到这种情况,我花了一段时间来调试,所以在这里添加它,以防将来它可以帮助别人。

我犯了“出口未定义”的错误。来自一个导入的NPM模块。改变我的typescript配置没有任何作用,因为我无法控制导入的第三方代码。问题是该包的导入语法无效。例如,我导入了“@mui/material/TextField/TextField"”,但正确的导入应该是“@mui/material/TextField"”。

所以这是一个超级通用的TypeScript错误,这个StackOverflow问题是我研究我的问题的各种查询的第一个结果。它有38.5万的浏览量。

对于那些使用Angular / TypeScript和使用ng-packagr的Angular库的人来说,你需要为每个特性/组件/服务定义public-api.ts,这样你就可以把它包含在index.ts中,比如在这个回购中找到这个文章

  • 节点16或18(下周LTS为18)
  • Angular 2+(目前有14个)
  • 打印稿4.6.4-4.8.2

一些简单的例子类似于引用创建库

ng new workspace --no-create-application
cd workspace
ng generate app home --routing=true --style=scss
ng generate app admin --routing=true --style=scss
ng generate library lib
... # include your library 'lib' into your application 'home'
ng build lib --watch &
ng serve home --open

没有直接解释的是你的index.tspublic-api.ts文件需要在每个功能/组件/服务中。如果你有一个复杂的库,比如下面回购中的这些示例特性A、B和C。回购有以下内容:

我也有这个问题。然后我将"module": "commonjs"改为"module": "ESNext",一切正常 this my tsconfig.json:

{
"compilerOptions": {
"module": "ESNext",
"esModuleInterop": true,
"target": "ESNext",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
},
"lib": ["ESNext"],
}

希望它能解决你的问题!