21

is there a way I can use an npm package on the client side? For example, I want to use the dateformat(https://www.npmjs.com/package/dateformat) package in my client side javascript file

Trung Tran
  • 13,141
  • 42
  • 113
  • 200
  • 1
    moment.js is a good client side implementation of the above.. http://momentjs.com/ – OliverJ90 Jan 28 '16 at 21:07
  • 2
    Possible duplicate of [How to manage client-side JavaScript dependencies?](http://stackoverflow.com/questions/12893046/how-to-manage-client-side-javascript-dependencies) – gfpacheco Jan 28 '16 at 21:07

3 Answers3

15

If you want to use npm on the client you may consider using browserify which is designed for that purpose. The node module system is not compatible with browsers so browserify transpiles the javascript into something that will work. Hence the name : browserify.

Arne Evertsson
  • 19,693
  • 20
  • 69
  • 84
chriskelly
  • 7,526
  • 3
  • 32
  • 50
  • 3
    But some package allows me to use the global variable directly. Such as `socket.io`, the `io` variable is exposed when I put `` in the html file. I don't need to copy the file to the public directory. – newguy May 14 '17 at 09:22
7

I found it wasn't enough to use Browserify. There were still issues with the client-side not finding the variables/functions from the library.

Here are the steps that worked for me:

Install Browserify:

npm install -g browserify

Install a library from npm (I'll use leader-line as an example):

npm i leader-line

You will now have all the npm files needed inside the node_modules directory:

enter image description here

Now we can run the usual Browserify command to bundle the JS file from the npm package:

browserify node_modules/leader-line/leader-line.min.js -o bundle.js

This will produce a bundle.js file outside of node_modules:

enter image description here

This is the file we can bring into the front-end, as we would with a usual JS library.

So, assuming I added my bundle.js file to a libs folder, and renamed bundle.js to leaderline.js, I can simply add the usual line in the header of my index.html file:

<script src="libs/leaderline.js" type="module"></script>

Notice the addition of type="module" to the script tag.

However, this is STILL not enough. The final step is to open the JS file for the library (in my case leaderline.js) and find the main function that needs to be exported (usually somewhere near the top):

var LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"

I need LeaderLine to be available inside my scripts. To make this possible, we simply remove var and add window. in front of the function name, like this:

window.LeaderLine=function(){"use strict";var te,g,y,S,_,o,t,h,f,p,a,i,l,v="leader-line"

Now I can use the library client-side without any problems:

HTML:

<div id="start">start</div>
<div id="end">end</div>

JS

new LeaderLine(
    document.getElementById('start'),
    document.getElementById('end')
);

enter image description here

Some will argue that exposing the function to the window is too "global" for best practices. But the other option is to use module bundlers, which handle the exposing of packages, and this is overkill for many applications, especially if you're trying to whip together a quick front-end to try something out.

I find it odd that so many now publish packages in npm, that are obviously intended for the front-end (e.g. obviously nobody would use leaderline.js in back-end node, yet this is where the package was published, with no available CDN).

Given how tortuous it is to expose front-end functionality from an npm package, one can argue that today's JS ecosystem is a mess.

Cybernetic
  • 12,628
  • 16
  • 93
  • 132
1

Most of the packages on NPM are designed for server side and won't work on the client side because of security reasons. You could use NW.js, but the user would have to install your software on there computer.

"NW.js (previously known as node-webkit) lets you call all Node.js modules directly from DOM and enables a new way of writing applications with all Web technologies." http://nwjs.io/

Clay Risser
  • 3,272
  • 1
  • 25
  • 28