Omid
Omid

Reputation: 321

Pure TypeScript - “ReferenceError: exports is not defined”

I have a simple client-server typescript application and every import statement in my client.ts file will result in the ReferenceError: exports is not defined in browser after loading the HTML. project structure:

root
|-- dist
    |-- public
        |-- client.js
        |-- client.js.map
    |-- src
        |-- index.js
        |-- index.js.map
|-- node_modules
|-- public
    |-- client.ts
|-- src
    |-- index.ts
|-- index.html
|-- package.json
|-- tsconfig.json

I've read every similar question like this one How to fix "ReferenceError: exports is not defined" in a pure TypeScript project? and tried everything they suggested but still no luck!

Index.ts

import express from "express";
import path from "path";
import http from "http";
import {Server, Socket} from "socket.io";

const app = express();
const server = http.createServer(app);
const io = new Server(server);

// set static folder
app.use(express.static(path.join(__dirname, '../../')));

io.on('connection', (socket: Socket) => {
  console.log('new ws connection');
});

const port = 8080 || process.env.PORT; // default port to listen

// start the Express server
server.listen(port, () => {
  console.log(`server started at http://localhost:${port}`);
});

client.ts

import { io, Socket } from "socket.io-client";
const socket: Socket = io();

package.json

{
  "name": "proto",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js",
  "scripts": {
    "start": "node dist/src/index.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.13",
    "@types/node": "^16.3.3",
    "tslint": "^5.12.1",
    "typescript": "^3.9.10"
  },
  "dependencies": {
    "express": "^4.17.1",
    "socket.io": "^4.1.3",
    "socket.io-client": "^4.1.3",
  }
}

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "target": "es6",
    "noImplicitAny": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist",
    "baseUrl": ".",
    "paths": {
      "*": [
        "*",
        "src/*",
        "public/*"
      ]
    }
  },
  "lib": [
    "es2015"
  ]
}

client.js result from tsc compile output:

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const socket_io_client_1 = require("socket.io-client");
const socket = socket_io_client_1.io();
//# sourceMappingURL=client.js.map

Error message in browser console: Uncaught ReferenceError: exports is not defined at client.js:2

Upvotes: 0

Views: 374

Answers (1)

Drag13
Drag13

Reputation: 5998

The issue is that for the browser, you need to bundle (pack all files together) you code.

To achieve this you may use parcel, webpack or browserify

The simplest way (for me) is to use parcel. Simply install it as dev dependency

npm i parcel -D

And add build command to the package.json

...
"build": "parcel index.html"
...

And reference your root ts file from the index.html. Might happen you will be prompted to move index.html to the src folder

Everything other, including hot module reloading, minification and hashing parcel will do for you.

The documentation for Parcel is here

If you want something more flexible, then webpack should be your choice. Webpack is something like Swiss Knife in the world of bundling, it's really cool, but sometimes a bit complicated.

P.S. If you want to take a look at something newer - vite is also an option

Upvotes: 1

Related Questions