ENDER the no-library library

Build only what you need, when you need it.

$ ender build domready qwery underscore

Lightweight, expressive, familiar.

$('#content a.button')
  .bind('click.button', function (e) {
    $(this).data('clicked', true).unbind()
    e.preventDefault()
  })
  .css({
      opacity: 1
    , color: 'red'
  })
  .fadeOut(250)

$.map(['a', 'b', 'c'], function (letter) {
  return letter.toUpperCase()
})

$.ajax('/data', function (resp) {
  $('#content').html(resp)
})

INTRODUCTION

Ender is a full featured package manager for your browser.
It allows you to search, install, manage, and compile front-end JavaScript packages and their dependencies for the web. We like to think of it as npm's little sister.

Ender is not a JavaScript library.
It's not a jQuery replacement. It's not even a static asset. It's a tool for making the consumption of front-end JavaScript packages dead simple and incredibly powerful.

WHY?

In the browser - small, loosely coupled modules are the future and large, tightly-bound monolithic libraries are the past!

Ender capitalizes on this by offering a unique way to bring together the exciting work happening in JavaScript packages and allows you to mix, match, and customize your own build, suited to your individual needs, without all the extra cruft that comes with larger libraries.

With Ender, if one library goes bad or unmaintained, it can be replaced with another. Need a specific package version? No problem! Does your package have dependencies? Let us handle that for you too!

DOCUMENTATION CONTENTS

OVERVIEW

ON THE COMMAND LINE

$ ender build backbone
# installs:
# └─┬ backbone@0.5.2 - Give your JS App some Backbone with Models, Views, Collections, and Events.
#   └── underscore@1.1.7 - JavaScript's functional programming helper library.

$ ender add domready qwery
# installs:
# ├── domready@0.2.5 - bullet proof DOM ready method
# └── qwery@2.1.2 - blazing fast CSS1|2|3 query selector engine

$ ender remove qwery
# uninstalls:
# └── qwery@2.1.2 - blazing fast CSS1|2|3 query selector engine

IN THE BROWSER

// Require packages to access them as raw packages
var _ = require('underscore')
_.each([1, 2, 3], alert)

// Access methods augmented directly to the $
$.ready(function () {
  $([1, 2, null, 3])
    .filter(function (item) { return item })
    .each(alert)
})

INSTALLATION

When installing, first make sure you have a working copy of the latest stable version of both Node.js and npm. You can then install Ender with the following single line:

$ [sudo] npm install ender -g

Once installed, you should have access to the ender command.

USING ENDER FROM THE COMMAND LINE

The ender command provides the following actions:

BUILD

Installs and assembles JavaScript packages and their dependencies.

$ ender build [foo, bar, ...]

arguments

Accepts a list of npm package names and/or paths to local packages. If left blank, the directory root will be used. You can specify a version by suffixing a package with @ followed by a version number.

$ ender build scriptjs backbone@0.1.0 ../../myLocalPackage

note: When providing a path, the package directory must contain a valid package.json file

output

  • » ender.js - an uncompressed file containing assembled packages
  • » ender.min.js - a copy of ender.js, minified by uglify-js
  • » local copies of specified packages - located in the node_modules directory, these are used for dependency management

options

  • » --noop - this outputs the assembled packages without the ender-js client api.
  • » --output - this outputs your assembled packages to a specified path and filename.
  • » --help - gives you more info on the build method.

ADD

Installs and appends JavaScript packages and their dependencies to an already assembled library.

$ ender add [foo, bar, ...]

arguments

Accepts a list of npm package names and/or paths to local packages.

$ ender add scriptjs

output

  • » ender.js && ender.min.js - Appends package code to already present ender builds
  • » local copies of specified packages - located in the node_modules directory, these are used for dependency management

options

  • » --use - Specify which file to append package code to.
  • » --help - gives you more info on the add method.

note: You don't need to specify .js when referencing a JavaScript file here

SET

Sets a JavaScript packages to specific version.

$ ender set foo@0.0.1

arguments

Accepts a list of npm package names and/or paths to local packages.

$ ender add scriptjs@0.1.0

REMOVE

Uninstalls and removes JavaScript packages and their dependencies from an already assembled library.

$ ender remove [foo, bar, ...]

arguments

Accepts a list of npm package names and/or paths to local packages.

$ ender remove domready

options

  • » --use - Specify which file to remove package code from.
  • » --help - gives you more info on the remove method.

REFRESH

Rebuilds and reinstalls packages.

$ ender refresh

options

  • » --use - Specify which file to refresh.
  • » --help - gives you more info on the refresh method.

COMPILE

Shortcut for compiling code with google closure compiler.

arguments

Accepts file paths.

$ ender compile ./header.js ./footer.js ./my/app.js

INFO

Provides the current status of your built Ender library. This information includes the build type, a gzipped file size, and a list of all the current packages (with version numbers, descriptions, and dependency tree).

$ ender info

options

  • » --use - tell ender which file to operate on

Looks up keywords against npm's registry and surfaces the most relevant packages. It promotes results for known Ender compatible packages and also generic npm matches).

$ ender search underscore

HELP

Gives a simple run through of the available methods and documentation.

$ ender

BUILDING AND PUBLISHING YOUR OWN PACKAGES

Because Ender relies on npm for package management -- extending your Ender library is as simple as publishing to npm.

PACKAGE.JSON

If you haven't already registered your project with npm, create a file called package.json in your package root. A completed package file might look something like this:

{
  "name": "blamo",
  "description": "a thing that blams the o's",
  "version": "1.0.0",
  "keywords": ["blamo", "ender"],
  "homepage": "http://example.com",
  "authors": ["Mr. Blam", "Miss O"],
  "repository": {
    "type": "git",
    "url": "https://github.com/fake-account/blamo.git"
  },
  "dependencies": {
    "klass": "*"
  },
  "main": "./src/project/blamo.js",
  "ender": "./src/exports/ender.js"
}

Have a look at the Qwery package.json file to get a better idea of this in practice.

Ender Specific Practices

  • » Add the ender keyword to your package.json to get promoted by Ender search as a compatible package.
  • » Add a bridge file for integrating with the Ender client api by specifying an "ender" param.
  • » you may specify "noop" for the "ender" param to tell Ender to not try to integrate it with the Ender client api.

THE BRIDGE

The bridge is an optional JavaScript integration file used to integrate your code with the Ender client api.

THE ENDER CLIENT API

The Ender client api offers two powerful ways to interact with your JavaScript packages, a module API which is based on CommonJS Modules spec v1.1 and a heavily augmented $ namespace (like jQuery).

REQUIRE

Returns a raw exported JavaScript package.

var myPackage = require('myPackage')

arguments

A package name.

var _ = require('underscore') //return the underscore object

examples

If you were to run the following build command ender build backbone, you could then access both backbone and underscore from your browser like this:

var backbone = require('backbone')
  , _ = require('underscore')

backbone.Models(...)
_.each(...)

pro tip

Ender's module support is also great when you run into libs which are competing for namespace on the $. For example, if package "foo" and package "bar" both expose a method baz -- you could use require to gain access to the method being overridden -- as well as set which method you would prefer to be on Ender's internal chain.

$.baz() //executes bar's method baz

$.ender({ baz: require('foo').baz }); // sets $.baz to be foo's method baz

require('bar').baz() //bar's baz is still accessible at any time.

PROVIDE

Registers a new public package.

provide("myPackage", myPackageObj)

arguments

A package name and a value to store as the package.

provide('underscore', _)

note: Ender automatically wraps all command line installed packages in a closure and makes them available in this way. Because of this, most modules will not be accessible directly in the global scope -- this of course is great news!

$.ENDER

Augments arguments onto the Ender client object ($).

arguments

An object to augment onto the Ender $. An optional boolean value -- if true, the object will be added to the Internal chain.

$.ender({
  myUtility: myLibFn
})

$.myUtility()

note: Within the scope of your extension methods, the internal prototype will be exposed to the developer using the this context representing the node collection.

$.ender({
  rand: function () {
    return this[Math.floor(Math.random() * this.length)]
  }
}, true)

$('p').rand()

$._select

Set the selector engine for the $ object.

arguments

A method to be used as the selector engine.

$._select = mySelectorEngine
$('#foo .bar')

note: You can see it in practice in Qwery

example

If you're building a Mobile Webkit or Android application, you might want to set it simply to querySelectorAll.

$._select = function (selector, root) {
  return (root || document).querySelectorAll(selector)
})

THE JEESH

The Jeesh is the official starter pack for Ender. The Jeesh can help you build anything from small prototypes to providing a solid base for large-scale rich application for desktop and mobile devices. At its core, it's a collection of packages that we've found particularly useful for major use-case development endeavors -- but we encourage developers to add and remove packages to really make it your own. Currently, the Jeesh includes:

WHAT DOES THIS SETUP LOOK LIKE?

domready

$.domReady(function () {...})

DOM queries

$('#boosh a[rel~="bookmark"]').each(function (el) { ... })

Manipulation

$('#boosh p a[rel~="bookmark"]').hide().html('hello').css({
  color: 'red',
  'text-decoration': 'none'
}).addClass('blamo').after('✓').show();

Events

$('#content a').bind('keydown input', handler)
$('#content a').emit('customEvent')
$('#content a').remove('click.myClick')

TRY IT OUT

If you're looking to test drive this setup, have a play with the compiled source (minified).

BEYOND THE JEESH—ADDITIONAL PACKAGES

Ender is also a thriving ecosystem of packages, some specifically designed for Ender and others that are simply Ender compatible. To get an idea of what's available, why not have a look at these additional packages:

Or how about something more substantial? Ender Bootstrap gives you the individual Bootstrap plugins for Ender.

You can find additional modules, or add your own, on the Ender Wiki.

SELECTOR ENGINES

Ender doesn't limit you to using Qwery as your selector engine. You can also choose from:

  • » Sizzle - available as sizzle
  • » Sel - available as sel
  • » NWMatcher - available as nwmatcher

LEARNING ENDER

Instructional videos and other cool stuff for learning about Ender.

Getting Started with Ender

Building an Ender Module

ABOUT THIS PROJECT

We would love to hear how you're using Ender or why you're not. What you love... what you hate... And we would love all the help we can get! Got a great idea? Open an issue, submit a pull request, follow @ender, or message us on twitter!

LICENSE

Ender is licensed under MIT - copyright 2011-2013 Dustin Diaz, Jacob Thornton, Rod Vagg

For the individual modules, see their respective licenses.

Welcome to Ender 2.0

by Dustin Diaz on February 12th, 2014

Thanks to the selfless blood and tears of @amccollum, Ender has landed at 2.0.0. There's a bunch of new features! Aside from a plethora of bug fixes and improvements — here are the major highlights which will hopefully entice you to begin using Ender in your next project.

  • anything npm can install, Ender can too!
  • The minifier has been upgraded to Uglify 2
  • Source map support!
  • New Module runtime object for a better require! This supports multi-file modules, internal/relative requires, requiring submodules, and better CommonJS compatibility. See when.js package.json for an example of multi-files. It's pretty cool :)
  • Clearer understanding of your dependencies output from the CLI

If you have any questions, file an issue and we'll be happy to help.

Enjoy!

$ # p.s.
$ npm install ender

Ender CLI v1.0 has landed

by Rod Vagg on April 8th, 2013

It's been a full year in the making, but version 1.0.0 of the Ender command-line interface (CLI) was just pushed to npm and is now ready to augment your frontend-building awesomeness.

If you don't have Ender installed on your computer, you'll first need to install Node which comes with npm (the Node Package Manager). Once you have npm installed, you can install Ender:

$ npm install ender -g # the -g will install `ender` as a global command

If you already have Ender installed, then you can upgrade it with:

$ npm upgrade ender -g

What's in this baby?

The Ender CLI has been totally rewritten, but the commands are the same as v0.8 and prior. We had big plans for new features but other priorities caught up with us so we decided to just ship it when it was stable!

The CLI code now has a huge suite of tests and the code is a lot more solid than the previous CLI. More importantly, it's much more modular and gives us a ton of flexibility to extend and add the features that we really want for our own build processes.

The main themes of this release are:

  • Better CommonJS support: We're not there yet but we're close. We want Ender to help you build & package modular components around the CommonJS-style that you find in Node.js. We have some exciting stuff on this front to come in the next few releases.

  • Stability and predictability: For example, when you run ender build and associated commands, your packages are bundled in the order that you request them and the dependencies are also ordered so that a dependency will always appear before its dependant.

  • Flexibility for package authors: The package.json descriptor has become a lot more clever for Ender packages. It's now also much easier to share packages between Node and the browser by extending the descriptor with an "ender" specific key.

We promise not to sit on code for so long again, expect to see awesome new features appear in v1.1 and beyond.

More information?

For now you can find a lot of information in the CLI help, start with:

$ ender help

There are more advanced features for package authors and we'll try and document them here in the coming weeks. Feel free to bug us on #enderjs on Freenode, or ping @ender on Twitter, we're listening!


illustration courtesy raphaelurwiller

hosting generously provided by nodejitsu