A JavaScript library template.
JavaScript CSS HTML
Latest commit 0b58527 Oct 1, 2015 @jeremyckahn Merge pull request #5 from jseiden/patch-1
Update README.md

README.md

JavaScript Library Template

This is meant to serve as a foundation to build JavaScript libraries on top of. Exactly how a JavaScript library is structured isn't standardized, so this project aims to define an opinionated pattern for organizing, building, and testing code. If want to write a JavaScript library and need a starting point, this is a good option.

Here's a video explaining the ideas and motivation behind lib-tmpl.

Don't be afraid to change any code or conventions in this project, it's simply an educational tool meant to give direction when writing JavaScript libraries.

I created this skeleton project out of what I learned with my projects Rekapi and Shifty. It is also heavily inspired by other projects such as jQuery. The module pattern and AMD compatibility code is an abstraction of the work of Franck Lecollinet.

Setting it up

This project uses NodeJS and Grunt for the build process. Assuming you have Node and npm set up (npm is installed when Node in installed), you can just do this at the CLI in the lib-tmpl directory:

$: npm install

What this project gives you

A scalable, unobtrusive pattern

There are a lot of small things you can do maximize compatibility and minimize headaches. This template has a lot of this baked in. Only one global symbol is exposed (none are exposed if it is loaded as an AMD module), a clear convention for managing private and public APIs is provided, and JavaScript Strict Mode is enabled by default.

Module templates

As your library grows, it helps to separate code into files. This serves to keep large amounts of code manageable, and it also makes collaboration easier by mitigating merge conflicts. A lib-tmpl library must have one core module, and any number of additional modules. Modules should be organized by the task they perform. For instance, if you have a set of methods that do DOM manipulation, those should be isolated into a single module.

A directory structure

Each directory has a README that explains what its purpose is.

A build process (via Grunt)

Compiled code loads and runs faster than uncompiled code. lib-tmpl provides concatenation and minification via Grunt (see Gruntfile.js). Feel free to modify this configuration to suit your needs. The default configuration creates the production-ready dist/library.min.js and debug-friendly dist/library.js files. Building this project via the CLI is really easy:

$: grunt build

Conditional compilation for customizing binaries

UglifyJS has a great feature: Conditional compilation. Conditional compilation allows you to mark sections of code that should not be included in the compiled binary. This has a number of benefits, not least of which is exposing private functions and variables only during development and testing. This template provides sections to place code that get removed during compilation. The flag DEBUG is included and set up out of the box. See the notes in src/library.const.js for more info on how to add more.

Testing bootstrap

A good library is thoroughly unit tested. There are number of ways to unit test your code, and you are free to use whatever framework or approach you prefer. lib-tmpl provides basic test skeletons for API and AMD tests via QUnit.

To run the tests, you can either open each of the test/qunit.*.html pages in your browser, or run them all in the CLI (requires PhantomJS to be installed). The qunit Grunt task automates this for you:

$: grunt qunit

JSHint boilerplate

JSHint is a tool that helps ensure code quality. lib-tmpl provides some default settings in .jshintrc - feel free to customize it. To lint all of the source files, run this:

$: grunt jshint

AMD compatibility

AMD (Asynchronous Module Definition) defines a way by which to load code. You don't have to use it, but it's a great development tool and helps prevent pollution of the global scope. This template is compatible with AMD loaders, such as RequireJS (which is included by default). You can also safely load the code with a standard <script> element with no side effects.

Building on top of this template

If you choose to use this template to build your libraries on top of, you should first change the name of the library. It is called "Library" by default. You'll need to change the name of the constructor (in src/library.core.js) and all references to that constructor in the code and comments. It's also a good idea to change the file names to reference the actual name of your library, rather than the generic "library." In other words, you should change src/library.core.js to something like src/my-awesome-tool.core.js.

The naming convention for the files in src/ is significant:

<LIBRARY_NAME>.<MODULE_NAME>.js

When you change the name of the library and the prefix of the files in src/, you will also need to update the value of LIBRARY_NAME in Guntfile.js. As you add module files in src/, you will also need to add them to MODULE_LIST, also in Gruntfile.js. The areas you need to modify (LIBRARY_NAME and MODULE_LIST) are called out in the comments.

Don't forget to update package.json (for npm) and component.json (for Bower) to reflect you and your project!

More on adding module files

You can add modules to this library. You can think of src/library.module.js as a generic module template. Simply copy that file and modify as needed. To initialize the module, add its init wrapper function to src/library.init.js (there's a note in the comments where to do this).

Roadmap

Admittedly, building on top of and extending lib-tmpl is somewhat labor-intensive. Eventually I'd like to write generators for creating and linking modules automatically.