Use socket.io with ECMA Script modules (ESM)? - javascript

How do we use socket.io library with ecmascript module syntax?
I'm getting following error if I'm importing it like this:
import socketIO from "socket.io";
Error:
SyntaxError: The requested module 'socket.io' does not provide an export named 'default'

Try:
import {Socket} from ‘socket.io’
The socket.io package exports a server module as well so a default export won’t work here.
You can also do:
import * as SocketIO from ‘socket.io’
Then you will need to do socketIO.Socket

Related

When using the ES Module system in Node.js, can all Node packages be imported using the same import syntax?

This question is not whether Node.js supports the ES Module system.
That question has been answered previously, eg:
How can I use an ES6 import in Node.js?
Node.js - SyntaxError: Unexpected token import
And these answers are supported by the official Node.js docs:
ECMAScript modules are the official standard format to package JavaScript code for reuse...Node.js fully supports ECMAScript modules as they are currently specified and provides interoperability between them and its original module format, CommonJS. Node.js has two module systems: CommonJS modules and ECMAScript modules. Authors can tell Node.js to use the ECMAScript modules loader via the .mjs file extension, the package.json "type" field, or the --input-type flag.
Source
So it is clear that Node.js supports the ES Module system.
This question is:
When using the ES Module system in Node.js, can all Node packages be imported using the same import syntax?
The reason I ask is that a lot of packages' documentation does not specify how to import them using ES Module style, eg:
https://expressjs.com/en/starter/hello-world.html
https://github.com/expressjs/session
I want to avoid the situation where I am trying to figure out the correct syntax to use each time I want to import a library.
This answer seems to suggest this syntax:
import * as [ whatever_was_previously_used_as_the_variable_name ] from [ whatever_was_previously_between_the_quotes_in_the_parenthesis ]
So, using the examples above, this:
const express = require('express');
const app = express();
const session = require('express-session');
could safely be converted to:
import * as express from 'express';
const app = express();
import * as session from 'express-session';
Is that the 'universal' syntax that should be used to import all Node packages?
(Update: that session import above doesn't work, at app.use(session(sessionConfig)); it caused the error TypeError: session is not a function - I needed to define the import like this: import session from 'express-session'. I also had to import axios like this: import axios from 'axios', or i got a similar error. However, to use msal-node i had to use import * as msal from '#azure/msal-node').
Just to confuse things, I have come across other syntax examples, such as these in the Node docs (which includes node:):
import * as fs from 'node:fs/promises';
// OR:
import * as fs from 'node:fs';
Source
I am hoping a definitive answer can be provided that covers the different scenarios that may exist, eg: Node packages that live in the node_modules directory as well as one's own custom JavaScript modules that live outside of node_modules.
In this way, if I ever come across a package that does not specify installation instructions using the ES Modules style, I will still know the correct way to import it.
The import statement is indeed universal and can be used to import a module of either system, whether inside node_modules or out, or built-in to Node. When importing a CommonJS module this way, the value it would normally expose to require becomes its default export, so import name from 'url';, or any other form of import statement that retrieves the default export, will get you what you need.
The import * as name from 'url'; form you mentioned is for retrieving all of a module's named exports. This creates a module namespace object, never a function, though the function or other value that a CommonJS module exposes to require is available on the default property. There's generally no need to use import * with a CommonJS module, since everything that Node detects as a named export will be properties on the default export anyways.
You can also create a require from inside an ES module; this will work exactly the same way as require in CommonJS, but that includes the limitation of importing only CommonJS and built-in modules, not ES modules.

"Exports not defined" error in Svelte when importing Socket.IO client library

I'm having problems with the Socket.IO client library that I can't get my head around. When trying to import the library into my main Svelte Component like this
import io from 'socket.io-client'
everything compiles properly, but once I open it in the browser I get an
Uncaught Reference error: exports not defined
The above way is how the Socket.IO guides say, but I also tried different variations like
import {io} from 'socket.io-client'
import * as io from 'socket.io-client'
and can't get any one of them to work. I supsect it might have to do with how Rollup treats imports and what Module Formats it expects, but I don't have much knowledge in that regard.
Can anyone help?

what different between import * as module and import module in javascript

When I write typescript:
I have this code:
import * as express from 'express'
and the system gives me an error:
Type originates at this import. A namespace-style import cannot be called or constructed, and will cause a failure at runtime. Consider using a default import or import require here instead.
So, I change to:
import express from 'express'
what is the difference between them, why the first way can not called or constructed?
what is the difference between them
* as express will import the entire contents of a module
express is will import the default export only
why the first way can not called or constructed?
A module itself is not callable as per the ES spec. So you wouldn't be able to do express() i.e. a function invocation. Therefore it must mapped to a member of the module, in this case the default export member 🌹

importing js file in Vue project throws error

I am trying to use this plugin https://www.npmjs.com/package/mobius1-selectr
I did a npm install mobius1-selectr
and imported it in my main.js
import 'mobius1-selectr/dist/selectr.min.css';
import 'mobius1-selectr/dist/selectr.min.js';
but as soon I import I get this exception:
You must supply either a HTMLSelectElement or a CSS3 selector string.
which comes from the source of selectr.
Is the import not to be done this way in webpack / main.js?
What am I doing wrong? Any help is appreciated.
Yes your imports are incorrect. This library uses UMD to export Selectr constructor. You are using Webpack so default import in your case should work:
import Selectr from 'mobius1-selectr'

es6 in Node.js with Babel using import and IntelliSense

When using es6 import feature in Node.js there is a problem with modules written with commonjs module format. I use babel-register to run the code.
For example I want to use named exports from express module and I write:
import * as express from "express";
let app = express();
I also use TypeScript type definitions with typings and they work this way. But this code fails to run saying that express() is not a function.
When I write as if I use default export like:
import express from "express";
let app = express();
It works, but IntelliSense is not available.
What is the problem with this?

Categories

Resources