How can I manage client-side JavaScript dependencies? [closed] - javascript
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Although there are great solutions to manage dependencies on the server side, I could not find any that satisfies all my needs to have a coherent client side JavaScript dependency management workflow. I want to satisfy these five requirements:
Manage my client-side dependencies in a format similar to npm's package.json or Bower's bower.json
It should have the flexibility to point to a Git repository or actual JavaScript files (either on web or locally) in my dependency.json file for lesser known libraries (npm let you point to Git repositories)
It should minify and namespace all libraries into a single file like Ender - that's the only JavaScript file I would need to put in my <script> tag in the client side
It should have out of box support for CoffeeScript like BoxJS4 (now dead)
In the browser, I should be able to use either require style:
var $ = require('jquery');
var _ = require('underscore');
Or better yet, do headjs style:
head.js(['jquery', 'underscore', 'mylib'], function($, _, mylib) {
// Executed when all libraries are loaded
});
If no one such single tool exists, what is the best combination of tools i.e. a tool-chain that I can combine using something like Volo (or Grunt)?
I have already researched all the tools I have linked to in here and they satisfy only up to three of my requirements at best individually.
So, please don't post again about these tools. I would only accept an answer that provides a single tool that satisfies all five of my requirements or if someone posts a concrete workflow/script/working example of a toolchain of multiple such tools that also satisfies all my requirements.
RequireJS does everything you need.
My answer to this question may help you.
Example:
Client app project hierarchy:
sampleapp
|___ main.js
|___ cs.js
|___ require.js
main.js is where you initialize your client application and configure RequireJS:
require.config({
baseUrl: "/sampleapp",
paths: {
jquery: "libs/jquery", // Local
underscore: "http://underscorejs.org/underscore-min.js", // Remote
backbone: "https://github.com/documentcloud/backbone/blob/master/backbone-min.js" // Remote on GitHub
},
shim: {
backbone: {
deps: ["underscore", "jquery"] // Backbone depends on jQuery and Underscore.js
}
}
});
require(["cs!someCoffeescriptFile", "jquery", "backbone", "underscore"], function (SomeCoffeescriptFile, $, Backbone, _) {
// Dependencies are loaded...
// Execute code
});
Dependencies will use the cs plugin when prepended by "cs!". The cs plugin compiles the CoffeeScript file.
When you go in production, you can precompile your whole project with r.js.
node ./node_modules/requirejs/bin/r.js -o buildclientconfig.js
Here are your requirements:
Manage my client side dependencies in a format similar to npm's
package.json or Bower's component.json file. Different but as good!
I should have the flexibility to point to a Git repository or the actual JavaScript files (either on web or locally) in my dependency.json file for lesser-known libraries (npm lets you point to Git repositories). Yes
It should minify and namespace all libraries into a single file like Ender. That's the only JavaScript file I would need to put in my script-tag on the client side. Yes with r.js.
It should have out of box support for CoffeeScript, like Box. Yes
In the browser I can use either require style or headjs. Yes
RequireJS is the one you are looking for, I believe.
As Guillaume86, I think Hem will get you the closest to where you want to be.
In Hem, dependencies are managed using a combination of npm and Hem. Use npm
to explicitly install all of your projects external dependencies. Use Hem to specify which dependencies (both external and local) should be stitched together for you client side operations.
I created a skeleton project of this, so you can see how this would work. You can see it at Client-side Hem.
Adding dependencies
Use npm to search for a specific dependency and then modify the package.json file to ensure that the dependency is tracked in the future. Then specify the
dependency for your application in slug.json.
For example, suppose you wanted to add the CoffeeScript dependency. Just use npm to install the dependency and save it to your package.json file:
npm --save install coffee-script
Manually edit the slug.json file. Add "coffee-script" to "dependencies".
Suppose you wanted to include your own module 'bloomfilters' and it wasn't in the npm registry. You could add it to your project in the following way:
npm --save install https://github.com/dsummersl/bloomfilters/tarball/master
Manually edit the slug.json file. Add "bloomfilters" to "dependencies".
Local modules
If you want to include your own CoffeeScript or JavaScript code, you can do so by adding those files to the app/ folder. Note that in order to expose your script via the 'require' method you must make it a CommonJS module. It is very simple—see the Hem documentation.
Local files
If you want to include non-CommonJS non 'require' code, you can also stitch that by referencing your custom JavaScript or CoffeeScript code via the 'libs' list in
file slug.json.
CSS
Hem will stitch together your CSS too, if you want. See the Hem documentation.
Building
Once you have your dependencies listed, you can use hem to stitch them all together.
# Make sure all dependencies are present:
npm install .
# Make public/application.js
hem build
# See your minified js in public/application.js
Notes
Hem was meant for the Spine.js project - but you don't have to use it for that. Ignore any documentation mentioning spine as you wish...
There is also Browserify.
supports the package.json format
uses npm underneath which can use a GitHub (or any Git) repository as a package source
minifies and concatenates all dependencies into a single file.
supports CoffeeScript if you include it in your dependencies
require style all the way.
supports source maps
I'm pretty sure Hem meets your requirements (I use a personal fork with additional compilers, Jade and Stylus. It's easy to customize to your needs). It uses npm to manage dependencies.
You might want to take a look at Yeoman, which uses several techniques to help you with your requirements.
Our workflow is comprised of three tools for improving your
productivity and satisfaction when building a web app: Yo (the
scaffolding tool), Grunt (the build tool) and Bower (for package
management).
Built-in support for CoffeeScript, Compass and more. It works with r.js (RequireJS), unit testing, etc.
As for your requirements:
Bower is used for dependency management
Bower can work with local files, git://, http:// and more
Built-in support for minification and concatenation (even for your images)
Built-in support to automatically compile CoffeeScript and Compass (with LiveReload)
As stated in the build process: if you're using AMD, I will pass those modules through r.js so you don't have to.
All features:
Lightning-fast scaffolding — Easily scaffold new projects with
customizable templates (e.g HTML5 Boilerplate, Twitter Bootstrap),
RequireJS and more.
Great build process — Not only do you get
minification and concatenation; I also optimize all your image files,
HTML, compile your CoffeeScript and Compass files, if you're using
AMD, I will pass those modules through r.js so you don't have to.
Automatically compile CoffeeScript & Compass — Our LiveReload watch
process automatically compiles source files and refreshes your browser
whenever a change is made so you don't have to.
Automatically lint your scripts — All your scripts are automatically run against JSHint to ensure they're following language best-practices.
Built-in preview server — No more having to fire up your own HTTP Server. My built-in
one can be fired with just one command.
Awesome Image Optimization — I optimize all your images using OptiPNG and JPEGTran so your users can spend less time downloading assets and more time using your app.
Killer package management — Need a dependency? It's just a keystroke
away. I allow you to easily search for new packages via the
command-line (e.g. bower search jquery), install them and keep them
updated without needing to open your browser.
PhantomJS Unit Testing — Easily run your unit tests in headless WebKit via PhantomJS. When
you create a new application, I also include some test scaffolding for
your app.
Bower may suit your needs (1). And (2) for the rest you have RequireJS.
From the README:
Bower is a package manager for the web. Bower lets you easily install assets such as images, CSS and JavaScript, and manages dependencies for you.
To install a package:
bower install jquery
bower install git://github.com/maccman/package-jquery.git
bower install http://code.jquery.com/jquery-1.7.2.js
bower install ./repos/jquery
I just came across inject.js
Some of the features, from the project site:
Inject (Apache Software License 2.0) is a revolutionary way to manage your dependencies in a Library Agnostic way. Some of its major features include:
CommonJS Compliance in the Browser (exports.*)
View the full CommonJS Support Matrix
Cross domain retrieval of files (via easyXDM)
localStorage (load a module once)
Look at the Jam package manager. Following is the description from its homepage
For front-end developers who crave maintainable assets, Jam is a package manager for JavaScript. Unlike other repositories, we put the browser first.
It seems a lot similar to npm in how it works.
Install the package like below:
jam install backbone
Keep the packages up-to-date by executing:
jam upgrade
jam upgrade {package}
Optimize packages for production
jam compile compiled.min.js
Jam dependencies can be added in package.json file.
For complete documentation, read the Jam documentation.
There are a couple of options:
Browserify which allows you to import modules
RequireJS addresses the same problem
One that seems to be in active development is JoinJS
Component might also be of interest. It does not manage dependencies per se, but it allows you to use chopped up versions of otherwise large libraries.
Here's a solution that takes a very different approach: package up all the modules into a JSON object and require modules by reading and executing the file content without additional requests.
Pure client-side demo implementation: http://strd6.github.io/editor/
https://github.com/STRd6/require/blob/master/main.coffee.md
STRd6/require depends on having a JSON package available at runtime. The require function is generated for that package. The package contains all the files your app could require. No further HTTP requests are made because the package bundles all dependencies. This is as close as one can get to the Node.js style require on the client.
The structure of the package is as follows:
entryPoint: "main"
distribution:
main:
content: "alert(\"It worked!\")"
...
dependencies:
<name>: <a package>
Unlike Node.js a package doesn't know its external name. It is up to the package including the dependency to name it. This provides complete encapsulation.
Given all that setup here's a function that loads a file from within a package:
loadModule = (pkg, path) ->
unless (file = pkg.distribution[path])
throw "Could not find file at #{path} in #{pkg.name}"
program = file.content
dirname = path.split(fileSeparator)[0...-1].join(fileSeparator)
module =
path: dirname
exports: {}
context =
require: generateRequireFn(pkg, module)
global: global
module: module
exports: module.exports
PACKAGE: pkg
__filename: path
__dirname: dirname
args = Object.keys(context)
values = args.map (name) -> context[name]
Function(args..., program).apply(module, values)
return module
This external context provides some variable that modules have access to.
A require function is exposed to modules so they may require other modules.
Additional properties such as a reference to the global object and some metadata are also exposed.
Finally we execute the program within the module and given context.
This answer will be most helpful to those who wish to have a synchronous Node.js style require statement in the browser and are not interested in remote script loading solutions.
I use Hem with npm, and I wanted to add some additional benefits that I think weren't covered so far.
Hem has a self-contained web server (Strata) so you can develop your code without even needing to recompile. I never use hem build unless I am publishing an application.
You don't need to use Spine.js to use Hem. You can use it to compile arbitrary CoffeeScript packages if you set up file slug.json correctly. Here's one of my packages that is auto-compiled with cakefile:
TurkServer
Speaking of the above, Hem allows you to link other dependencies on your local system in with an npm link and combines them seamlessly even when you are using the Strata server. In fact, you needn't even use the cake method above; you can just link directly to CoffeeScript from dependent projects.
Hem supports eco (embedded CoffeeScript) for views and Stylus for CSS, and compiles all that, along with your CoffeeScript code, into one JavaScript file and one CSS file.
Here's a basic list for getting set up with a Spine.js, Hem, and CoffeeScript application. Feel free to ignore the Spine.js parts. In fact, sometimes I use spine app to set up a directory structure for a non-Spine.js application, then edit file slug.json to change to a different compilation structure.
Install NPM: curl http://npmjs.org/install.sh | sh on a Unix-like system. I'll assume it's available from the command line.
Install Hem globally (npm install -g hem). Development has branched as of late, so you might want to get it straight out of GitHub, checkout a branch, and npm install -g . in that folder.
npm install -g spine.app will make spine available as a global command
spine app folder will make a Spine project called app in folder, generating the right directory structure and a bunch of skeleton files to get started.
cd to folder and edit file dependencies.json for the libraries you need. Add them to file slug.json, so that Hem knows where to find them as well.
Optional: npm link any of your local packages in development to folder node_modules, and you can add them to file slug.json for Hem (either an index.js file to include directly or an index.coffee file if you want hem to compile it.)
npm install . to download all the dependencies you just entered in.
If you take a look at the default spine configuration, there is a app/lib/setup.coffee where you require all the libraries you need from your dependencies. Examples:
# Spine.app had these as dependencies by default
require('json2ify')
require('es5-shimify')
require('jqueryify')
require('spine')
require('spine/lib/local')
require('spine/lib/ajax')
require('spine/lib/manager')
require('spine/lib/route')
# D3.js was installed via file 'dependencies.json'
require 'd3/d3.v2'
In file index.coffee, you just do require lib/setup and load the main controller for your application. In addition, you need to do require on any other classes in those other controllers. You can use spine controller something or spine model something to generate templates for controllers and models. A typical Spine controller looks like the following, using Node.js' require:
Spine = require('spine')
# Require other controllers
Payment = require('controllers/payment')
class Header extends Spine.Controller
constructor: ->
# Initialize the class
active: ->
super
#render()
render: ->
# Pull down some eco files
#html require('views/header')
# Makes this visible to other controllers
module.exports = Header
The default generated index.html file will usually be fine for loading your application, but modify as necessary. Per your requirements, it only pulls in one .js and one .css file, which you never need to modify.
Edit your stylus files as necessary in the css folder. It's a lot more flexible than CSS :)
From folder, run hem server to start a Hem server, and navigate to localhost:9294 to see your application (if you installed Hem globally). It has some hidden arguments, for example, --host 0.0.0.0 listens on all ports.
Build the rest of your application using proper MVC techniques, and use stylus for CSS and eco for views. Or don't use Spine at all, and Hem will still work great with CoffeeScript and npm. There are many examples of projects using both models.
One more thing: normally, hem server will update automatically as you update your code and save files, which makes it a cinch to debug. Running hem build will compile your application into two files, application.js, which is minified and application.css. If you run hem server after this, it will use those files and no longer update automatically. So don't hem build until you actually need a minified version of your application for deployment.
Additional references: Spine.js and Hem: Getting started
Check out Cartero if you are using Node.js or Express.js on the backend.
I'd suggest to check out the Dojo Toolkit which seems to meet most of your requirements. The one I'm not sure about is CoffeeScript.
Dojo works with modules written in the Asynchronous Module Definition (AMD) format. It has a build system with packages and you can aggregate them in one or several files (called layers). Apparently it accepts Git type repositories, and more details on the build system are on Creating Builds.
For the record, v1.9 beta is expected next month.
Dependency injection with asynchronous loading and Browserify will be another good choice, compares to RequireJS.
asynchronous-frontend-dependency-management-without-AMD
Another framework that satisfies all my criteria released recently is http://duojs.org/ (and it also supports treating other resources, like CSS, as dependencies).
Related
Including/bundling dependencies in npm library with webpack
I've used webpack for a few single page apps and am now trying to build an npm library to be used by some of those apps (and anyone else who might find it useful.) I understand that peerDependencies in package.json and externals in the webpack config go together. If I'm writing an AngularJS plugin, I don't bundle angular, because the consumer should already have it installed and we want to work with whatever version they're using. Where I'm confused is on how to include another library I don't expect the consumer to have. If I list it in dependencies and import it and don't include it in externals, webpack seems to bundle the other library with my code. I don't think this is what I want. If I list it in dependencies and do include it in externals, it seems not to be available in the consumer unless I explicitly include it in the consumer, e.g. a script tag pointing to a CDN. It acts like a peerDependency, even though it isn't. Is it possible to have have my library's dependencies installed by npm in the consumer app and available at runtime without a) bundling the dependency into my library or b) forcing consumers of the library to explicitly load an obscure package?
Publish Aurelia component on NPM?
We have built a small-ish application using Aurelia, and would like to be able to integrate the app into a larger codebase. For example, it may be desirable to publish the Aurelia app on NPM, so other projects could integrate our code. How can we build/publish the Aurelia app, so that it can be instantiated in a larger JavaScript application?
Typically, you wouldn't publish an entire Aurelia application to NPM, rather you would push plugins to NPM. The simplest way to learn how to do this is to follow the example of the various Aurelia repos. We build the code in to multiple formats, but the most important are AMD and CommonJS (which is more important for your company is dependent on what tooling your company is using). Once you've built the code, the next step is to make sure your package.json file is set up correctly. It's best to copy the example of what we're doing in our own repos. I would start by looking at either the dialog plugin or the templating-resources plugin. Both of these show good examples of how to publish your Aurelia plugin to NPM, whether it is a public or private npm feed. https://github.com/aurelia/dialog/blob/master/package.json https://github.com/aurelia/templating-resources/blob/master/package.json Both of these plugins are set up to support Webpack, JSPM/SystemJS, and the Aurelia CLI out of the box.
I totally agree with #Ashley in not publishing larger applications to the global NPM registry. The big advantage of it is the simplicity of all that small packages which can be used to build large applications. If you feel you got some reusable code, put in an own package and publish it. Anyway, to give you an answer which does not require you to publish your complete app: you can include a complete repository (which is probobly what you are lookig for) in a different application via NPM. npm install git://github.com/somegit/hubrepo.git Or directly via the package.json: "dependencies": { "private-repo": "git+ssh://git#github.com:somegit/hubrepo.git#v1.0.0", } You can also do something similiar e.g. using JSPM. This would be simply: jspm install your-app=github:OrgOrUser/your-app#your-branch If you are facing long relative paths in your imports now, depending on your tooling, you may be interested in something like e.g. Resolving require paths with webpack which shows how to alias relative paths. Sources/Links: How to install a private NPM module without my own registry? npm install private github repositories by dependency in package.json
Do I need to keep a copy of js library in lib or vendor folder though already installed using npm?
Question 1 : I am installing my project dependency libraries using npm and it gets stored in the npm_modules folder. Is it necessary to keep the copy of library like angular.js,angular-route.js in lib folder or vendor folder? I could see few people are using lib folder or vendor folders to store the library in the permanent manner. I am confused by seeing this. Question 2: Do I need to copy/paste the node_modules folder to production or just run the npm install command on the project folder's command prompt to install all the dependencies in production. How does a dependency library get promoted to production? Thank you kindly for your advice.
It all depends on how you need to deploy your site to production, really. Ultimately, you will probably want to bundle all your JS files into one or a few files, which are minified and sent with gzip compression. How you bundle them is up to you. There are quite a few options: Browserify Webpack Grunt / gulp build process And many more besides As to whether you need to keep a copy of these bundled javascript files under version control, well I think that boils down to 1 key question: can you run a build process (such as one of the tools using NodeJS) on the production server, or on a build server that creates a zip file or installer? If so, then you don't need to include them, just get the build server or production server to check out the latest copy from version control, npm install and then run the build process. But if the best you could do is have the production server check files out from source control, then you would want to include the final versions of the files to use in the repository. Keeping generated files, such as your bundled javascript files, in your source control repo should be avoided where possible. Because otherwise, every commit has to contain the changes to the source files, and the corresponding change to the generated files as well. And the latter is just noise, and has to be ignored by every developer looking at a diff/patch for a commit.
Creating bower projects that have dependencies
I am creating a javascript client side library which I will make available via Bower and depends on two other libraries, one that is available via Bower (https://github.com/abritinthebay/datejs) and another that is available only via npm (https://github.com/fent/randexp.js). I am concerned about how the users of my library would go about using it. My doubts and fears are: how can I declare the second library as a dependency of my library when it's only available via npm? after the user installs my library, will he/she have to be aware of the dependencies and manually include the corresponding javascript files in their index.html? I am aware of grunt-bower-install solving this issue, but I'm concerned about people who don't even use grunt at all. would it be so bad if I just gave up on all of this and included the code of said libraries in my own code? (bonus round): I want my library to be available as an AngularJS service, as a node.js module, and as a 'normal' javascript function. Is there a way for me to achieve this using only one repository or do I have to create 3 separate projects?
1) You need to wrap the second library in a bower package if you want it to be available to the bower package management system. npm is something entirely different and you won't be sharing between the two directly. 2) Yes, the user needs to ensure the dependencies are loaded in the right order on each page. Bower just ensures your dependencies are installed and at the correct version. 3) Generally, I'd avoid this. They're separate projects with orthogonal concerns. This is why we've created package managers like bower to begin with. Bonus: 4) Yes, you can achieve this with one repository. Each package management service requires their own configuration files - but there's nothing wrong with having a bower.json and a package.json both sitting at the root of your repository. You just use npm and bower separately and respectively to publish to each system. PS. This should have been more than 1 question.
What is the difference between Bower and npm?
What is the fundamental difference between bower and npm? Just want something plain and simple. I've seen some of my colleagues use bower and npm interchangeably in their projects.
All package managers have many downsides. You just have to pick which you can live with. History npm started out managing node.js modules (that's why packages go into node_modules by default), but it works for the front-end too when combined with Browserify or webpack. Bower is created solely for the front-end and is optimized with that in mind. Size of repo npm is much, much larger than bower, including general purpose JavaScript (like country-data for country information or sorts for sorting functions that is usable on the front end or the back end). Bower has a much smaller amount of packages. Handling of styles etc Bower includes styles etc. npm is focused on JavaScript. Styles are either downloaded separately or required by something like npm-sass or sass-npm. Dependency handling The biggest difference is that npm does nested dependencies (but is flat by default) while Bower requires a flat dependency tree (puts the burden of dependency resolution on the user). A nested dependency tree means that your dependencies can have their own dependencies which can have their own, and so on. This allows for two modules to require different versions of the same dependency and still work. Note since npm v3, the dependency tree will be flat by default (saving space) and only nest where needed, e.g., if two dependencies need their own version of Underscore. Some projects use both: they use Bower for front-end packages and npm for developer tools like Yeoman, Grunt, Gulp, JSHint, CoffeeScript, etc. Resources Nested Dependencies - Insight into why node_modules works the way it does
This answer is an addition to the answer of Sindre Sorhus. The major difference between npm and Bower is the way they treat recursive dependencies. Note that they can be used together in a single project. On the npm FAQ: (archive.org link from 6 Sep 2015) It is much harder to avoid dependency conflicts without nesting dependencies. This is fundamental to the way that npm works, and has proven to be an extremely successful approach. On Bower homepage: Bower is optimized for the front-end. Bower uses a flat dependency tree, requiring only one version for each package, reducing page load to a minimum. In short, npm aims for stability. Bower aims for minimal resource load. If you draw out the dependency structure, you will see this: npm: project root [node_modules] // default directory for dependencies -> dependency A -> dependency B [node_modules] -> dependency A -> dependency C [node_modules] -> dependency B [node_modules] -> dependency A -> dependency D As you can see it installs some dependencies recursively. Dependency A has three installed instances! Bower: project root [bower_components] // default directory for dependencies -> dependency A -> dependency B // needs A -> dependency C // needs B and D -> dependency D Here you see that all unique dependencies are on the same level. So, why bother using npm? Maybe dependency B requires a different version of dependency A than dependency C. npm installs both versions of this dependency so it will work anyway, but Bower will give you a conflict because it does not like duplication (because loading the same resource on a webpage is very inefficient and costly, also it can give some serious errors). You will have to manually pick which version you want to install. This can have the effect that one of the dependencies will break, but that is something that you will need to fix anyway. So, the common usage is Bower for the packages that you want to publish on your webpages (e.g. runtime, where you avoid duplication), and use npm for other stuff, like testing, building, optimizing, checking, etc. (e.g. development time, where duplication is of less concern). Update for npm 3: npm 3 still does things differently compared to Bower. It will install the dependencies globally, but only for the first version it encounters. The other versions are installed in the tree (the parent module, then node_modules). [node_modules] dep A v1.0 dep B v1.0 dep A v1.0 (uses root version) dep C v1.0 dep A v2.0 (this version is different from the root version, so it will be an nested installation) For more information, I suggest reading the docs of npm 3
TL;DR: The biggest difference in everyday use isn't nested dependencies... it's the difference between modules and globals. I think the previous posters have covered well some of the basic distinctions. (npm's use of nested dependencies is indeed very helpful in managing large, complex applications, though I don't think it's the most important distinction.) I'm surprised, however, that nobody has explicitly explained one of the most fundamental distinctions between Bower and npm. If you read the answers above, you'll see the word 'modules' used often in the context of npm. But it's mentioned casually, as if it might even just be a syntax difference. But this distinction of modules vs. globals (or modules vs. 'scripts') is possibly the most important difference between Bower and npm. The npm approach of putting everything in modules requires you to change the way you write Javascript for the browser, almost certainly for the better. The Bower Approach: Global Resources, Like <script> Tags At root, Bower is about loading plain-old script files. Whatever those script files contain, Bower will load them. Which basically means that Bower is just like including all your scripts in plain-old <script>'s in the <head> of your HTML. So, same basic approach you're used to, but you get some nice automation conveniences: You used to need to include JS dependencies in your project repo (while developing), or get them via CDN. Now, you can skip that extra download weight in the repo, and somebody can do a quick bower install and instantly have what they need, locally. If a Bower dependency then specifies its own dependencies in its bower.json, those'll be downloaded for you as well. But beyond that, Bower doesn't change how we write javascript. Nothing about what goes inside the files loaded by Bower needs to change at all. In particular, this means that the resources provided in scripts loaded by Bower will (usually, but not always) still be defined as global variables, available from anywhere in the browser execution context. The npm Approach: Common JS Modules, Explicit Dependency Injection All code in Node land (and thus all code loaded via npm) is structured as modules (specifically, as an implementation of the CommonJS module format, or now, as an ES6 module). So, if you use NPM to handle browser-side dependencies (via Browserify or something else that does the same job), you'll structure your code the same way Node does. Smarter people than I have tackled the question of 'Why modules?', but here's a capsule summary: Anything inside a module is effectively namespaced, meaning it's not a global variable any more, and you can't accidentally reference it without intending to. Anything inside a module must be intentionally injected into a particular context (usually another module) in order to make use of it This means you can have multiple versions of the same external dependency (lodash, let's say) in various parts of your application, and they won't collide/conflict. (This happens surprisingly often, because your own code wants to use one version of a dependency, but one of your external dependencies specifies another that conflicts. Or you've got two external dependencies that each want a different version.) Because all dependencies are manually injected into a particular module, it's very easy to reason about them. You know for a fact: "The only code I need to consider when working on this is what I have intentionally chosen to inject here". Because even the content of injected modules is encapsulated behind the variable you assign it to, and all code executes inside a limited scope, surprises and collisions become very improbable. It's much, much less likely that something from one of your dependencies will accidentally redefine a global variable without you realizing it, or that you will do so. (It can happen, but you usually have to go out of your way to do it, with something like window.variable. The one accident that still tends to occur is assigning this.variable, not realizing that this is actually window in the current context.) When you want to test an individual module, you're able to very easily know: exactly what else (dependencies) is affecting the code that runs inside the module? And, because you're explicitly injecting everything, you can easily mock those dependencies. To me, the use of modules for front-end code boils down to: working in a much narrower context that's easier to reason about and test, and having greater certainty about what's going on. It only takes about 30 seconds to learn how to use the CommonJS/Node module syntax. Inside a given JS file, which is going to be a module, you first declare any outside dependencies you want to use, like this: var React = require('react'); Inside the file/module, you do whatever you normally would, and create some object or function that you'll want to expose to outside users, calling it perhaps myModule. At the end of a file, you export whatever you want to share with the world, like this: module.exports = myModule; Then, to use a CommonJS-based workflow in the browser, you'll use tools like Browserify to grab all those individual module files, encapsulate their contents at runtime, and inject them into each other as needed. AND, since ES6 modules (which you'll likely transpile to ES5 with Babel or similar) are gaining wide acceptance, and work both in the browser or in Node 4.0, we should mention a good overview of those as well. More about patterns for working with modules in this deck. EDIT (Feb 2017): Facebook's Yarn is a very important potential replacement/supplement for npm these days: fast, deterministic, offline package-management that builds on what npm gives you. It's worth a look for any JS project, particularly since it's so easy to swap it in/out. EDIT (May 2019) "Bower has finally been deprecated. End of story." (h/t: #DanDascalescu, below, for pithy summary.) And, while Yarn is still active, a lot of the momentum for it shifted back to npm once it adopted some of Yarn's key features.
2017-Oct update Bower has finally been deprecated. End of story. Older answer From Mattias Petter Johansson, JavaScript developer at Spotify: In almost all cases, it's more appropriate to use Browserify and npm over Bower. It is simply a better packaging solution for front-end apps than Bower is. At Spotify, we use npm to package entire web modules (html, css, js) and it works very well. Bower brands itself as the package manager for the web. It would be awesome if this was true - a package manager that made my life better as a front-end developer would be awesome. The problem is that Bower offers no specialized tooling for the purpose. It offers NO tooling that I know of that npm doesn't, and especially none that is specifically useful for front-end developers. There is simply no benefit for a front-end developer to use Bower over npm. We should stop using bower and consolidate around npm. Thankfully, that is what is happening: With browserify or webpack, it becomes super-easy to concatenate all your modules into big minified files, which is awesome for performance, especially for mobile devices. Not so with Bower, which will require significantly more labor to get the same effect. npm also offers you the ability to use multiple versions of modules simultaneously. If you have not done much application development, this might initially strike you as a bad thing, but once you've gone through a few bouts of Dependency hell you will realize that having the ability to have multiple versions of one module is a pretty darn great feature. Note that npm includes a very handy dedupe tool that automatically makes sure that you only use two versions of a module if you actually have to - if two modules both can use the same version of one module, they will. But if they can't, you have a very handy out. (Note that Webpack and rollup are widely regarded to be better than Browserify as of Aug 2016.)
Bower maintains a single version of modules, it only tries to help you select the correct/best one for you. Javascript dependency management : npm vs bower vs volo? NPM is better for node modules because there is a module system and you're working locally. Bower is good for the browser because currently there is only the global scope, and you want to be very selective about the version you work with.
My team moved away from Bower and migrated to npm because: Programmatic usage was painful Bower's interface kept changing Some features, like the url shorthand, are entirely broken Using both Bower and npm in the same project is painful Keeping bower.json version field in sync with git tags is painful Source control != package management CommonJS support is not straightforward For more details, see "Why my team uses npm instead of bower".
Found this useful explanation from http://ng-learn.org/2013/11/Bower-vs-npm/ On one hand npm was created to install modules used in a node.js environment, or development tools built using node.js such Karma, lint, minifiers and so on. npm can install modules locally in a project ( by default in node_modules ) or globally to be used by multiple projects. In large projects the way to specify dependencies is by creating a file called package.json which contains a list of dependencies. That list is recognized by npm when you run npm install, which then downloads and installs them for you. On the other hand bower was created to manage your frontend dependencies. Libraries like jQuery, AngularJS, underscore, etc. Similar to npm it has a file in which you can specify a list of dependencies called bower.json. In this case your frontend dependencies are installed by running bower install which by default installs them in a folder called bower_components. As you can see, although they perform a similar task they are targeted to a very different set of libraries.
For many people working with node.js, a major benefit of bower is for managing dependencies that are not javascript at all. If they are working with languages that compile to javascript, npm can be used to manage some of their dependencies. however, not all their dependencies are going to be node.js modules. Some of those that compile to javascript may have weird source language specific mangling that makes passing them around compiled to javascript an inelegant option when users are expecting source code. Not everything in an npm package needs to be user-facing javascript, but for npm library packages, at least some of it should be.