Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I package a node module with optional submodules?

I'm writing a javascript library that contains a core module and several optional submodules which extend the core module. My target is the browser environment (using Browserify), where I expect a user of my module will only want to use some of my optional submodules and not have to download the rest to the client--much like custom builds work in lodash.

The way I imagine this working:

// Require the core library
var Tasks = require('mymodule');
// We need yaks
require('mymodule/yaks');
// We need razors
require('mymodule/razors');

var tasks = new Tasks();    // Core mymodule functionality
var yak = tasks.find_yak(); // Provided by mymodule/yaks
tasks.shave(yak);           // Provided by mymodule/razors

Now, imagine that the mymodule/* namespace has tens of these submodules. The user of the mymodule library only needs to incur the bandwidth cost of the submodules that she uses, but there's no need for an offline build process like lodash uses: a tool like Browserify solves the dependency graph for us and only includes the required code.

Is it possible to package something this way using Node/npm? Am I delusional?

Update: An answer over here seems to suggest that this is possible, but I can't figure out from the npm documentation how to actually structure the files and package.json.

Say that I have these files:

./lib/mymodule.js
./lib/yaks.js
./lib/razors.js
./lib/sharks.js
./lib/jets.js

In my package.json, I'll have:

  "main": "./lib/mymodule.js"

But how will node know about the other files under ./lib/?

like image 801
David Eyk Avatar asked Jun 25 '15 21:06

David Eyk


1 Answers

It's simpler than it seems -- when you require a package by it's name, it gets the "main" file. So require('mymodule') returns "./lib/mymodule.js" (per your package.json "main" prop). To require optional submodules directly, simply require them via their file path.

So to get the yaks submodule: require('mymodule/lib/yaks'). If you wanted to do require('mymodule/yaks') you would need to either change your file structure to match that (move yaks.js to the root folder) or do something tricky where there's a yaks.js at the root and it just does something like: module.exports = require('./lib/yaks');.

Good luck with this yak lib. Sounds hairy :)

like image 81
ccnokes Avatar answered Nov 15 '22 08:11

ccnokes