These are some basic steps for writing a NodeJS module.
Most of the suggestions in this document are optional. You can definitely write your program however you like, and many in the node community enjoy trying out new creative ways of doing things.
This is merely a set of patterns that noders have found to work for them and their projects.
Most people in the node community use git for all their version control needs. It is an extremely powerful and robust tool. If you don't already use it, you should.
Don't wait until your program is "ready" before using git on it! Run
git init
in the root of your project folder right away, and commit
your changes as you make them. It is a good habit, and can help avoid a
lot of painful mishaps.
If you wish to share your program with others, then github is also a tremendously useful resource that most nodejs developers use.
Create a file in the root of your program named package.json
. This
file is a json description of what's in your project. If you're just
writing a standalone server or website that isn't intended to ever be
shared, then this is not strictly necessary, but it still does make some
things more convenient.
If you plan to publish your program and let others install it using npm, then a package.json file is essential.
You can specify in this file:
- Name, version, description, and keywords to describe your program.
- A homepage where users can learn more about it.
- Other packages that yours depends on.
If you have installed npm, then you can use the
npm init
command to get started. See npm help json
for lots of
information about everything you can put in this file.
If you are writing a program that is intended to be used by others, then
the most important thing to specify in your package.json
file is the
main
module. This is the module that is the entry point to your
program.
Documenting your dependencies is really handy. It is a very polite practice if you are going to share this program with others, and it provides a lot of useful techniques if you are deploying it somewhere.
Put basic entry-level documentation about your program in a README file in the root of your project.
If you enjoy the markdown format, you can write it in markdown, and save the file as README.md.
Seriously, do this! Even if you think you'll never have users, history teaches us that you'll go off and forget what this thing is for, and then come back to it and curse yourself for not documenting it even a little.
So document it. Even a little.
If you feel so inclined, it's also a great idea to put documentation in
a folder called ./docs
. Markdown files should end in .md
and html
should end in .html
.
Generally, node modules fall into these rough categories:
- A binding to some C or C++ library.
- A library of functionality to be used in other node programs, written primarily in JavaScript.
- A command-line program.
- A website or server or something. (That is, an implementation that you'll put on an actual server, not a framework.)
There is a lot of overlap in these categories. A thing doesn't have to be just one sort of thing.
Typically, C++ source code is put in a subdirectory of your project
called ./src
. C++ files usually have the extension .cc
. C files
usually have the extension .c
.
Generally, the simplest and best approach is to put the minimum necessary effort into the C++ layer, and then make the functions "nice" by wrapping a JavaScript layer around the raw binding.
Node programs use the included node-waf
program to compile. Create a
wscript
file with the appropriate rules in it, and then run node-waf configure build
to build your module.
Use the eio
thread pool to do any actions that perform synchronous
I/O. Note that v8 constructs may not be used on the thread pool, so
data types must be passed into the sync code blocks as eio_request
structs.
See these examples to get started building a binding that leverages eio and node-waf:
Example hello-world-ish programs:
Some "real" examples:
- https://github.com/pkrumins/node-png
- https://github.com/mranney/node_pcap
- https://github.com/ry/node_postgres
- https://github.com/isaacs/node-glob
If you have a lot of JavaScript code, then the custom is to put it in
the ./lib
folder in your project.
Specify a main
module in your package.json file. This is the module
that your users will load when they do require('your-library')
. This
module should ideally expose all of the functionality in your library.
If you want your users to be able to load sub-modules from the "guts" of your library, then they'll need to specify the full path to them. That is a lot of work to document! It's better and more future-proof to simply specify a main module, and then, if necessary, have ways to dynamically load what they need.
For example, you might have a flip
library that is a collection of
widget
objects, defined by files in the flip/lib/widgets/*.js
files.
Rather than having your users do require('flip/lib/widgets/blerg.js')
to get the blerg widget, it's better to have something like:
require('flip').loadWidget('blerg')
.
Of course, a library may also include a build step that compiles an add-on that it uses.
The only feature that differentiates a command-line program from a
library is the bin
field in the package.json file.
When installed with npm, the bin
field in a package.json file tells
npm to create an executable in the PATH that runs your program.
In a nodejs script, the process.argv
is an array of strings that
represent the command the user started node with. The first item is
always node, and the second is always your program. Generally, the
arguments to your program can be retrieved via:
var args = process.argv.slice(2)
There are a variety of option parsing libraries available via npm.
The current working directory can be found by calling process.cwd()
,
and changed with process.chdir(newPath)
.