One of the most important aspects of Yarn is determinism (predictability). The lock file ensures that the same dependencies will always be installed in the same way and order regardless of the machine for a given repository.
Even though it's still in its early stages of development, security is one of the core values on which Yarn is built. It uses checksums to verify the integrity of every package before executing its code. This also helps avoiding errors related to faulty caching or captive portals.
Further steps are also being taken to improve the security of Yarn which will be implemented in the future.
Even though it's backed by Facebook, Yarn is built as a community project first and foremost. It's completely open source and hosted on Github. It's released under a standard open source client and has its own GitHub organization and set up to work under the same governance model that other successful projects have used in the past, such as Rust and Ember.
All of this means that both existing and new contributors will always work together to improve the product and introduce new features while also keeping in mind suggestions coming from the community.
The team working on Yarn has made sure that it would work without a hitch with frameworks like React, Angular or Ember, all of which have strained the limits of npm.
With other task runners, you need to install wrapper modules for tools you may already have installed. When using NPM that's not necessary, to use the tools you need, just install them directly through NPM.
NPM scripts require fewer lines of code to run a given task. This is true even when it's for running build processes. Using Unix pipes lots of tasks can be reduced to one-liners.
While Webpack and Browserify recompile the source code using Babel, jspm is the only packager that can load prebuild/minified code downloaded from the npm registry.
It creates a packages folders which are versioned. This makes it future proof for a time where we stop bundling all the code. In the following presentation Guy Bedford calls bundling an anti-pattern.
JSPM doesn't try to hide complexity from the user. I.e. when some issue emerges you need understand a lot to be able to patch it or create a workaround.
Bundling performance is slow, though offset by the fact that bundling is not required during development, since it can load dependencies asynchronously.
A central repository provides more guarantees about the availability of the package. With requiring directly from repository urls, the entire project could potentially be taken down on a whim.
Because Jam only manages Javascript and only works on the client side, you have the assurance that any packages listed are AMD compatible for asynchronous loading.
Jam's only a front-end package manager, the rest of your server can be on a different architecture or framework. No matter what the architecture, Jam will integrate easily with it.
Volo is based around AMD, which is great for asynchronous loading, and if you try to add a non-AMD package, it will interactively ask you for its dependencies and exports.
Volo installs components directly from urls and repositories, which makes it more susceptible to components being taken down, with fewer guarantees about their availability.
Volo also allows you to provide a volofile that lets you run various tasks. Volo provides a helper object for running cross platform command line commands, and also allows you to use binaries in node_modules or create your own.
Sometimes you might require some additional commands, other than the ones Volo provides; Volo has you covered in these cases as well. The package manager is extremely extensible at its core, and can be easily modified and extended.
If you're using node.js as your backend, you gain a lot of flexibility by using the same package manager for the frontend and backend, making it much easier to share code without adding one more tool to an already large toolbase.
Npm gains a lot from its large community, and the activity from node.js gives npm the largest set of active repositories. Since so many people already use npm, chances are the library you need has already been added to npm, and many new authors are writing their libraries with npm in mind.
Browserify provides client side versions of non I/O related built in npm modules. This allows you to use the path manipulation, crypto, and zip libraries on the client side.
Browserify's documentation assumes that you have some familiarity with Node before starting to work with it. Some methods are not explained very thoroughly and others are assumed to be already known by the developer.
For example, Node's module.exports is not explained, it's just mentioned that browserify modules can be exported using it. Which is fine, but for a developer not used with Node, or a front-end engineer that has never used Node it can be confusing.
Browserify allows splitting up bundles among multiple pages to get the benefit of caching for shared, infrequently-changing modules, while still being able to use require().
Because of the nature of Browserify, it's easy to require different dependencies and concatenate them into one minified file.
This helps with performance and load times, especially for mobile devices.
npm dedupe lets you flatten the dependency tree.
Npm has a very handy dedupe tool. What this tool does is that it checks the dependency tree to find modules that depend on third dependencies. If a suitable version for all modules exists, it keeps that version and deletes any other versions that are not needed.
For example, in this dependency graph:
a
+-- b <-- depends on c@1.0.x
| -- c@1.0.3
-- d <-- depends on c@~1.0.9
-- c@1.0.10
dedupe will transform it to:
a
+-- b
+-- d
-- c@1.0.10
What it did was to make sure that both b and d got their dependency met by a single c module. It then deleted all the unneeded versions of the c module.
Browserify shim is a transformation extension for Browserify that lets you load in libraries that do not follow the Common JS structure (using an exports module). This allows you to explicitly define what globally defined variables should be exposed by a require statement so you can control how you load in these poorly formatted libraries safely without polluting the global scope.
Because the Common JS style loads in required libraries within a closure, any variables defined in a library will not pollute the global scope. Browserify shim lets you define which variables defined within that closure to map to the exports variable that Common JS expects in a safe and explicit way through declarations in your project's package.json file.
Using Webpack opens you up to npm, that has over 80k modules of which a great amount work both client-side and server-side. And the list is growing rapidly.
If you want to use a module that's not available in npm, you can still use any repository you want. Webpack can easily be configured to load modules from wherever you want. For example, to load modules from the bower_components/ folder you can do this:
module.exports = {
entry: 'app/index.js',
output: {
path: 'dist/',
filename: 'bundle.js',
},
resolve: {
modulesDirectories: ['node_modules', 'bower_components'],
},
};
Plugins and loaders are easy to write and allow you to control each step of the build, from loading and compiling CoffeeScript, LESS and JADE files to smart post processing and asset manifest building.
Webpack supports AMD and CommonJS module styles. It performs clever static analysis on the AST of your code. It even has an evaluation engine to evaluate simple expressions. This allows you to support most existing libraries.
NPM with Webpack/Browserify can handle all the dependencies for both back-end and front-end. The only place where Bower may be useful is for projects which use libraries not supported by NPM, such as Polymer.
As of May 2017 Bower has been deprecated and will not receive any updates with new features. Bugs will still be fixed though for existing projects that use Bower.
Bower is flexible enough that you can manage pretty much any package you would need on the front-end, so you can manage all your dependencies with one tool, including CSS, boilerplate, fonts and more.
Bower installs components directly from urls and repositories, which makes it more susceptible to components being taken down, with fewer guarantees about their availability.
Bower doesn't try to handle too much of the workflow process, which means it's more flexible, and can be incorporated into more workflows. It tries to just do package management well and nothing else, which is why so many workflow wrappers support it. Because it doesn't try to do too much vertical integration, it also means that the list of supported components that it manages is huge.
To create a minified bundle of all the required JS dependencies other tools need to be used.
For example a JavaScript task runner which will automatically concatenate JavaScript files and minify them will be needed. Although it's done automatically, it's still extra work because the task runner needs to be configured.
Anyone can register their package on Bower's GIT registry - on one side, this brings a lot of ease to developers, but on the other hand, this can lead to security issues because the packages are not signed.
Although npm is the largest javascript package manager, Bower is the most popular one built specifically for the front-end. With over 16000 components in its registry, pretty much every component you can think of is supported.
Because of Bower's focus on simplicity, it makes it much easier to integrate with other tools, so it has a wide range of support with workflow wrappers and task managers such as yeoman and grunt.
While nested dependencies are better for backend modules that need lots of inter-dependency, they lead to bloated file sizes. Flat dependencies are better for frontend optimization, where file size needs to be more closely managed.
You always get package directly from owner's repository, i.e. you will always get latest version as soon as its version tag is committed without need of waiting until owner publishes updated package.
Bower strives to be as simple of a package manager as possible and puts as few restrictions on the packages in the registry as possible, making it the most flexible package manager with the most potential packages.
Because Duo allows you to require dependencies directly in your html, css, and javascript, you don't need to manage annoying build processes. Duo automatically supports preprocessed languages like Coffeescript and Sass, and automatically bundles them into a single file, making it an easy-to-use, all-in-one tool. All you have to do is run duo in > out and you're done!
With Duo you don't need to manage a separate dependency file, you just require projects from your files where you need them. It works with all front-end languages, giving you powerful inline Javascript, HTML, CSS, and even JSON management in a way that no other package manager supports.
Duo allows you to use require to import packages directly from github using the username/package_name@version syntax. The version is optional, in case you want to test out a new package quickly.
Duo is primarily designed to support Component packages, but Bower package support is available with npm support planned, so you can use Duo with libraries as well as components.
Because versions and dependencies can be specified inline, it might be harder to update your packages when you want to upgrade. (However, it is possible to specify dependencies in a JSON file.)
As for common modules shared by multiple pages, duo.js cannot extract and put them into another bundle which is loaded commonly. On the other hand, modules modified rarely should put into another bundle so they can be still cached when other modules change.
Ender is another attempt at hijacking and using npm for downloading browser dependencies. But in doing so, it's using a registry and module specifications not made for the browser. This means that there will have to be some extra work to get them to work properly.
Ender allows you to expose your packages into the $ namespace, which allows you to effectively create a customized jQuery. You can provide it with the selector engine, a DOM manipulation library, and an event library of your choice, as well as extend it with additional utilities. By using micro-libraries instead of jQuery, you can get smaller file sizes and more customized utility with more flexibility.
Ender accomplishes this by allowing a package to describe its functionality with an optional javascript "bridge" file that allows it to integrate with Ender.
As opposed to Browserify, Ender has the package management portion and bundler as one. Browserify is only a bundler, meaning you need to manage packages with npm as well. Using npm is good if you have frontend and backend dependencies, as you need to use npm for the backend anyway, but not as nice if you only need to create a package for the frontend.
Ender encourages the use of smaller modules through a jQuery like object. Smaller projects benefit from being developed in parallel which can lead to faster release cycles for a single component, compared to a monolithic project like jQuery. You can also find more diverse functionality by using smaller projects.
By just using the components you need leads to a smaller file size and faster load speed. It also allows you to be more opinionated about which components you want to use, so you don't have to use an API you don't agree with just because it needs to provide backwards compatibility.
While using Github as a backend database for Component makes things a lot easier, as there's no need to add other authorization credentials to use modules, it means that modules that aren't on Github cannot be added.
Component handles more than just package management; it also deals with the build process and bundling, so you don't have to find and manage a separate solution. This lets you get up and running faster with less to worry about.
Components can be html snippets or css in addition to Javascript, and are treated as first class objects by being converted into Javascript modules that load styles and markup as strings.
Components can be javascript, style and markup, they are bundled in a way that makes it possible to load in entire UI chunks. This means less flexibility, but the components that are available are easier to work with.
Component is designed as a current-day solution for the currently proposed ES6 modules and Web Components, making it more in-line with the direction the web is going in the future.
Components are encouraged by convention to be small and single-use, meaning that the packages in the community's ecosystem are easier to use and combine together. More complex components use dependency resolution to compose smaller components so that components stay limited in scope.
Component provides you with a flat dependency tree. This results in easy dependency management. A flat dependency tree is important for file size optimization, so you don't end up loading multiple copies of the same library, or deeply nested dependencies that bloat up.
Rollup is still relatively new so it may be a bit harder to find information on how to do some things with it. In addition, that means that plugins can be a little scarce and it may be subject to minor changes as it matures.
Rollup can be expanded just like webpack and browserify through the use of plugins. Plugins can do things such as transpilation (e.g. with Babel), import data from non JS places (like JSON files), etc.
If two chunks contain the same modules, they are merged into one. This can cause chunks to have multiple parents. If a module is available in all parents of a chunk, it’s removed from that chunk. If a chunk contains all modules of another chunk, this is stored. It fulfills multiple chunks.
The module syntax addition (import x from 'xyz') is intentionally designed to be statically analyzable, which means that you cannot do dynamic imports.
Normalize has had several problems down the road which have delayed it's development. From unstable ES6 modules to custom loaders that are not ready yet.
So it's very much an unfinished work which may still requires some time to be ready for big projects.