admin管理员组

文章数量:1122832

I am currently writing some TypeScript to work with socket.io by following the examples on the socket.io website (/).

I can get it to work properly, but if I follow the documentation as is, it leads to the error: Uncaught TypeError: Failed to resolve module specifier "socket.io-client". Relative references must start with either "/", "./", or "../". and this means I need to delete that line after every time I compiled the project.

A very similar question was asked 2+ years ago but none of the solutions worked for me.

This is because when TSC compiles the code to JavaScript it includes the import statement in my client side JS: import { io } from 'socket.io-client';

If I delete this line the code works great because the socket.io codebase is being served by my Express App and is being picked up by this line in the HTML file: <script src="/socket.io/socket.io.js"></script>

The issue is that I require the import statement in my Typescript file because that is what the compiler is using to get the socket.io types:

import { io, Socket } from 'socket.io-client';

const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();

Without the import statement I get the error "Cannot find name 'Socket'" and the code will not compile.

TypeScript (zero errors until I remove import statement) :

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 (The import statement causing the error, when that is removed it works properly):

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:

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

I am currently writing some TypeScript to work with socket.io by following the examples on the socket.io website (https://socket.io/docs/v4/typescript/).

I can get it to work properly, but if I follow the documentation as is, it leads to the error: Uncaught TypeError: Failed to resolve module specifier "socket.io-client". Relative references must start with either "/", "./", or "../". and this means I need to delete that line after every time I compiled the project.

A very similar question was asked 2+ years ago but none of the solutions worked for me.

This is because when TSC compiles the code to JavaScript it includes the import statement in my client side JS: import { io } from 'socket.io-client';

If I delete this line the code works great because the socket.io codebase is being served by my Express App and is being picked up by this line in the HTML file: <script src="/socket.io/socket.io.js"></script>

The issue is that I require the import statement in my Typescript file because that is what the compiler is using to get the socket.io types:

import { io, Socket } from 'socket.io-client';

const socket: Socket<ServerToClientEvents, ClientToServerEvents> = io();

Without the import statement I get the error "Cannot find name 'Socket'" and the code will not compile.

TypeScript (zero errors until I remove import statement) :

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 (The import statement causing the error, when that is removed it works properly):

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:

    "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"
    }
Share Improve this question edited Nov 22, 2024 at 17:03 Scarmez asked Nov 22, 2024 at 9:00 ScarmezScarmez 13 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

I have solved this problem myself. After reading the client socket.io installation page I noticed that to use with NPM you need to use a bundler such as Webpack or Browserify.

I have started using Webpack now and it works a treat, I was avoiding it for a while because I am new to full stack development and wanted to keep it barebones. There was no mention of having to use a bundler on the typescript socket.io page.

本文标签: