Wednesday, September 05, 2012

Moving to a new blog

Any new posts I do will be at jrburke.com. There is a post over there about the new blog.

I will keep this blog for historical purposes, but any new posts will be at the new location.

Wednesday, August 29, 2012

volo 0.2.3: semver and a web site

volo, a command line tool to create web projects, add front end dependencies and automate tasks, is now at 0.2.3. Get it via npm:

    npm install -g volo

The complete set of changes are here. The notable ones:

1. semver ranges can be used with dependencies now. For example:

    volo add requirejs/~2 

will download the latest 2.x version of jrburke/requirejs from GitHub.

2. volo add mentions possible incompatibilities after doing a nested dependency install, and gives commands for manually choosing one of the other versions.

3. volo now has a simple web site that hopefully gives a better idea intro to volo. Many thanks go to James Long for starting the structure and helping to refine its message. There is more to do for the site, but it is already much better than what was there before.

Saturday, August 18, 2012

RequireJS 2.0.6 released

RequireJS 2.0.6 is available.

The main focus of this release was cleaning up some rough edges in the r.js optimizer after switching to esprima for all module parsing/tracing. Most notably, the findNestedDependencies build option should work correctly again. The bundled UglifyJS was updated to 1.3.3 too.

Complete list of fixes:

Wednesday, August 08, 2012

RequireJS 2.0.5 released

RequireJS 2.0.5 is available, along with almond 0.1.2 that matches the 2.0.5 behavior.

The most notable changes:
Complete listing of:


Wednesday, July 25, 2012

On client components for web apps

This is a response to a blog post by TJ Holowaychuk about browser-based components for web applications, and Isaac's notes on TJ's post.

I am going to try to make this brief because I get tired of people in the Node community wanting to apply the same patterns from Node in the browser. I feel like I say these things on a periodic basis, but human communication is hard, and I certainly could do better. But I also want to get back to just making things. So this will be terser than I normally would like.

Web components

I suggest TJ look at volo, my attempt in this space. It does lots of what he describes already, and it can even be used as a module in another command line tool. We use volo for some things in Mozilla already.

volo uses GitHub as the component registry. It does so without the downsides that TJ mentions.

Specifically, volo uses the GitHub HTTP API to get version tags, do registry searches. I grabs .zip snapshots for a given version/github commit/branch, so the command line tool (the consumer) does not need use git. Git is not necessary on the client side.

This means the downloaded code is smaller -- no need to get a full repo and all of its commits.

volo also understands dependencies via the shorter "owner/repo/tag" IDs instead of the full github URLs.

It has a "shim" repo that means it can support installing components without needing the author of the component to conform to some new publishing system. Since it allows {version} replacement in URLs, the registry setup just needs to be done once. From then on, normal best-practice versioning via git tags is enough.

Some other notes in this post.

Base module format

Node bros, the AMD trolling is getting tiresome. Node's module system is woefully under-specified for web-based loading. While you can limp along with browserify, there are still these issues:

* For builds you need a wrapped format. For CDN deployment you need a wrapped format. browserify uses a wrapped format. AMD anyone? For that reason alone, AMD will never go away. Get used to it already.
* Web code needs a callback-style require for on-demand loading.
* Browserify's uses of file paths for IDs is awful for mixed local and CDN-based loading. Module IDs need to stay in ID format, not translated to a specific file path.
* Loader plugins reduce the need for callback-style APIs, and callback pyramid of doom, or inside-out callback hell, or the need for promise based programs. This more than makes up for the extra level of indent in AMD.

Loader plugins solve the translation issues TJ talks about, and they can participate in optimization builds, meaning templating engines can inline the JS function form of the template. Ditto for language transpilers like CoffeeScript.

By doing this:

define(function (require) {
    //node module code in here.

    //Return module value instead
    //of needing `module.exports`
});


you have an AMD module.

Quit dismissing AMD for surface issues. AMD avoids mandating translation layers that lead to more things for the developer to understand and fix, and more process for the user to go through to deploy code. It is a net win when the source file works when deployed anywhere, without requiring specialized builds/converters.

Even if you want to personally use Node style and always do builds before loading in the browser, AMD is a great target for the built, wrapped format. You can even use the requirejs optimizer to do this, with the cjsTranslate option.

The universal module boilerplate gets simpler when Node supports AMD's define along with Node's existing module format. If you want to help improve the ugliness, start there.

AMD comes from real world exprience in Dojo with trying to deploy an unwrapped module format that depended on XHR+eval in dev and a wrapped format for builds. Yes, you can something to to work but the second order translation and support costs are not worth it. Some environments disallow eval. CORS configuration is awkward, and potentially hazardous if your API is on the same domain and CORS is done incorrectly.

The simplicity of the complete module lifecycle is worth the function wrapping. Quit looking just at what you type once, and consider the complete code lifecycle, and how much time could be wasted there.

npm's registry as the component registry

The implied rules with npm and node's module behavior are not good fits for front end web development:
  • Forcing a directory structure is complicating project layout and loading for web-based projects. It should be possible to publish and install single JS libraries as single files. volo can do this.
  • Related: the "index.js" convention is awful for web development and debugging. Debugging 'jquery.js' instead of trying to find 'jquery/index.js' in the web tools? No thank you.
  • npm's registry namespace is already polluted. Check searches for 'jquery'. Maybe that just means having a separate npm registry-based registry for client code. But if there needs to be a separate repo, might as well use one that can adapt better to front end development. Like single JS/CSS file installs without extra Java-esque directory structures and metadata debris on the file system.
Ender is not a success story for using npm. Ask the Ender folks how well that worked out. It only works because it is small scale.

By using GitHub, it comes with user auth handled, private repos, and robust social tools that will not be matched by a something like npm because the financial incentives are not there. Plus developers already use it. For simple open source sharing, make it easy without introducing more things in the middle.

Github as the registry is not perfect, and we still need some standalone servers that can be run inside corporations/for mirrors, but I would model those standalone servers on the github API. At least the default case of a public repo can be bootstrapped very quickly.

Monday, July 09, 2012

RequireJS 2.0.4 released

 RequireJS 2.0.4 is available.
 
And hot on the heels of 2.0.3, there is a 2.0.4 release! Unfortunately a bug with a fix that was in 2.0.3 caused a different bug, and it was not found until after the 2.0.3 release. It made the optimizer unusable in certain situations, so the change was rolled back and 2.0.4 is out, with the only change over 2.0.3 being the rollback of that previous change.


I apologize for the extra noise.

RequireJS 2.0.3 released

 RequireJS 2.0.3 is available.

Just a maintenance bug fix release. Most notable changes are probably:
  • optimizer now does not fully resolve "paths" until all config sources (mainConfigFile, build profile and comand line args) have been merged.
  • a fix for data-main resolution for require.js.
Full list of fixed bugs:


Saturday, July 07, 2012

volo 0.2.2 released

volo 0.2.2, a JS package manager and project automator, has been released. To install/update:

npm install -g volo

Here is a list of changes. Probably the most notable one:

volo create will run npm if there is a package.json in the downloaded project template with a dependencies property, and if there is not an existing node_modules directory.

This makes it easier to share volo commands between projects and their volofiles.

Example: the create-responsive-template now uses these separate volo commands in its volofile:
  • appcache: generates an appcache manifest for a project.
  • ghdeploy: deploys a directory of code to github pages.