From 5218f0106e78edce4cfb905d0ea4492ed3fd38af Mon Sep 17 00:00:00 2001 From: James Halliday Date: Sat, 18 Jun 2011 02:36:37 -0700 Subject: [PATCH] implementation seems to work but no tests yet --- README.markdown | 11 ++++--- index.js | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 6 deletions(-) create mode 100644 index.js diff --git a/README.markdown b/README.markdown index cda076b8..bc3d1688 100644 --- a/README.markdown +++ b/README.markdown @@ -7,16 +7,15 @@ except you can pass in the file to compute paths relatively to along with your own `require.paths` without updating the global copy (which doesn't even work in node `>=0.5`). -example -======= - methods ======= -resolve(pkg, opts={paths:[],path:__filename}) ---------------------------------------------- +var resolve = require('resolve'); + +resolve.sync(pkg, opts={paths:[],path:__filename}) +-------------------------------------------------- -Search for the package/filename `pkg` +Synchronously search for the package/filename string `pkg` according to the [`require.resolve()` algorithm](http://nodejs.org/docs/v0.4.8/api/all.html#all_Together...) for `X=pkg` and `Y=opts.path`. diff --git a/index.js b/index.js new file mode 100644 index 00000000..0c5a8d35 --- /dev/null +++ b/index.js @@ -0,0 +1,77 @@ +var fs = require('fs'); +var path = require('path'); + +// http://nodejs.org/docs/v0.4.8/api/all.html#all_Together... + +var core = [ 'assert', 'buffer', 'child_process', 'crypto', 'dgram', 'dns', + 'events', 'fs', 'http', 'https', 'net', 'os', 'path', 'querystring', 'repl', + 'stream', 'sys', 'tls', 'tty', 'url', 'util', 'vm' +].reduce(function (acc, x) { acc[x] = true; return acc }, {}); + +exports.sync = function (x, opts) { + if (core[x]) return x; + + if (!opts) opts = {}; + var y = opts.path || require.cache[__filename].parent.filename; + + if (x.match(/^(?:\.\/|\/|\.\.\/)/)) { + var m = loadAsFileSync(y + x) || loadAsDirectorySync(y + x); + if (m) return m; + } + + var n = loadNodeModulesSync(x, path.dirname(y)); + if (n) return n; + + throw new Error("Cannot find module '" + x + "'"); +} + +function loadAsFileSync (x) { + if (path.existsSync(x) && fs.statSync(x).isFile()) { + return x; + } + else if (path.existsSync(x + '.js') && fs.statSync(x + '.js').isFile()) { + return x + '.js'; + } +} + +function loadAsDirectorySync (x) { + var pkgfile = x + '/package.json'; + if (path.existsSync(pkgfile) && fs.statSync(pkgfile).isFile()) { + var body = fs.readFileSync(pkgfile, 'utf8'); + try { + var pkg = JSON.parse(body); + if (pkg.main) { + var m = loadAsFileSync(path.resolve(x, pkg.main)); + if (m) return m; + } + } + catch (err) {} + } + + return loadAsFileSync(x + '/index'); +} + +function loadNodeModulesSync (x, start) { + var dirs = nodeModulesPathsSync(start); + for (var i = 0; i < dirs.length; i++) { + var dir = dirs[i]; + var m = loadAsFileSync(dir + '/' + x); + if (m) return m; + var n = loadAsDirectorySync(dir + '/' + x); + if (n) return n; + } +} + +function nodeModulesPathsSync (start) { + var parts = start.split(/\/+/); + var root = parts.indexOf('node_modules'); + if (root < 0) root = 0; + + var dirs = []; + for (var i = parts.length - 1; i >= root; i--) { + if (parts[i] === 'node_modules') continue; + var dir = parts.slice(0, i + 1).join('/') + '/node_modules'; + dirs.push(dir); + } + return dirs; +}