Creating a demo page for your npm module
So, you’ve created a super-awesome npm module, and you want to share it with the world. You’ve seen other modules include handy demo sites, where you can play around with the functionality directly in your browser, before even downloading the module yourself. So, just how do you create a demo page?
In the past, if you created server-side code, you’d need to run a server so that a demo could be created. However, since we are just writing JavaScript, provided your module is not using any node-specific APIs, we can use a few friends to package up your npm module for consumption by a static web page. This is really nice, as it means you can publish your demo page to a static host, such as Github Pages.
In this post, I’ll walk through how to setup an automatic build toolchain to create and publish a static demo page for your super-awesome module.
Here are the steps we’ll take to publish your demo page.
- Install grunt and all of the dependencies needed to build the page.
- Create a demo folder, which includes the static HTML, CSS and JavaScript that will be published.
- Implement your HTML demo page and associated JavaScript, making use of the browserified module.
- Setup a
Gruntfile
to browserify your module and make it available for your demo page. - Use
grunt
to build and deploy your demo site to GitHub Pages.
The tutorial assumes that you have:
- Created a module in
lib/index.js
- A valid
package.json
file - Checked in your code to a repository on GitHub.
Your folder structure should resemble the following:
├── lib/
| └── index.js
├── package.json
1. Install dependencies
We’ll be using grunt to automate the building and deploying of the demo page. Install grunt and all the needed plugins with these commands:
npm install -g grunt-cli
npm install --save-dev grunt grunt-browserify grunt-build-control grunt-contrib-clean grunt-contrib-connect grunt-contrib-copy grunt-contrib-uglify grunt-contrib-watch jit-grunt
2. Create a demo folder
The next step is to create a demo folder. Populate it with three files as shown below:
├── demo/
| ├── index.css
| ├── index.html
| └── index.js
├── lib/
| └── index.js
├── package.json
3. Implement your demo site
3.1 index.js
This is where your JavaScript magic will live.
In this index.js
file, we’ll pull in our super-awesome module with a require
call, and use it directly. require
is part of CommonJS, and while this isn’t supported by vanilla JavaScript in the browser, we’ll use a tool called browserify to package up the modules and make them available for consumption by the browser.
The rest of index.js
will likely be concerned with accessing the DOM and manipulating the HTML view.
Here’s an example:
// index.js
'use strict';
var superAwesome = require('super-awesome');
var input = document.getElementById('input');
var result = document.getElementById('result');
input.addEventListener('input', function () {
result.value = superAwesome(input.value);
});
Here, we are listening for any changes to the input
and updating the result
using the superAwesome
library.
3.2 index.html
This is the part where you create your demo page. Open up the index.html
page and create your masterpiece.
In your HTML page, we need to include our script file too, so make sure you include a reference to it. It’s a good idea to put the script below your DOM elements so that we know that the DOM is fully initialised before we add the event handler.
<html>
<body>
<input id="input" type="text" />
<pre id="result"></pre>
<script src="index.js"></script>
</body>
</html>
We are now done with the implementation of the demo page. If we try to access the file at demo/index.html
in a browser, however, things will fail, because the browser doesn’t know what to do with the require
call in index.js
.
To solve this, we need to use browserify to build a bundle which can then be used in the browser.
4. Setup a Gruntfile
to browserify your module
The next step is to include a Gruntfile to package up your module as something that the browser understands. We’ll use grunt-broswerify
and some common grunt utility plugins to create a folder build
which we can then serve using a static web server, and hence can be deployed to GitHub Pages.
Here is the Gruntfile in full:
'use strict';
module.exports = function (grunt) {
// Load grunt tasks automatically, when needed
require('jit-grunt')(grunt, {
buildcontrol: 'grunt-build-control',
});
grunt.initConfig({
clean: {
demo: ['build'],
},
copy: {
demo: {
files: {
'build/index.html': ['demo/index.html'],
},
},
},
browserify: {
options: {
alias: {
diffex: './lib/index.js',
},
},
demo: {
files: {
'build/index.js': ['demo/index.js'],
},
options: {
watch: true,
},
},
},
buildcontrol: {
options: {
dir: 'build',
commit: true,
push: true,
connectCommits: false,
message: 'Built live demo from commit %sourceCommit%',
},
demo: {
options: {
// Update the remote to point to your github repo
remote: '[email protected]:fiznool/super-awesome.git',
branch: 'gh-pages',
},
},
},
connect: {
dev: {
options: {
base: 'build',
hostname: 'localhost',
port: 3000,
livereload: true,
},
},
},
watch: {
dev: {
files: 'build/index.js',
options: {
livereload: true,
},
},
},
});
grunt.registerTask('build', ['clean', 'copy', 'browserify']);
grunt.registerTask('serve', ['build', 'connect', 'watch']);
grunt.registerTask('deploy', ['build', 'buildcontrol']);
grunt.registerTask('default', ['serve']);
};
Here is a rundown of the tasks, and what occurs at each stage.
build
- Cleans the
build
folder, removing atrifacts from a previous build. - Copies over the
demo/index.html
file to thebuild
folder. - Uses browserify to package up the source in
demo/index.js
and anything that isrequire
d into a single bundle, and writes it out to thebuild
folder.
serve
- Builds the demo page as above.
- Begins a web server on port
3000
where you can preview the demo page. - Watches for changes to the JavaScript source, and automatically re-browserifies the bundle, and reloads the browser.
deploy
- Builds the demo page as above.
- Pushes the contents of the
build
folder to a branch calledgh-pages
. This automatically creates a new GitHub Pages page at the URLhttps://<user>.github.io/<project>
.
5. Use grunt
to build and deploy the site
This is the fun part! Once you are happy with your demo page, run
grunt deploy
This will build your demo site and deploy it to GitHub Pages, where you can see it in all its glory!
Summary
Creating a simple demo page for your super awesome npm module is easy with a little help from grunt and friends. We can use the power of GitHub Pages to create a nice demo site, and host it for free.
I’d love to hear feedback on this method, in particular if there is anything I’ve missed, or could be done better. If you have anything to add, please let me know in the comments below or via my Twitter. Thanks for reading!