Reputation:
Trying to implement a module following the official handbook, I get this error message:
Uncaught ReferenceError: exports is not defined
at app.js:2
But nowhere in my code do I ever use the name exports
.
How can I fix this?
let a = 2;
let b:number = 3;
import Person = require ('./mods/module-1');
export class Person {
constructor(){
console.log('Person Class');
}
}
export default Person;
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true,
"outDir": "scripts/"
},
"exclude": [
"node_modules"
]
}
Upvotes: 284
Views: 643882
Reputation: 92
Hello o fix this probleme by using this :
{
"compilerOptions": {
"target": "es6", // 👈️ set this to es6
// "module": "commonjs", // 👈️ REMOVE this (if browser env)
}
}
Upvotes: 0
Reputation: 2307
If you are are using webpack along with babel-loader and @babel/preset-env, then make sure to callout loose and modules. So instead of the following:
"presets": ["@babel/preset-env"]
instead do
"presets": [["@babel/preset-env", { "loose": true, "modules": false }]],
Upvotes: 2
Reputation: 1207
I hit this error shortly after switching to "Node 16 + ESM + strict" tsconfig.json.
I think the ESM change was the bit that caused it.
I had to bisect the file to figure out the root cause:
exports.webhookTaskProcessor = functions.firestore
.document("items/{itemId}/tasks/{taskId}")
.onCreate((_change, context) => {
processItemTasks(context.params.itemId);
});
This fixed it:
export const webhookTaskProcessor = functions.firestore
.document("items/{itemId}/tasks/{taskId}")
.onCreate((_change, context) => {
processItemTasks(context.params.itemId);
});
Would be rad if the error message was a little more helpful. I hope this breadcrumb is useful to you.
Upvotes: 3
Reputation: 442
I have this issue too. then I just change "module": "commonjs"
to "module": "ESNext"
everything is working fine.
this my tsconfig.json
:
{
"compilerOptions": {
"module": "ESNext",
"esModuleInterop": true,
"target": "ESNext",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist",
},
"lib": ["ESNext"],
}
I hope it can solve your problem!
Upvotes: 4
Reputation: 171
In package.json, add "type": "module"
In terminal type in
npx tsc --init
It will create a tsconfig.json.
In tsconfig.json,
"target": "es5"
to "target": "es6"
//"module": "commonjs",
"moduleResolution": "node",
You should be good to go.
In package.json, create a build script:
"build": "tsc -p tsconfig.json"
Then, when you want to build, you just compile npm run build
then execute and should be good
Upvotes: 7
Reputation: 81
So this is a super generic TypeScript error and this StackOverflow question is the first result for various queries I made researching my problem. It has 385k views.
For those with Angular / TypeScript and an Angular Library using ng-packagr seeing a generic "ReferenceError: exports is not defined", you'll need to define public-api.ts
for each feature/component/service such that you include it with index.ts
such as found in this repo for this article
Several shallow examples go something like this referencing Creating Libraries
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
What's not directly explained is your index.ts
and public-api.ts
files need to be in each feature/component/service. Such as these example features A, B, and C in the repo below if you have a complex library. repo has the following:
./public-api
)./public-api
)./public-api
)Upvotes: 1
Reputation: 386
Not answering the question directly, but no stackoverflow thread mentionned this case, took me a while to debug, and so adding it here in case it could help someone in the future.
I had the error "exports is not defined" coming from an imported NPM module. Changing my typescript config did nothing as I had no control over the imported third-party code. The problem was an invalid import syntax for that package. For example, I had imported "@mui/material/TextField/TextField", yet the correct import was supposed to be "@mui/material/TextField".
Upvotes: 1
Reputation: 5630
Add the following line before other references to JavaScript. This is a nice little hack.
<script>var exports = {};</script>
Upvotes: 132
Reputation: 9326
First, go to your index.html
in your public folder find the reference of the script <script src="myScript.js"></script>
and add type="module"
Like so:
<script type="module" src="myScript.js"></script>
Secondly, in your tsconfig.json
make sure target is set to es5
and module to 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. */
}
important: make sure to import with the .js
extension e.g. import Piece from './classes/piece.js'
Upvotes: 3
Reputation: 31
I think the problem may be the mismatched configuration.
I just post partial content here, for clarity. Github project https://github.com/jmmvkr/ts-express/ have a complete set of files demonstrate the working solution 1 and solution 2.
Working solution 1, ES Module
/* Configuration for ES Module */
// tsconfig.json
{
"compilerOptions": {
"module": "es6", // or "esnext"
}
}
// package.json
{
"type": "module", // type is module
}
Working solution 2, CommonJS
/* Configuration for CommonJS */
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
}
}
// package.json
{
"type": "", // type is NOT module
}
Mixed, do NOT work
/* Mixed, got ReferenceError: exports is not defined in ES module scope */
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
}
}
// package.json
{
"type": "module", // type is module
}
Upvotes: 2
Reputation: 729
I ran into this issue a few weeks ago and used the exports hack above in the short term but finally figured out another way around this that's working great for me.
So unlike some of the other responses above, I actually wanted the code I'm compiling to be a module. By setting "target": "es6",
"module": "esnext"
and then linking to my compiled JS file with type="module"
instead of type="text/javascript"
, my compiled code no longer has the Object.defineProperty(exports, "__esModule", { value: true });
line and it's still a module 🎉
My 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"]
}
My link to my compiled code in HTML head
tags:
<script src="../build/index.js" type="module" defer></script>
As a bonus, now I can also import anything that I export in that index.js file in a separate type="module"
script down below the main HTML body
code:
<script type="module">
import { coolEncodingFunction, coolDecodingFunction } from "../build/index.js";
/* Do stuff with coolEncodingFunction and coolDecodingFunction */
/* ... */
</script>
Upvotes: 19
Reputation: 171
I had similar issue as the original poster of the question:
I better tell you what mistakes I made and how I corrected it, that might help someone.
I had javascript nodejs project and converted it to typescript.
Previously in package.json I had "type":"module" when I was running in JavaScript.
When I converted it to TypeScript project and started converting files in .ts files and started running using following command:
npx tsc test.ts && node test.ts
I would get the above error.
I got rid of the error by simply removing the "type":"module" from package.json
My tsconfig.json would like below:
{
"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"]
I am using node 14 and TypeScript 4.2.4
Upvotes: 4
Reputation: 4580
As ES5
/ES2009
doesn't support modules (import/export/require) on the client / browser you have to use libraries, which bundle the modules into a single file, which can be included via <script>
tag, such as
See also this answer.
Upvotes: 0
Reputation: 2035
I stuck with such error in a SSR
client part because it used a lib which was built with tsconfig.json
compilerOptions
as target: ES5
what brought using CommonJS
for module resolution tsc CLI Options Compiler Options: target === "ES3" or "ES5" ? "CommonJS" : "ES6"
. While it used the target ESNext
.
Upvotes: 0
Reputation: 14464
EDIT:
This answer might not work depending if you're not targeting es5
anymore, I'll try to make the answer more complete.
Original Answer
If CommonJS isn't installed (which defines exports
), you have to remove this line from your tsconfig.json
:
"module": "commonjs",
As per the comments, this alone may not work with later versions of tsc
. If that is the case, you can install a module loader like CommonJS, SystemJS or RequireJS and then specify that.
Note:
Look at your main.js
file that tsc
generated. You will find this at the very top:
Object.defineProperty(exports, "__esModule", { value: true });
It is the root of the error message, and after removing "module": "commonjs",
, it will vanish.
Upvotes: 125
Reputation: 2290
If you are just using interfaces for types, leave out the export
keyword and ts can pick up on the types without needing to import. They key is you cannot use import
/export
anywhere.
export interface Person {
name: string;
age: number;
}
into
interface Person {
name: string;
age: number;
}
Upvotes: -2
Reputation: 31
To solve this issue, put these two lines in your index.html page.
<script>var exports = {"__esModule": true};</script>
<script type="text/javascript" src="/main.js">
Make sure to check your main.js file path.
Upvotes: 2
Reputation: 796
I had the same issue, but my setup required a different solution.
I'm using the create-react-app-rewired
package with a config-overrides.js
file. Previously, I was using the addBabelPresets
import (in the override()
method) from customize-cra
and decided to abstract those presets to a separate file. Coincidentally, this solved my problem.
I added useBabelRc()
to the override()
method in config-overrides.js
and created a babel.config.js
file with the following:
module.exports = {
presets: [
'@babel/preset-react',
'@babel/preset-env'
],
}
Upvotes: 0
Reputation: 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"]
}
}
Upvotes: -3
Reputation: 380
Note: This might not be applicable for OP's answer, but I was getting this error, and this how I solved it.
So the problem that I was facing was that I was getting this error when I retrieved a 'js' library from a particular CDN.
The only wrong thing that I was doing was importing from the CDN's cjs
directory like so:
https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/cjs/popper.min.js
Notice the dist/cjs
part? That's where the problem was.
I went back to the CDN (jsdelivr) in my case and navigated to find the umd
folder. And I could find another set of popper.min.js
which was the correct file to import:
https://cdn.jsdelivr.net/npm/@popperjs/[email protected]/dist/umd/popper.min.js
.
Upvotes: 2
Reputation: 443
Had the same issue and fixed it by changing the JS packages loading order.
Check the order in which the packages you need are being called and load them in an appropriate order.
In my specific case (not using module bundler) I needed to load Redux
, then Redux Thunk
, then React Redux
. Loading React Redux
before Redux Thunk
would give me exports is not defined
.
Upvotes: 0
Reputation: 23654
This is fixed by setting the module
compiler option to es6
:
{
"compilerOptions": {
"module": "es6",
"target": "es5",
}
}
Upvotes: 53
Reputation: 57
for me, removing "esModuleInterop": true
from tsconfig.json did the trick.
Upvotes: 3
Reputation: 10502
Simply add libraryTarget: 'umd'
, like so
const webpackConfig = {
output: {
libraryTarget: 'umd' // Fix: "Uncaught ReferenceError: exports is not defined".
}
};
module.exports = webpackConfig; // Export all custom Webpack configs.
Upvotes: 2
Reputation: 279
Try what @iFreilicht suggested above. If that didn't work after you've installed webpack and all, you may have just copied a webpack configuration from somewhere online and configured there that you want the output to support CommonJS by mistake. Make sure this isn't the case in 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"
}
};
Upvotes: 0
Reputation: 13699
For some ASP.NET projects import
and export
may not be used at all in your Typescripts.
The question's error showed up when I attempted to do so and I only discovered later that I just needed to add the generated JS script to the View like so:
<script src="~/scripts/js/[GENERATED_FILE].Index.js" asp-append-version="true"></script>
Upvotes: 1
Reputation: 106
I had this same error too. In my case it was because we had an old-fashioned import statement in our TypeScript AngularJS project like this:
import { IAttributes, IScope } from "angular";
which was compiled to JavaScript like this:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
This was needed back in the old days because we then used IAttributes
in the code and TypeScript wouldn't have known what to do with it otherwise.
But after removing the import statement, and converting IAttributes
to ng.IAttributes
those two JavaScript lines disappeared - and so did the error message.
Upvotes: 5
Reputation: 1105
my solution is a sum up of everything above with little tricks I added, basically I added this to my html code
<script>var exports = {"__esModule": true};</script>
<script src="js/file.js"></script>
this even allows you to use import
instead of require
if you're using electron or something, and it works fine with typescript 3.5.1, target: es3 -> esnext.
Upvotes: 11
Reputation: 335
npm install @babel/plugin-transform-modules-commonjs
and add to to .babelrc plugins resolved my question.
Upvotes: 21