A couple of weeks ago I did a post on packaging research code. While talking about web-based research projects, I concluded with the following paragraph:
There are a lot of newer (relatively speaking) projects out there that let you easily package code involving web applications and make them ready for deployment on other machines.
I felt that I didn’t do quite the justice in explaining this part and skipped over a lot of good stuff.
I am sure that you too, like me, would have been a bit hesitant in allowing others to deploy your web-projects on their own. Mainly because of the amount of work that goes into do so.
In this post I am going to offer you a some more (hopefully) helpful advice on how to use the tools that package your webapps with minimal extra effort.
Make isn’t as helpful when you are looking to distribute webapps
While writing code for the web may be similar to writing other (generic) projects, there are a few of issues that are better tackled by a few other dedicated tools:
- Many more libraries to manage
If you have written Javascript apps, you’d know that you tend to rely on a lot of external frameworks, libraries, plugins etc… when coding for web projects. And frankly that is the one of the convenient reasons of doing a webapp in the first place. It is a lot more fun to concentrate on your own stuff when you have a lot of existing re-usable code at your disposal. But all of this makes your app even more vulnerable to fail when you have package and distribute it to others. Pulling different versions of your libraries from the web, may prevent your application to run smoothly. They could interfere with each other and result in conflicts specially when you are dealing with not-so-well-tested research code. - Dependence on other services
If you are writing a webapp, it is quite likely that you’d have a back-end service to use as well. It is usually a good idea to develop them independent of each other but this leaves you with many more configuration variables to manage. Manually taking care of each of these settings adds to a lot work either during deployment or while writing code. There are far too many prefix and suffix variables that get thrown around. - Deploying it on a webserver
And ofcourse you need a web-server to be able to deploy and run your apps. You might be using different types of them depending on what you did your backend in (Java / PHP / .NET … etc.). This adds to a whole new set of problems on its own while packaging apps.
Because of these factors it is a challenging to package webapps that can be easily deployed on other machines. But then you could take a few extra steps for the sake of reproducibility (and science!).
Node.js to the rescue!
While your options are a many here, I am going to talk about my (current) favorite development stack – Node.js. But then of-course you could look for other alternatives depending on your specific uses.
One of the advantages of using Node.js is that it lets you do the back-end in JavaScript. This specially convenient when you also have a good portion of the UI code in js as well. In fact, I
would recommend using it even if you are doing your backend in some other language. That’s because I like node’s package manager – npm a lot (I would rate it right after apt-get in terms of usability). You’d want to use them for deploying apps on servers that don’t rely on node as well.
Two packages that I couldn’t highly recommend would be bower and grunt. Bower is a client side code manager that let’s you deal with all of the client side dependencies with ease. These include your frameworks (jquery / angular etc.), starter code (Bootstrap / HTML5 Boilerplate etc.), and even your framework plugins.
While grunt takes care of all the repetitive tasks such as minifying source files, building docs, and configuration management etc.
And then finally, you could also use npm to install a basic http-server for cases when you have a simple or no back-end. Saves you the trouble of using a separate web-server altogether.
Assuming that I have sold node to you, I will now illustrate their uses with small examples so that you could get some idea on how you can use node and npm with your own projects.
For using npm, you would include a simple a package.json file where you can specify individual packages (bower, http-server etc.) that you are using for your project. It let’s you specify specific versions for them to avoid any conflicts. I’ll use a sample package.json file as an example:
Once you do a npm install
, it would not only install all the package dependencies but you have an option of doing a couple of post-install steps in the script section. Once you have all the packages you’d be using you’d probably want to download all the libraries that you are using using bower. You also have other options in the scripts section like starting the simple http-server and so on. And here’s how a sample bower.json file would look like:
See, that? Bower and npm install let you pull all your dependencies on the fly while taking care of managing their required versions! No longer you need to explicitly include these files with your project.
And finally I’ll come to this another neat package called grunt. I find it really useful for managing the configuration variables. With a gruntfile, true to its name, you could automate your repetitive tasks that need to be carried out during different steps like installing the app, start the server, running tests etc . In case you were wondering about about the config
variable in my package.json, now’s the time when I will be make use of them:
In my code, I’d like replace all instances of the term @@backEndApp in my config/services.js file, replace it with the correct value as set in package.json and finally copy this file inside my app’s working directory. The two at (@) symbols is the default syntax for a full match but you could use regular expressions there as well.
As you would have noticed, this is a regular javascript file and you enjoy its full functionality as well. You might probably already have ideas to do a lot more with with grunt.
Once you start exploring other npm packages likes, the only steps required by somebody looking to deploy your webapp would be something like a npm install
, possibly followed by a npm start
. Neat isn’t it? Hope this would help you package your webapps better.
nice write up….
one thought npm install [–save-dev | –save] is a better option that way you don’t need to manage package.json manually.
Agreed. Thanks for mentioning that! I missed it in my post.
Use gulp instead of grunt. Much lesser boilerplate and much more intuitive. The piping ensures you don’t have too many temporary files to create too
Yeah, I have read about it but I haven’t really tried it yet. Had been quite satisfied with grunt. Will check it out next time.