Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Transpiling node server and socket.io with webpack

I try to use webpack for my node server which use socket.io.

I have a simple server :

var server = require('http').createServer();
var io = require('socket.io').listen(server);

io.on('connection', function(client) {
  console.log('new client');

  client.on('hello', function(data) {
    console.log('msg: ', data);
  });

  client.on('disconnect', function(){
    console.log('client disconnect');
  });
});

server.listen(3000);

And my webpack.config.js

var config = {
  target: "node",
  entry: {
    server: ["server.js"]
  },
  module: {
    loaders: [
      {
        test: /\.(txt|json|osgjs|osgt|bin)$/,
        loader: "file?name=[path][name].[ext]"
      }
    ],
    noParse: ["ws"]
  }
  externals: ["ws"],
  output: {
    path: __dirname,
    filename: "[name].js"
  }
}

module.exports = config;

When I "compile" I have no error, just a warning :

> NODE_ENV=development BUILD_TARGET=server webpack --display-error-details

Hash: a692e23215bcd6caa05a
Version: webpack 1.13.2
Time: 672ms
                                       Asset     Size  Chunks             Chunk Names
              _/node_modules/mime-db/db.json   145 kB          [emitted]  
_/node_modules/socket.io-client/package.json  4.29 kB          [emitted]  
                                   server.js   572 kB       0  [emitted]  server
   [0] multi server 28 bytes {0} [built]
   [1] ./server.js 346 bytes {0} [built]
    + 88 hidden modules

WARNING in ../~/engine.io/lib/server.js
Critical dependencies:
74:43-65 the request of a dependency is an expression
 @ ../~/engine.io/lib/server.js 74:43-65

And when I try to start my server :

fs.js:977
  return binding.fstat(fd);
                 ^

Error: EBADF: bad file descriptor, fstat
    at Error (native)
    at Object.fs.fstatSync (fs.js:977:18)
    at tryStatSync (fs.js:462:13)
    at fs.readFileSync (fs.js:510:12)
    at Object.<anonymous> (/Users/alexis/Documents/server.js:109:21)
    at __webpack_require__ (/Users/alexis/Documents/server.js:21:30)
    at Object.<anonymous> (/Users/alexis/Documents/server.js:56:34)
    at __webpack_require__ (/Users/alexis/Documents/server.js:21:30)
    at Object.<anonymous> (/Users/alexis/Documents/server.js:48:19)
    at __webpack_require__ (/Users/alexis/Documents/server.js:21:30)

I use :

  • node: 6.7.0
  • webpack: 1.13.2
  • socket.io: 1.5.1
like image 433
CitronHades Avatar asked Oct 31 '16 14:10

CitronHades


1 Answers

The warning comes from a dynamic require, such as:

const test = require('scripts/' + scriptName)

It is usually safe to ignore it. Webpack tries to deal with dynamic requires using a context module, which is basically a representation of all of the possible modules that match the dynamic require. You can read more about it here: https://webpack.github.io/docs/context.html

Regarding the error, if you don't need socket.io to be bundled in your output bundle, you can add it to webpack's externals config, and webpack will just ignore it, but you will need to have a node_modules folder with socket.io in your solution.

So your configuration will be:

var config = {
  target: "node",
  entry: {
    server: ["server.js"]
  },
  module: {
    loaders: [
      {
        test: /\.(txt|json|osgjs|osgt|bin)$/,
        loader: "file?name=[path][name].[ext]"
      }
    ],
    noParse: ["ws"]
  }
  externals: ["ws", "socket.io"],
  output: {
    path: __dirname,
    filename: "[name].js"
  }
}

module.exports = config;

It is actually preferred not to include node_modules dependencies in your bundle for backend apps, and there is a webpack plugin just for that: https://www.npmjs.com/package/webpack-node-externals

If you would like to use the plugin instead, your config will be (after installing webpack-node-externals):

var nodeExternals = require('webpack-node-externals')

var config = {
  target: "node",
  entry: {
    server: ["server.js"]
  },
  module: {
    loaders: [
      {
        test: /\.(txt|json|osgjs|osgt|bin)$/,
        loader: "file?name=[path][name].[ext]"
      }
    ],
    noParse: ["ws"]
  }
  externals: [nodeExternals()],
  output: {
    path: __dirname,
    filename: "[name].js"
  }
}

module.exports = config;
like image 131
omerts Avatar answered Sep 22 '22 08:09

omerts