sync.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. var core = require('./core');
  2. var fs = require('fs');
  3. var path = require('path');
  4. var caller = require('./caller.js');
  5. var nodeModulesPaths = require('./node-modules-paths.js');
  6. var defaultIsFile = function isFile(file) {
  7. try {
  8. var stat = fs.statSync(file);
  9. } catch (e) {
  10. if (e && (e.code === 'ENOENT' || e.code === 'ENOTDIR')) return false;
  11. throw e;
  12. }
  13. return stat.isFile() || stat.isFIFO();
  14. };
  15. module.exports = function (x, options) {
  16. if (typeof x !== 'string') {
  17. throw new TypeError('Path must be a string.');
  18. }
  19. var opts = options || {};
  20. var isFile = opts.isFile || defaultIsFile;
  21. var readFileSync = opts.readFileSync || fs.readFileSync;
  22. var extensions = opts.extensions || ['.js'];
  23. var basedir = opts.basedir || path.dirname(caller());
  24. opts.paths = opts.paths || [];
  25. if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
  26. var res = path.resolve(basedir, x);
  27. if (x === '..' || x.slice(-1) === '/') res += '/';
  28. var m = loadAsFileSync(res) || loadAsDirectorySync(res);
  29. if (m) return m;
  30. } else {
  31. var n = loadNodeModulesSync(x, basedir);
  32. if (n) return n;
  33. }
  34. if (core[x]) return x;
  35. var err = new Error("Cannot find module '" + x + "' from '" + basedir + "'");
  36. err.code = 'MODULE_NOT_FOUND';
  37. throw err;
  38. function loadAsFileSync(x) {
  39. var pkg = loadpkg(path.dirname(x));
  40. if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) {
  41. var rfile = path.relative(pkg.dir, x);
  42. var r = opts.pathFilter(pkg.pkg, x, rfile);
  43. if (r) {
  44. x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign
  45. }
  46. }
  47. if (isFile(x)) {
  48. return x;
  49. }
  50. for (var i = 0; i < extensions.length; i++) {
  51. var file = x + extensions[i];
  52. if (isFile(file)) {
  53. return file;
  54. }
  55. }
  56. }
  57. function loadpkg(dir) {
  58. if (dir === '' || dir === '/') return;
  59. if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
  60. return;
  61. }
  62. if (/[/\\]node_modules[/\\]*$/.test(dir)) return;
  63. var pkgfile = path.join(dir, 'package.json');
  64. if (!isFile(pkgfile)) {
  65. return loadpkg(path.dirname(dir));
  66. }
  67. var body = readFileSync(pkgfile);
  68. try {
  69. var pkg = JSON.parse(body);
  70. } catch (jsonErr) {}
  71. if (pkg && opts.packageFilter) {
  72. pkg = opts.packageFilter(pkg, dir);
  73. }
  74. return { pkg: pkg, dir: dir };
  75. }
  76. function loadAsDirectorySync(x) {
  77. var pkgfile = path.join(x, '/package.json');
  78. if (isFile(pkgfile)) {
  79. try {
  80. var body = readFileSync(pkgfile, 'UTF8');
  81. var pkg = JSON.parse(body);
  82. if (opts.packageFilter) {
  83. pkg = opts.packageFilter(pkg, x);
  84. }
  85. if (pkg.main) {
  86. if (pkg.main === '.' || pkg.main === './') {
  87. pkg.main = 'index';
  88. }
  89. var m = loadAsFileSync(path.resolve(x, pkg.main));
  90. if (m) return m;
  91. var n = loadAsDirectorySync(path.resolve(x, pkg.main));
  92. if (n) return n;
  93. }
  94. } catch (e) {}
  95. }
  96. return loadAsFileSync(path.join(x, '/index'));
  97. }
  98. function loadNodeModulesSync(x, start) {
  99. var dirs = nodeModulesPaths(start, opts);
  100. for (var i = 0; i < dirs.length; i++) {
  101. var dir = dirs[i];
  102. var m = loadAsFileSync(path.join(dir, '/', x));
  103. if (m) return m;
  104. var n = loadAsDirectorySync(path.join(dir, '/', x));
  105. if (n) return n;
  106. }
  107. }
  108. };