Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid using debug module and other node builtins in client library #1188

Closed
1 of 2 tasks
rmehta opened this issue Feb 19, 2018 · 7 comments
Closed
1 of 2 tasks

Avoid using debug module and other node builtins in client library #1188

rmehta opened this issue Feb 19, 2018 · 7 comments
Labels
documentation Improvements or additions to documentation

Comments

@rmehta
Copy link

rmehta commented Feb 19, 2018

Note: for support questions, please use one of these channels: stackoverflow or slack

You want to:

  • report a bug
  • request a feature

Current behaviour

Use socket-io.client in an app and build it with rollup

JS file

const io = require('socket.io-client')
...

Build with rollup

5:44:40 PM watch.1  |  (!) Unresolved dependencies
5:44:40 PM watch.1  |  https://github.com/rollup/rollup/wiki/Troubleshooting#treating-module-as-external-dependency
5:44:40 PM watch.1  |  tty (imported by ../frappejs/node_modules/socket.io-client/node_modules/debug/src/node.js, commonjs-external:tty, ../frappejs/node_modules/socket.io-parser/node_modules/debug/src/node.js, ../frappejs/node_modules/debug/src/node.js)
5:44:40 PM watch.1  |  util (imported by ../frappejs/node_modules/socket.io-client/node_modules/debug/src/node.js, commonjs-external:util, ../frappejs/node_modules/socket.io-parser/node_modules/debug/src/node.js, ../frappejs/node_modules/debug/src/node.js)
5:44:40 PM watch.1  |  fs (imported by ../frappejs/node_modules/socket.io-client/node_modules/debug/src/node.js, commonjs-external:fs, ../frappejs/node_modules/socket.io-parser/node_modules/debug/src/node.js, ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, ../frappejs/node_modules/bindings/bindings.js)
5:44:40 PM watch.1  |  net (imported by ../frappejs/node_modules/socket.io-client/node_modules/debug/src/node.js, commonjs-external:net, ../frappejs/node_modules/socket.io-parser/node_modules/debug/src/node.js)
5:44:40 PM watch.1  |  url (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:url, ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
5:44:40 PM watch.1  |  child_process (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:child_process)
5:44:40 PM watch.1  |  http (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:http, ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
5:44:40 PM watch.1  |  https (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:https, ../frappejs/node_modules/ws/lib/WebSocket.js)
5:44:40 PM watch.1  |  events (imported by ../frappejs/node_modules/ws/lib/WebSocket.js, commonjs-external:events, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
5:44:40 PM watch.1  |  crypto (imported by ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/Sender.js, commonjs-external:crypto, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
5:44:40 PM watch.1  |  buffer (imported by ../frappejs/node_modules/safe-buffer/index.js, commonjs-external:buffer)
5:44:40 PM watch.1  |  zlib (imported by ../frappejs/node_modules/ws/lib/PerMessageDeflate.js, commonjs-external:zlib)
5:44:40 PM watch.1  |  path (imported by ../frappejs/node_modules/bindings/bindings.js, commonjs-external:path)
5:44:40 PM watch.1  |  (!) Missing global variable names
5:44:40 PM watch.1  |  Use output.globals to specify browser global variable names corresponding to external modules
5:44:40 PM watch.1  |  tty (guessing 'tty')
5:44:40 PM watch.1  |  util (guessing 'util')
5:44:40 PM watch.1  |  fs (guessing 'fs')
5:44:40 PM watch.1  |  net (guessing 'net')
5:44:40 PM watch.1  |  url (guessing 'url')
5:44:40 PM watch.1  |  child_process (guessing 'child_process')
5:44:40 PM watch.1  |  http (guessing 'http')
5:44:40 PM watch.1  |  https (guessing 'https')
5:44:40 PM watch.1  |  buffer (guessing 'buffer')
5:44:40 PM watch.1  |  path (guessing 'path')
5:44:40 PM watch.1  |  zlib (guessing 'zlib')
5:44:40 PM watch.1  |  crypto (guessing 'crypto')
5:44:40 PM watch.1  |  events (guessing 'events')

Steps to reproduce (if the current behaviour is a bug)

See above

Expected behaviour

Should be include client library easily without nodejs builtins

Setup

  • OS:
  • browser:
  • socket.io version: 2.0.4

Other information (e.g. stacktraces, related issues, suggestions how to fix)

Client libraries should be dependent only on browser API.

Using nodejs builtins (debug) creates "dependency hell". I had to include socket.io-client separately with the <script> tag finally.

@darrachequesne
Copy link
Member

Hi! I'm not familiar with Rollup, is it possible to exclude a library from a build? (like we did here with webpack)

@rmehta
Copy link
Author

rmehta commented Feb 20, 2018

Thanks for the tip! I did some more experiments, but replacing debug did not work. It also looks for fs and other modules (xmlhttprequest-ssl).

7:24:36 PM watch.1  |  fs (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:fs, ../frappejs/node_modules/bindings/bindings.js)
7:24:36 PM watch.1  |  url (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:url, ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
7:24:36 PM watch.1  |  child_process (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:child_process)
7:24:36 PM watch.1  |  http (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:http, ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
7:24:36 PM watch.1  |  https (imported by ../frappejs/node_modules/xmlhttprequest-ssl/lib/XMLHttpRequest.js, commonjs-external:https, ../frappejs/node_modules/ws/lib/WebSocket.js)
7:24:36 PM watch.1  |  events (imported by ../frappejs/node_modules/ws/lib/WebSocket.js, commonjs-external:events, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
7:24:36 PM watch.1  |  crypto (imported by ../frappejs/node_modules/ws/lib/WebSocket.js, ../frappejs/node_modules/ws/lib/Sender.js, commonjs-external:crypto, ../frappejs/node_modules/ws/lib/WebSocketServer.js)
7:24:36 PM watch.1  |  buffer (imported by ../frappejs/node_modules/safe-buffer/index.js, commonjs-external:buffer)
7:24:36 PM watch.1  |  zlib (imported by ../frappejs/node_modules/ws/lib/PerMessageDeflate.js, commonjs-external:zlib)
7:24:36 PM watch.1  |  path (imported by ../frappejs/node_modules/bindings/bindings.js, commonjs-external:path)

Also tried using require('socket.io-client/dist/socket.io') directly, but it gets stuck in the browser at:

bundle.js:17 Uncaught TypeError: Cannot read property 'Blob' of undefined
    at Object.<anonymous> (bundle.js:17)
    at Object.<anonymous> (bundle.js:17)
    at e (bundle.js:17)
    at Object.<anonymous> (bundle.js:17)
    at e (bundle.js:17)
    at Object.<anonymous> (bundle.js:17)
    at e (bundle.js:17)
    at bundle.js:17
    at bundle.js:17
    at bundle.js:17

Edit: Sorry realise cannot just import the dist (its a webpack build!).

Rollup is a much simpler package manager (I like it much more than webpack). Will be great if you can build a browser friendly module that can be built via imports or commonjs without hacks.

@hath995
Copy link

hath995 commented Jan 22, 2019

I also am running into this issue.

@Akatuoro
Copy link

For anyone still running into this issue (like me today), make sure to use the option browser: true for @rollup/plugin-node-resolve.

Excluding the debug module like in the slim webpack build mentioned above does still reduce the bundle size.

@darrachequesne darrachequesne added the documentation Improvements or additions to documentation label Jan 28, 2021
@darrachequesne
Copy link
Member

Added in the documentation here: https://socket.io/docs/v4/client-with-bundlers/#browser-1

@roggc
Copy link

roggc commented Aug 2, 2024

For anyone still running into this issue (like me today), make sure to use the option browser: true for @rollup/plugin-node-resolve.

Excluding the debug module like in the slim webpack build mentioned above does still reduce the bundle size.

I am using this but still no luck, the xmlhttprequest-ssl imports 'url', 'http', and 'https' in the corresponding bundled file (I do preserveModules: true and I use esm format). I tried with rollup-plugin-polyfill-node but no luck.

@roggc
Copy link

roggc commented Aug 7, 2024

For anyone still running into this issue (like me today), make sure to use the option browser: true for @rollup/plugin-node-resolve.
Excluding the debug module like in the slim webpack build mentioned above does still reduce the bundle size.

I am using this but still no luck, the xmlhttprequest-ssl imports 'url', 'http', and 'https' in the corresponding bundled file (I do preserveModules: true and I use esm format). I tried with rollup-plugin-polyfill-node but no luck.

One workaround I've found is to use browserify for the entire socket.io-client module and then use an alias in rollup to point to the browserified module. You must do first:

npx browserify -r socket.io-client -t [ babelify --presets [ @babel/preset-env ] ] -o module.browserified.js

For this you must first install browserify, babelify and @babel/preset-env.

Then you must manually edit the output (module.browserified.js). It must look like this:

var require=....
const { io } = require("socket.io-client");
export { io };

The parts I've added is the var at the beginning and the const {io}=require... and export {io} lines.

Finally, in your rollup config file you do:

plugins: [
      alias({
        entries: [
          {
            find: "socket.io-client",
            replacement: path.resolve(__dirname, "module.browserified.js"),
          },
        ]
     })
]

and for __dirname you do first in the same rollup config file:

import { fileURLToPath } from "url";
import path from "path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

I hope this can help anyone with the same problem as me and googling about it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

No branches or pull requests

5 participants