NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

Tutorial: NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

Questions:

  1. What is webpack & webpack-dev-server? Official documentation says it’s a module bundler but for me it’s just a task runner. What’s the difference?
  2. Where would you use browserify? Can’t we do the same with node/ES6 imports?
  3. When would you use gulp/grunt over npm + plugins?
  4. Please provide examples when you need to use a combination

Answer to NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

Answer 1: NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

Webpack and Browserify

Webpack and Browserify do pretty much the same job, which is processing your code to be used in a target environment (mainly browser, though you can target other environments like Node). The result of such processing is one or more bundles – assembled scripts suitable for the targeted environment.

For example, let’s say you wrote ES6 code divided into modules and want to be able to run it in a browser. If those modules are Node modules, the browser won’t understand them since they exist only in the Node environment. ES6 modules also won’t work in older browsers like IE11. Moreover, you might have used experimental language features (ES next proposals) that browsers don’t implement yet so running such a script would just throw errors.

Tools like Webpack and Browserify solve these problems by translating such code to a form a browser is able to execute. On top of that, they make it possible to apply a huge variety of optimizations on those bundles.

However, Webpack and Browserify differ in many ways, Webpack offers many tools by default (e.g. code splitting), while Browserify can do this only after downloading plugins but using both leads to very similar results. It comes down to personal preference (Webpack is trendier). Btw, Webpack is not a task runner, it is just a processor of your files (it processes them by so-called loaders and plugins) and it can be run (among other ways) by a task runner.


Webpack Dev Server

Webpack Dev Server provides a similar solution to Browsersync – a development server where you can deploy your app rapidly as you are working on it, and verify your development progress immediately, with the dev server automatically refreshing the browser on code changes or even propagating changed code to the browser without reloading with so-called hot module replacement.


Task runners vs NPM scripts

I’ve been using Gulp for its conciseness and easy task writing, but have later found out I need neither Gulp nor Grunt at all. Everything I have ever needed could have been done using NPM scripts to run 3rd-party tools through their API. Choosing between Gulp, Grunt, or NPM scripts depends on the taste and experience of your team.

While tasks in Gulp or Grunt are easy to read even for people not so familiar with JS, it is yet another tool to require and learn and I personally prefer to narrow my dependencies and make things simple. On the other hand, replacing these tasks with the combination of NPM scripts and (probably JS) scripts which run those 3rd party tools (eg. Node script configuring and running riprap for cleaning purposes) might be more challenging. But in the majority of cases, those three are equal in terms of their results.


Examples

NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

As for the examples, I suggest you have a look at this React starter project, which shows you a nice combination of NPM and JS scripts covering the whole build and deploy process. You can find those NPM scripts in package.json the root folder, in a property named scripts.

There you will mostly encounter commands like babel-node tools/run start. Babel-node is a CLI tool (not meant for production use), which at first compiles an ES6 file tools/run (run.js file located in tools) – basically a runner utility. This runner takes a function as an argument and executes it, which in this case is start – another utility (start.js) responsible for bundling source files (both client and server) and starting the application and development server (the dev server will be probably either Webpack Dev Server or Browsersync).

Speaking more precisely, start.js creates both client and server-side bundles, starts an express server and after a successful launch initializes Browser-sync, which at the time of writing looked like this (please refer to react starter project for the newest code).

const bs = Browsersync.create();  
bs.init({
      ...(DEBUG ? {} : { notify: false, ui: false }),

      proxy: {
        target: host,
        middleware: [wpMiddleware, ...hotMiddlewares],
      },

      // no need to watch '*.js' here, webpack will take care of it for us,
      // including full page reloads if HMR won't work
      files: ['build/content/**/*.*'],
}, resolve)

The important part is proxy.target, where they set the server address they want to proxy, which could be http://localhost:3000, and Browsersync starts a server listening on http://localhost:3001, where the generated assets are served with automatic change detection and hot module replacement. As you can see, there is another configuration property files with individual files or patterns Browser-sync watches for changes and reloads the browser if some occur, but as the comment says, Webpack takes care of watching js sources by itself with HMR, so they cooperate there.

Now I don’t have any equivalent example of such Grunt or Gulp configuration, but with Gulp (and somewhat similarly with Grunt) you would write individual tasks in gulpfile.js like

gulp.task('bundle', function() {
  // bundling source files with some gulp plugins like gulp-webpack maybe
});

gulp.task('start', function() {
  // starting server and stuff
});

where you would be doing essentially pretty much the same things as in the starter-kit, this time with task runner, which solves some problems for you, but presents its own issues and some difficulties during learning the usage, and as I say, the more dependencies you have, the more can go wrong. And that is the reason I like to get rid of such tools.

Answer 2: NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack

Webpack is a bundler. Like Browserfy it looks in the codebase for module requests (require or import) and resolves them recursively. What is more, you can configure Webpack to resolve not just JavaScript-like modules, but CSS, images, HTML, literally everything. What especially makes me excited about, you can combine both compiled and dynamically loaded modules in the same app. Thus one gets a real performance boost, especially over HTTP/1.x. How exactly you you do it I described with examples here http://dsheiko.com/weblog/state-of-javascript-modules-2017/ As an alternative for bundler one can think of Rollup.js (https://rollupjs.org/), which optimizes the code during compilation, but stripping all the found unused chunks.

For AMD, instead of RequireJS one can go with native ES2016 module system, but loaded with System.js (https://github.com/systemjs/systemjs)

Besides, I would point out that npm is often used as an automating tool like grunt or gulp. Check out https://docs.npmjs.com/misc/scripts. I personally go now with npm scripts only avoiding other automation tools, though in past I was very much into grunt. With other tools, you have to rely on countless plugins for packages, that often are not well written and are not being actively maintained. npm knows its packages, so you call any of locally installed packages by name like:

{
  "scripts": {
    "start": "npm http-server"
  },
  "devDependencies": {
    "http-server": "^0.10.0"
  }
}

Actually, you as a rule do not need any plugin if the package supports CLI.

Conclusion

I hope NPM vs. Bower vs. Browserify vs. Gulp vs. Grunt vs. Webpack Solution would be useful for you to learn something new from this solution. If it helped you then don’t forget to bookmark our site for more Quiz Answers and solutions.

Leave a Reply

Your email address will not be published.