83

What is the best way to load CommonJS modules as client-side JavaScript code in the browser?

CommonJS modules put their functionality in the module.exports namespace and are usually included using require(pathToModule) in a server-side script. Loading them on the client cannot work the same way (require needs to be replaced, asynchronousness needs to be taken into account, etc.).

I have found module loaders and other solutions: Browserify, RequireJS, yabble, etc. or ways to simply alter the modules. What do you consider the best way and why?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
travelboy
  • 2,647
  • 3
  • 27
  • 37
  • you can try https://github.com/component/component – Jonathan Ong May 10 '13 at 03:27
  • 1
    @JonathanOng As of 2015, component is deprecated. – mgthomas99 Feb 01 '18 at 16:50
  • 3
    As of 2018, some answers are dated, and webpack isn't mentinoed. Webpack would be another solution. Based on reading the different solutions webpack is becoming more and more used/recommended. It's a PITA to learn but very powerful and as of Webpack V4 with a good architecture for solving the transpiling/packaging problem. – PatS May 29 '18 at 21:35

6 Answers6

51

I have used RequireJS extensively in the past (implementation on BBC iPlayer in 2010) and it works well. It can handle CommonJS modules, but it needs an additional wrapper, which I find annoying.

If you want to use those modules in Node.js as well, you need to use RequireJS on the server side as well, which I don't like doing since it is not idiomatic Node.js JavaScript code.

I have used webmake and Browserify in the past year on a few projects. Initially, the compilation step put me off, but having used it extensively this year, I can say that this is not an issue.

Browserify has a watch function included, which works very well. Webmake can be hooked up to a watcher (such as watchr) or, you can use the webmake-middleware module, which can be used as part of an Express.js or connect application. This has the advantage that rather than compiling the JavaScript on each save, it is only compiled when you actually request it.

Connect makes it trivial to create a server (also static), so you could create a tiny static Node.js server to serve up your files if you want to develop your frontend without a backend.

Bonus: There isn't any need for a build script as you always deal with the built code.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gillesruppert
  • 646
  • 6
  • 6
22

Here is a comprehensive list of your current options ordered by their respective popularity (number of watchers) on GitHub:

Options for use of require() in the browser (Wayback Machine archive)

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Bruiser
  • 11,767
  • 5
  • 34
  • 45
13

Use Browserify.

Its description is: "Browser-side require() for your node modules and npm packages" which sounds what you need.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Kevin McTigue
  • 3,503
  • 2
  • 18
  • 22
2

The CommonJS compiler.

Why? It works fine with Node.js (CommonJS) modules /treat module exactly as Node.js and, with UMD, brings minimum extra code to the compiled JavaScript, allows exporting global variables of third-party libraries without touching their code, source maps and a trick that other cannot do:

var str = require( "lorem-ipsum.txt" );
console.log( str );

Output:

 Lorem ipsum dolor
 sit amet, consectetur
 adipiscing elit. Morbi...

Here are the slides: https://speakerdeck.com/dsheiko/modular-javascript-with-commonjs-compiler

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dmitry Sheiko
  • 2,130
  • 1
  • 25
  • 28
0

Webmake is one of the options. I use it to pack an application that is build from over 200 modules of over 20 packages. It works.

If you want to see some example, check: SoundCloud Playlist Manager. It's strictly client-side and built with Webmake.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mariusz Nowak
  • 32,050
  • 5
  • 35
  • 37
-2

I can't say I've tried the others you've listed here, but I like RequireJS because:

  • It works in a similar way to CommonJS
  • It's easy to use
  • It implements some of the upcoming new standards
  • You can use it in Node.js so that you can use the same files in server and client
  • It includes a minifier/packer for deploying to production
  • It has plugins. The Text plugin, that lets you load HTML files, is very useful for large applications.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
evilcelery
  • 15,941
  • 8
  • 42
  • 54
  • 7
    After having used RequireJS for a while I'm planning on switching to Browserify. RequireJS is still good but I got to the point where I needed to start really sharing certain modules between Node and the browser and it's easier to do by writing proper CommonJS modules. – evilcelery May 02 '12 at 21:30
  • 1
    CommonJS and requireJS are two different module systems. Is there any way to make them compatible, or automatically convert from one format to the other? – Anderson Green Jan 04 '13 at 01:28
  • 1
    RequireJs is only one module system, of a specific module format (AMD). The only tool that really bridges the module system incompatibilities (commonjs/AMD) is http://github.com/anodynos/urequire. It converts to UMD that runs everywhere. (note: I am its author) – Angelos Pikoulas Jun 30 '13 at 22:07
  • 9
    This doesn't answer the question. – Indolering Feb 16 '14 at 01:20
  • 1
    what you can do, is write commonjs modules, and then have development server and build script wrap these modules in AMD definitions – so that the source code is CJS, but when requested in browser it works as AMD – Misha Reyzlin Mar 23 '14 at 19:23
  • You can of course use require.js with node.js, I'm using right now and sharing files between the client and the server... – Totty.js Sep 09 '14 at 09:16
  • 1
    @Indolering The question literally says `What do you consider the best way and why?` – The Muffin Man Feb 24 '20 at 22:56