From Requirejs to Webpack, the old and the new…

requirejswebpack

 

As you already figured out by the title, this post will try to show you why I and my team decided to move from requirejs to webpack. They are both widely used and requirejs is clearly the oldest of the two, hence, this is somehow comparing the old with the new.

And, for me at least, in this case, old doesn’t mean gold :). Don’t get me wrong, requirejs was a great library when it was built and set the standards for many of the similar bundlers that came after, like webpack.

But in my experience requirejs is not dealing well with how new web applications are evolving, and I’ll try to explain, according to my experience using the tool, why we decided to move to webpack.

Why move:

Well, we first started thinking about moving from requirejs to webpack after we started extracting modules from a big application we had into separate npm modules. Because requirejs doesn’t import node modules, we had to start “hacking” and we installed our private npm modules into a folder inside the source path of our application so that they could be bundled by requirejs.

Well this has a lot of problems, first we don’t want a separate folder inside our source folder just to have external dependencies imported by requirejs. Second, if any of these modules has a dependency on a module that is already installed in the outer “primary” node_modules folder you would end up with that dependency being installed twice.

Webpack was built to support NPM modules, so you don’t have to worry about placing node modules inside the application source folder.

Requirejs follows the AMD (Asynchronous Module Definition) proposal, which for anyone used to work with node and CJS (CommonJS) modules can be annoying. They provide a way to convert CJS into AMD, but is really not flexible, and you have to follow specific steps to make it work, and really why should we care about that anyway, it should be transparent to us.

Webpack supports both AMD and CJS, so you don’t have to worry about converting AMD to CJS or vice versa, it just works. You might think that this is not a big deal, but when you think that you can use any nodejs library in the browser out of the box, things start to get exciting.

Another problem with requirejs is the loaders plugins. I really don’t want to explicitly have to do something like this:

define(['css!styles/cssfile'], function() { /* .. */})

Applying processors explicitly is not a good idea, it should be a responsibility of the bundler to detect different types of files and process them in the background, and it should be transparent to you.

Webpack loaders are really amazing, configuring the loaders is really simple and the overall plugin system is more robust. Also, ES6 support is very easy to add with the babel-loader in webpack, while making ES6 to function in requirejs is a little bit of a battle.

Conclusion:

For all this, we decided to take the hit of converting a big application from requirejs to webpack, but I think it is the right thing to do and will undoubtedly pay off in the future.

 

 

Advertisements

TeamCity vs Jenkins, an overview.

TeamCity and Jenkins are two of the most used CI’s out there, and having used both of them I have a pretty solid idea of the pros and cons of each one and I’ll list some of them in this post according to my experience using both products.

Jenkins:jenkins

Jenkins was the first CI I’ve used and I must admit is a really good product, even more when you think that is an open source project and you don’t have to pay anything to use it.

Pros:

  • Very easy to use.
  • Backed up by a huge community.
  • Lots of plugins to choose from.
  • Open source.

Cons:

  • Some server instability (at least when installed in a windows machine).
  • Outdated interface.
  • Node js plugin doesn’t work on windows machine installations yet (This was the main reason for me to start using TeamCity 🙂 )

So if your an opensource enthusiast this might be the right tool for you. It’s a very mature product with lots of plugins providing all the heavy lifting for you and an enormous community to help you as well.

 

TeamCity:

tc

TeamCity developed by JetBrains is the CI I now use the most. Although the reason for me to start using TeamCity wasn’t at first related to its features, I’m glad I choose to use TeamCity. The simplicity and ease of usage caught my attention from the first day.

Although being a commercial product, meaning you have to pay for it, you have 20 builds and 3 free agent installations, which should be enough for you to start using it and show the business guys how awesome it is, so you can ask for the license purchase :). Also, if you work on a startup you get 50% discount, and if you’re working on an open source project the license is free.

Pros:

  • Very easy to install and maintain.
  • Lots of plugins to choose from.
  • Multi-platform builds.
  • Excellent backup functionality.
  • Excellent source control support.

Cons:

  • Free edition limited to 20 builds.
  • Built in Java, meaning that if you want to create your own plugin you have to know java.

 

Having used both of them, and still use them both in my current company, I tend to prefer TeamCity over Jenkins mainly because TeamCity is so easy to use and it behaves better under node js deployments, which gives it a bit of an edge over Jenkins, not to mention the ancient Jenkins interface :).

But don’t understand me wrong, Jenkins is an awesome CI and should be always considered as a viable option.

A Gulp set up suited for most javascript projects

One of the most important things to think about when starting a new javascript project is which building tasks we want to create and automate to make sure we increase our development speed. This might not sound like a big thing, but it becomes evident when you think that a big portion of your time is spent doing building related tasks, like running unit tests, bundling components, transpiling less files, linting and so on.

I’ve done this process quite a few times now and I think I managed to get a pretty good automated building setup which definitely increases our productivity.

Depending on the javascript project you’re doing some of the tasks will vary. But I’ll explain that later.

But more to the point, if you’re thinking of starting a new React, Knockout, Angular or any of the fancy javascript libraries/frameworks projects, these are the bare minimum tasks you’ll have to automate:

  • Unit tests
    • Karma, webcomponents-tester and so on. This assumes you’re a TDD oriented developer, as you should 😉
  • Local development server
    • Local server that you’re going to use to test your application
  • Bundling
    • Bundles your application into small sized files for browser performance purposes.
  • Linting
    • To make sure your code doesn’t have errors or potential problems.
  • File Minification
    • To minify javascript, css and html files. This is normally an option on the bundling library, but for the sake of clarity I separate those.

These are, for me, the minimum building tasks every javascript project should have.

I’ll go through each one of them now, giving my preference about the library I normally use.

Unit tests:

Unit tests are one the most important parts of your application. They ensure your code does what is supposed to do and give you confidence to change your code.

If you’re not using a webcomponents library, my first choice to optimize your tests is Karma. Karma is maintained by the AngulaJs team, and it allows you to run your unit tests in an automated fashion.

gulp-karma is my favorite gulp task for this. It’s very simple to set up.

var gulp = require('gulp'); 
var Server = require('karma').Server; 

/* Run test once and exit  */ 

gulp.task('test', function (done) { 
            new Server(
                      { 
                         configFile: __dirname + '/karma.conf.js', 
                         singleRun: true 
                      }, 
                      done).start(); 
});

This code will run all your tests on your application. You can see more in the karma GitHub page. Combine karma with jasmine or mocha and you have all you need to unit test your application.

If you’re using webcomponents the web-component-tester library is the one to go. It was built by google for Polymer, but it can be used with other frameworks like x-tag and so on.

Local development server:

This is an absolute must have in every project. If you don’t want to spend all your time doing a release every time you change your code, a fast local development server is obligatory.

You have several options here, if you’re using webpack as your bundler, the webpack dev server is the best choice, is easy to configure and the hot module replacement is a very cool functionality. You can see more clicking here.

If you’re using requirejs or other bundlers, gulp-connect is one of my favorites. Is essentially a gulp plugin that allows you to use a webserver.

Bundling:

Modern web applications should be fast and responsive, and choosing the most suited bundler for your project goes a long way to achieve it. It helps to shrink  your application into one or more small chunks so that you can load them when your browser needs them. It also helps your application access node js libraries that would normally not work in the browser, only on the server.

Depending on the type of project you have, several options are available.

Requirejs is one of the oldest bundlers around and is still very used today. Although very good, I personally prefer webpack or browserify for the same type of projects. They are easy to set up, and webpack is so powerful that if you want you can basically substitute your gulp tasks with webpack plugins.

Webpack and browserify have the added benefit of allowing you to use node js libraries in the browser.

To see how you can use webpack with gulp click here, and for browserify click here.

If you’re using webcomponents the best and, as of the time of writing this post, the only bundler that supports html imports in an efficient manner is vulcanize developed by google for Polymer, but it works with other frameworks like x-tag and so on.

Linting: 

This is a very useful task to have if you don’t want to spend lots of time correcting errors in your javascript and doing potentially harm code.

gulp-jshint is perhaps my favorite due to the complete set of options you can use to configure it. You can also choose from a set of different reporters so you can choose the one you like the most.

var jshint = require('gulp-jshint');
var gulp   = require('gulp');

gulp.task('lint', function() {
  return gulp.src('./lib/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('YOUR_REPORTER_HERE'));
});

File Minification:

This is essential if you want to keep your release files small. Minifying html, css and javascript files can be done with several libraries, and bundlers like webpack or browserify can be set up with their own minification options.

But if you want to separate those tasks into different gulp tasks you can use gulp-cssnano, gulp-htmlmin and gulp-minify to minify css, html and javascript files respectively.

 

Conclusion:

These are, for me, the bare minimum tasks you should have to automate/streamline your building process.

All these tasks can be done using grunt as well, but I prefer gulp because it’s more javascript-ish like 🙂