Browse Source

support for package.json

This adds basic support for situations where there is a package.json
with a "main" field.  That "main" module is used as the code that is
loaded when the package folder is required.
v0.7.4-release
isaacs 14 years ago
committed by Ryan Dahl
parent
commit
da2f4b2dc4
  1. 13
      doc/api/modules.markdown
  2. 32
      lib/module.js
  3. 1
      test/fixtures/packages/main/package-main-module.js
  4. 3
      test/fixtures/packages/main/package.json
  5. 4
      test/simple/test-module-loading.js

13
doc/api/modules.markdown

@ -69,6 +69,19 @@ interrupting once a file is found. Files ending in `'.node'` are binary Addon
Modules; see 'Addons' below. `'index.js'` allows one to package a module as Modules; see 'Addons' below. `'index.js'` allows one to package a module as
a directory. a directory.
Additionally, a `package.json` file may be used to treat a folder as a
module, if it specifies a `'main'` field. For example, if the file at
`./foo/bar/package.json` contained this data:
{ "name" : "bar",
"version" : "1.2.3",
"main" : "./lib/bar.js" }
then `require('./foo/bar')` would load the file at
`'./foo/bar/lib/bar.js'`. This allows package authors to specify an
entry point to their module, while structuring their package how it
suits them.
`require.paths` can be modified at runtime by simply unshifting new `require.paths` can be modified at runtime by simply unshifting new
paths onto it, or at startup with the `NODE_PATH` environmental paths onto it, or at startup with the `NODE_PATH` environmental
variable (which should be a list of paths, colon separated). variable (which should be a list of paths, colon separated).

32
lib/module.js

@ -60,6 +60,34 @@ function statPath(path) {
return false; return false;
} }
// check if the directory is a package.json dir
var packageCache = {};
function readPackage(requestPath) {
if (packageCache.hasOwnProperty(requestPath)) {
return packageCache[requestPath];
}
var fs = NativeModule.require('fs');
try {
var jsonPath = path.resolve(requestPath, 'package.json');
var json = fs.readFileSync(jsonPath, 'utf8');
var pkg = packageCache[requestPath] = JSON.parse(json);
return pkg;
} catch (e) {}
return false;
}
function tryPackage(requestPath, exts) {
var pkg = readPackage(requestPath);
if (!pkg || !pkg.main) return false;
var filename = path.resolve(requestPath, pkg.main);
return tryFile(filename) || tryExtensions(filename, exts);
}
// check if the file exists and is not a directory // check if the file exists and is not a directory
function tryFile(requestPath) { function tryFile(requestPath) {
var fs = NativeModule.require('fs'); var fs = NativeModule.require('fs');
@ -113,6 +141,10 @@ Module._findPath = function(request, paths) {
} }
} }
if (!filename) {
filename = tryPackage(basePath, exts);
}
if (!filename) { if (!filename) {
// try it with each of the extensions at "index" // try it with each of the extensions at "index"
filename = tryExtensions(path.resolve(basePath, 'index'), exts); filename = tryExtensions(path.resolve(basePath, 'index'), exts);

1
test/fixtures/packages/main/package-main-module.js

@ -0,0 +1 @@
exports.ok = "ok"

3
test/fixtures/packages/main/package.json

@ -0,0 +1,3 @@
{"name":"package-name"
,"version":"1.2.3"
,"main":"package-main-module"}

4
test/simple/test-module-loading.js

@ -67,6 +67,10 @@ var three = require('../fixtures/nested-index/three'),
assert.equal(threeFolder, threeIndex); assert.equal(threeFolder, threeIndex);
assert.notEqual(threeFolder, three); assert.notEqual(threeFolder, three);
common.debug('test package.json require() loading');
assert.equal(require('../fixtures/packages/main').ok, 'ok',
'Failed loading package');
common.debug('test cycles containing a .. path'); common.debug('test cycles containing a .. path');
var root = require('../fixtures/cycles/root'), var root = require('../fixtures/cycles/root'),
foo = require('../fixtures/cycles/folder/foo'); foo = require('../fixtures/cycles/folder/foo');

Loading…
Cancel
Save