In my current TypeScript project, I am working with socket.io using examples from the official socket.io website's documentation (https://socket.io/docs/v4/typescript/).
Although I can make it function correctly, following the documentation as is leads to an error:
Uncaught TypeError: Failed to resolve module specifier "socket.io-client". Relative references must start with either "/", "./", or "../".
. This requires me to delete that line after every project compile.
A user had a similar issue over 2 years ago and none of the solutions provided have worked for me. You can view the question here.
The problem arises during compilation by TSC causing the import statement in my client-side JavaScript code:
import { io } from 'socket.io-client';
Deleting this line solves the issue because the socket.io codebase is served by my Express App and picked up in the HTML file here:
<script src="/socket.io/socket.io.js"></script>
However, I need the import statement in my Typescript file as it allows the compiler to correctly identify the socket.io types:
import { io, Socket } from 'socket.io-client';
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();
If I remove the import statement, I encounter the error "Cannot find name 'Socket'" and the code fails to compile.
Below is the TypeScript code snippet (error-free until import statement removal) :
import { io, Socket } from 'socket.io-client';
const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();
var messages = document.getElementById('messages')!;
var form = document.getElementById('form')!;
var input = document.getElementById('input')! as HTMLInputElement;
form.addEventListener('submit', function (e) {
e.preventDefault();
if (input.value) {
socket.emit('msg', input.value);
input.value = '';
}
});
socket.on('msg', (user, msg) => {
var item = document.createElement('li');
item.textContent = `${user}: ${msg}`;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
JavaScript code snippet (error occurs due to import statement), but functions properly when removed:
import { io } from 'socket.io-client';
const socket = io();
var messages = document.getElementById('messages');
var form = document.getElementById('form');
var input = document.getElementById('input');
form.addEventListener('submit', function (e) {
e.preventDefault();
if (input.value) {
socket.emit('msg', input.value);
input.value = '';
}
});
socket.on('msg', (user, msg) => {
var item = document.createElement('li');
item.textContent = `${user}: ${msg}`;
messages.appendChild(item);
window.scrollTo(0, document.body.scrollHeight);
});
Package.json dependencies listed below:
"dependencies": {
"@prisma/client": "^5.22.0",
"@quixo3/prisma-session-store": "^3.1.13",
"dotenv": "^16.4.5",
"express": "^4.21.1",
"express-session": "^1.18.1",
"passport": "^0.7.0",
"passport-discord": "^0.1.4",
"prisma": "^5.22.0",
"socket.io": "^4.8.1",
"socket.io-client": "^4.8.1",
"sqlite3": "^5.1.7"
},
"devDependencies": {
"@types/express": "^5.0.0",
"@types/express-session": "^1.18.0",
"@types/passport": "^1.0.17",
"@types/passport-discord": "^0.1.14",
"@types/sequelize": "^4.28.20",
"@types/sqlite3": "^3.1.11",
"ts-node": "^10.9.2",
"typescript": "^5.6.3"
}