This example will guide you through the recommended way to package a YUI module as
an exportable package with npm
on Node.js.
Packaging up your scripts with npm
makes them usable by others so they can benefit from
all your hard work. There's nothing quite like having others use something you worked hard
to create. So, why not make using your code as easy as possible?
There are 2 primary ways a Node.js user could use your YUI module, below we will discuss both ways as well as how to package up your code so they can both be available to your end user.
First we need to set up the code so we can package it up all nice and neat.
We are going to use this simple version of a module in this example:
YUI.add('my-module', function(Y) { Y.MyModule = function() { Y.log('Here'); }; });
This file will be saved as module.js
in a directory all by itself.
Next we create a package.json
file that describes our Node.js package:
{ "version": "0.1.0", "name": "my-yui-module", "description": "My YUI Module", "dependencies": { "yui": "*" }, "main": "./index.js" }
Note that we are using index.js
here as our main script and not module.js
, index.js
will be created below.
Your index.js
file is the main file in your npm
package, it's the file that executed when your module
is required
. We need to make a special index.js
file that will load YUI and use
our module.
In this example, we will export our module as a working YUI instance. So when the user requires
our
module they get all of YUI with it too. Here's the index.js
file used in this case:
var path = require('path'); //setup our custom modules meta-data var meta = { 'my-module': { requires: [ 'yql' ], //Give it a full path on the file system fullpath: path.join(__dirname, 'module.js') } }; module.exports = { module: function() { var inst = require('yui').getInstance(); inst.applyConfig({useSync: true, modules: meta }); return inst.use(Object.keys(meta)); } };
This setup allows the user to do this:
var mod = require('my-yui-module').module(); mod.MyModule(); mod.YQL('select * from ...');
At this point mod
will be a YUI instance containing my-module
and all of it's dependencies (yql
, jsonp
).
This will allow you to create a module that the end user doesn't even have to that YUI is there. Making it
easy for them to just require
and run your module.
The other type of user you want to deal with is the one that is already writing scripts with YUI
on Node.js and they want to use your module too. In this case you need to make your modules metadata
available so they can add it to their YUI instances. You can do this in your index.js
to provide
the metadata needed to load your module.
var path = require('path'); //setup our custom modules meta-data var meta = { 'my-module': { requires: [ 'yql' ], //Give it a full path on the file system fullpath: path.join(__dirname, 'module.js') } }; module.exports = { metadata: function() { return meta; } }
This will export the module metadata needed to allow Loader
to load your module and
use it as if it was a native module.
var YUI = require('yui').YUI, var mod = require('my-yui-module'); YUI({ //Populating the modules config option // with the metadata from the package modules: mod.metadata() }).use('my-module', function(Y) { Y.MyModule(); Y.YQL('select * from ...'); });
Now that we have them individually covered, let's put them together so you have one
package that now works for both types of use cases. Here is the complete index.js
file.
var path = require('path'); //setup our custom modules meta-data var meta = { 'my-module': { requires: [ 'yql' ], //Give it a full path on the file system fullpath: path.join(__dirname, 'module.js') } }; module.exports = { /** * Calling this method will create and return a YUI instance * with the modules in the meta data attached. * @method module * @return YUI */ module: function() { var inst = require('yui').getInstance(); inst.applyConfig({useSync: true, modules: meta }); return inst.use(Object.keys(meta)); }, /** * Calling this method will return the modules meta data * so that it can be passed to the YUI constructor. * @method metadata * @return Object */ metadata: function() { return meta; } }
Now that we have our index.js
file ready to go, we can now include our package and use it both ways.
#!/usr/bin/env node var mod = require('my-yui-module'); mod.MyModule(); mod.YQL('select * from ...'); // OR var YUI = require('yui').YUI; YUI({ modules: mod.metadata() }).use('my-module', function(Y) { Y.MyModule(); Y.YQL('select * from ...'); });
Using this method to setup your YUI module, you can now publish your module to npm
and
share it with others.