Socket.io: Error when building for WebPack

Created on 2 May 2015  ·  27Comments  ·  Source: socketio/socket.io

A while ago, I had realized that there is an error when trying to use socket.io-client within a WebPack module. It turns out, that "dist/debug.js" can not be located. I did a little bit of unixy research:

[email protected] ~/W/BIRD3 $ grep -r "dist/debug" node_modules/socket.io-client/
node_modules/socket.io-client//node_modules/engine.io-client/node_modules/debug/Makefile:all: dist/debug.js
node_modules/socket.io-client//node_modules/engine.io-client/node_modules/debug/Makefile:dist/debug.js: node_modules browser.js debug.js dist
[email protected] ~/W/BIRD3 $ find node_modules/socket.io-client -name "dist"
[empty]
[email protected] ~/W/BIRD3 $ find node_modules -name "debug.js" | grep dist

Conclusion: The dist folder must be a virtual folder that is used during the Browserify process... Now, how exactly do I get rid of that? It's really heavy-lifting to require("socket.io-client/socket.io") although there already IS a system that knows commonJS.

With heavy-lifting, I mean that adding the SIO client is ~350KB... A fix would be pretty awesome.

Most helpful comment

import IO from 'socket.io-client'

should work fine with webpack + babel

All 27 comments

I am also not sure how to add the socket.io-client library into my client-side app to connect back to the server.

I am trying to require it like so:

var io = require("socket.io-client");

var socket = io("http://localhost:3000");
socket.on("data", function(data) {
    console.log("data event", data);
});

...and I get this error: TypeError: undefined is not an object (evaluating 'global.WebSocket') for an anon function.

I'm mostly a back-end guy so client-side javascript is not my strong suit.

Update: require("socket.io-client/socket.io") seems to have worked, but with a warning that suggests what was mentioned above: This seems to be a pre-built javascript file. Though this is possible, it's not recommended. Try to require the original source to get better results.

@johnelliott : just do require("socket.io-client"), Webpack will locate the correct source via the package.json entry. The warning comes because that file is packaged to be loaded via a <script> tag.

Nope.

The reason why it did not work for me was that I was using a plugin to resolve Bower modules, which didn’t play entirely nice on nested require()s. So what I did was to change that factor.

If you were using a plugin called something like „bower-webpack-plugin“ or alike, dump it. the actual solution is this:

var bowerProvider = new webpack.ResolverPlugin([
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin("bower.json", ["main"]),
new webpack.ResolverPlugin.DirectoryDescriptionFilePlugin(".bower.json", ["main"])
], ["normal", "loader"]);

It totally look awkward, agreed. But if you read it over a couple of time,s you will realize that it changes the way that modules are resolved, and hence required.

If that still does not work, then you could use a module alias.

Within the client, the debug library is loaded like so:

var debug = require(„debug“)(…); // excuse the quoting, my mail client sucks.

So you can add a module alias in your webpack.config.js:

// Add the alias section into the resolve section of the config.
module.exports = {
resolve: {
alias: {
// Ensure compatibility to original bootstrap
"debug$": path.join("node_modules","debug","index.js")
}
}
};

If that still does not work, let me know. :)

Are you using babel?

I was not. I switched to SocketCluster in the meantime since that worked.

so the best solution is?

import IO from 'socket.io-client'

should work fine with webpack + babel

When I used it, I think I'd called out for the index.js file directly. But its quite a while ago...so i cant be certain.

Think this could be closed.

I am getting this error still, I don't think this should be closed just yet.

I fixed this by uninstalling socket.io-client from npm and installing via bower

I am having this same problem. I don't use bower. Is there another way?

You can use an alias in your webpack config.
Or the SIO devs find a better solution.

I came across the same problem when updating to
npm 3.3.9 webpack 1.12.13 socket.io-client 1.4.5

Solving this by adding

    resolve: {
        alias: {
            'socket.io-client': path.join( nodeRoot, 'socket.io-client', 'socket.io.js' )
        }
    },
    module: {
        noParse: [ /socket.io-client/ ]
    }

Anyone has a better solution?

@faller what do we put for node root? like in the public directory or is that something from an HTML file?
My bad if it's a bad question, never used any of this before.

@kennetpostigo var nodeRoot = path.join( __dirname, 'node_modules' ),

i was getting shit load of errors but using require('socket.io/lib/socket.js') solved it , but now am getting a new error

untitled

the calling code
var socket = require('socket.io/lib/socket.js')('http://appdev:3000');

I was getting the same error too. I think I managed to realize what is happening.
Webpack resolves _only_ requires, not requires.resolve. I think the problem is this, since it is used in the _lib/index.js_ file as follows:

var clientSource = read(require.resolve('socket.io-client/socket.io.js'), 'utf-8');

This is a problem for webpack, since it is not supposed to be working with that directive, how it is possible to see here.
Once I understood this, I saw that the line of code mentioned above is only useful for a function that handles a request serving /socket.io.js.
Since this functionality was completely useless for my application (I use only require('modulename'), I commented both the line above and the whole serve function in the _lib/index.js_ file. Now it works like a charm.
I don't know whether this has to be considered a bug or not, but It took some time to really understand what was going on and how to fix it.

I'm getting a number of socket.io webpack build issues as well.

ERROR in ./~/socket.io/lib/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' /Users/mkozachek/development/webserver_development/node_modules/socket.io-client/socket.io.js in /Users/mkozachek/development/webserver_development/node_modules/socket.io/lib
 @ ./~/socket.io/lib/index.js 9:13-40


ERROR in ./~/socket.io/lib/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' /Users/mkozachek/development/webserver_development/node_modules/socket.io-client/socket.io.js/package in /Users/mkozachek/development/webserver_development/node_modules/socket.io/lib
 @ ./~/socket.io/lib/index.js 10:20-55

ERROR in ./~/socket.io/lib/index.js
Module not found: Error: Cannot resolve 'file' or 'directory' /Users/mkozachek/development/webserver_development/node_modules/socket.io-client/socket.io.js/dist/socket.io.min.js in /Users/mkozachek/development/webserver_development/node_modules/socket.io/lib
 @ ./~/socket.io/lib/index.js 101:24-81

I've modified my webpack config to include
resolve: { alias: { 'socket.io-client': path.join( __dirname, 'node_modules', 'socket.io-client', 'socket.io.js' ) } },, noparse on the client, and target: 'node'.

There seems to be several different issues here.. It seems I was able to bundle both the client and the server here, can anyone check that example please?

I was getting this error with Webpack 2.2 and socket.io-client 1.7.2. I tried pretty much everything listed here and nothing worked. Eventually I stopped the errors by installing the debug module into node_modules, npm i debug -S and listing 'debug' as an external in my webpack config, externals: ['debug'],.

Hi, I would like to reopen this issue because it works like a charm for socket.io-client, but not for the server !

So I cannot bundle my NodeJS server using socket.io with Webpack ! I have to put socket.io in the "externals" of webpack along with the few libraries that doesn't work (including webpack itself)

See these related issues in Webpack and Yargs :

https://github.com/webpack/webpack/issues/1434
https://github.com/yargs/yargs/issues/312

@rgranger This's an example on how to use webpack and socket.io for the server:

package.json

{
  "name": "whatever",
  "version": "1.0.0",
  "description": "",
  "main": "",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "John Doe",
  "license": "ISC",
  "dependencies": {
    "brfs": "^1.4.3",
    "bufferutil": "^3.0.0",
    "socket.io": "^1.7.3",
    "transform-loader": "^0.2.4",
    "utf-8-validate": "^3.0.1"
  },
  "devDependencies": {
    "json-loader": "^0.5.4",
    "null-loader": "^0.1.1",
    "webpack": "^2.4.1"
  }
}

webpack.config.js

const path    = require("path");

module.exports = {
  entry: './server.js',
  target: 'node',
  output: {
    path: __dirname,
    filename: 'bundle.server.js'
  },
  module: {
    loaders: [
      {
        test: /(\.md|\.map)$/,
        loader: 'null-loader'
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.js$/,
        exclude: '/node_modules/',
        loader: "transform-loader?brfs"
      }
    ]
  }
};

server.js

const server = require('http').createServer();
const io = require('socket.io')(server, {
  // serveClient: false // do not serve the client file, in that case the brfs loader is not needed
});
const port = process.env.PORT || 3000;

io.on('connect', onConnect);
server.listen(port, () => console.log('server listening on port ' + port));

function onConnect(socket){
  console.log('connect ' + socket.id);

  socket.on('disconnect', () => console.log('disconnect ' + socket.id));
}

A sample Webpack build for the server : https://github.com/socketio/socket.io/tree/master/examples/webpack-build-server

Thanks very much @Arbaoui-Mehdi, the key to get this fixed is to disable serving the client socket.js.

@freemh you save my life bro

When using Webpack v3, I just did
npm install --save-dev uglifyjs-webpack-plugin@1
then just use UglifyJsPlugin(...) instead of webpack.optimize.UglifyJsPlugin({...})
be aware that the options change.. you need to add uglifyOptions inside the object..

ref: https://github.com/webpack-contrib/uglifyjs-webpack-plugin

Was this page helpful?
0 / 5 - 0 ratings