Monday, January 21, 2013

PackScript – Better. Because…

*UPDATE* Check out http://packscript.com/ for a complete reference and examples.

What is this PackScript Jiggery?

PackScript is a powerful open source (MIT license) resource build tool designed specifically for the combining and minification JavaScript, HTML and CSS files in modern, single page web applications. It was built from real need, specifically to support knockout.composite, and is focused around taking all of the pain out of managing all of the resources for your web app. You can find it on github.

PackScript is the next generation of build tools for the web and handles every aspect of building and optimising your web resources. Say goodbye to painful optimisation and to managing code for your debug, test and production environments, say hello to the optimum debugging experience in your browser. PackScript leaves you to do what you do best – code.

Next Generation Build? What makes PackScript better than everything else out there?

First of all, PackScript is much more than a minification tool. It actually delegates the task of compressing resources to separate tools. Microsoft AjaxMin is used by default, but adding support for others is simple. YUICompressor, Closure Compiler, uglifyjs, jsMin and minify are other tools that fall into this category.

So PackScript handles “bundling” together a bunch of files and compresses them. There are a number of existing tools out there that do this…

Server-side Solutions

A significant number of these tools rely on a server side component to dynamically combine and minify your resources. ASP.NET bundling, Carabiner, SquishIt and bundlejs are all examples of this kind of build tool. Generally, they do the job quite well, but they have some drawbacks.

The most obvious issue is that these solutions require a server side component, adding a dependency, tying you to a platform and consuming your valuable CPU cycles. Modern, single page web applications perform rendering tasks on the client, relying on server side processes purely for process and data access. Adding a dependency like this just adds unnecessary complexity.

PackScript produces static resources, as you code and as part of your build process, that can be deployed to any high-performance web server, anywhere, even to a global CDN.

The other not so obvious issue is one of debugging. These tools generally present your debugger with one behemoth file; a less than desirable experience. PackScript allows your files to be packaged in a way that splits your files back up and gives you the debugging experience you need. Even if you are using a server side rendering framework, you can still benefit from PackScript.

Client-side Solutions

Client side tools are not really combining and minifying tools, they optimise the loading of multiple files asynchronously. headjs and labjs are examples of these tools. PackScript will happily coexist with these sorts of tools if you really want to optimise your loading times.

At some point I intend to create an extension that will split your resources into an number of equal size chunks, load them with one of the above tools and piece them together on the client. I’m expecting this to have pretty significant impact on load times!

JavaScript Frameworks

If you’re using a framework like CommonJS or Dojo, they often come with their own set of resource management tools. Use them!

Having said this, PackScript can still offer you some benefits. Read on, and check out the features that PackScript offers.

RequireJS / AMD

RequireJS is arguably the best resource management build tool out there (until now…), popular enough and similar enough to PackScript that it deserves it’s own section.

RequireJS essentially allows you to declaratively define dependencies in your code. Dependencies can consist of individual JavaScript files or you can define named modules that can themselves have dependencies. Modules implement the Asynchronous Module Definition API. RequireJS will ensure that all dependencies (including nested dependencies) have been fulfilled.

AMD is a good standard that is gaining popularity. It takes a lot of the pain out of managing complex dependency trees, and RequireJS minifies your resources along the way. We think PackScript is better for many situations, and can actually coexist with an AMD approach.

Two main problems that RequireJS has are that it’s intrusive and that it introduces a degree of friction.

Intrusive

By intrusive, I mean that you have to write code in a specific way to satisfy RequireJS; modules must be defined and dependencies must be declared using the AMD API. This is not all bad, enforcing a consistent approach to this sort of stuff is not a bad idea, but it introduces a direct dependency on a third party product and unnecessarily ties you to an API.

PackScript manages your dependencies externally to your code and builds static, optimised files at build time. No code needs to be written to manage resources that will ever make it into your running application.

Friction

Friction is anything that consumes your time, most often repetitive and error prone tasks – a “force resisting relative movement”. As an example, creating an optimised set of resources with RequireJS involves creating a configuration file and executing the optimiser against that new file. We also need to make sure the build process includes creation of this resource set, so update the build configuration for each environment.

This sort of friction can (and should) usually be eliminated with some custom solutions – create an executable that scans our project folder for build profiles that conform to a specific convention and execute the optimiser against them with a common set of arguments.

PackScript is focused around eliminating friction. It builds your application in the background as you work and is designed to be easily integrated with any automated build process. In most cases, you can just add your resources to the project and move on. If not, add a simple configuration file and PackScript does the rest, even as you code.

Flexibility and Extensibility

PackScript also offers a great deal more flexibility and extensibility than RequireJS.

Don’t like the API? Change it.

Doing the same configuration over and over? Abstract it out.

Optimising the buggery out of your resources? Load multiple modules from one combined script at key points in the application lifecycle, or in the background after loading a set of bootstrapper resources.

Got a stack of icons that are loaded individually? Combine them into a single file and generate a CSS map for them. Add an icon to your project and it’s there. Frictionless.

PackScript works with any static resource and is easily extensible with either JavaScript or .NET. Combine this with the declarative dependency management of knockout.composite, and you get the best of it all.

What Are You Waiting For?

Head over to the feature overview for PackScript, check out an example, have a look at the core unit tests and integration tests, download it from github and have a play! It’s worth noting there are a number of issues on github.

What do you think? Have I missed anything? Is there another solution that’s not mentioned here?

0 Comments:

Post a Comment

<< Home