sync.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. var parent = opts.filename || basedir;
  25. opts.paths = opts.paths || [];
  26. if (/^(?:\.\.?(?:\/|$)|\/|([A-Za-z]:)?[/\\])/.test(x)) {
  27. var res = path.resolve(basedir, x);
  28. if (x === '..' || x.slice(-1) === '/') res += '/';
  29. var m = loadAsFileSync(res) || loadAsDirectorySync(res);
  30. if (m) return m;
  31. } else {
  32. var n = loadNodeModulesSync(x, basedir);
  33. if (n) return n;
  34. }
  35. if (core[x]) return x;
  36. var err = new Error("Cannot find module '" + x + "' from '" + parent + "'");
  37. err.code = 'MODULE_NOT_FOUND';
  38. throw err;
  39. function loadAsFileSync(x) {
  40. var pkg = loadpkg(path.dirname(x));
  41. if (pkg && pkg.dir && pkg.pkg && opts.pathFilter) {
  42. var rfile = path.relative(pkg.dir, x);
  43. var r = opts.pathFilter(pkg.pkg, x, rfile);
  44. if (r) {
  45. x = path.resolve(pkg.dir, r); // eslint-disable-line no-param-reassign
  46. }
  47. }
  48. if (isFile(x)) {
  49. return x;
  50. }
  51. for (var i = 0; i < extensions.length; i++) {
  52. var file = x + extensions[i];
  53. if (isFile(file)) {
  54. return file;
  55. }
  56. }
  57. }
  58. function loadpkg(dir) {
  59. if (dir === '' || dir === '/') return;
  60. if (process.platform === 'win32' && (/^\w:[/\\]*$/).test(dir)) {
  61. return;
  62. }
  63. if (/[/\\]node_modules[/\\]*$/.test(dir)) return;
  64. var pkgfile = path.join(dir, 'package.json');
  65. if (!isFile(pkgfile)) {
  66. return loadpkg(path.dirname(dir));
  67. }
  68. var body = readFileSync(pkgfile);
  69. try {
  70. var pkg = JSON.parse(body);
  71. } catch (jsonErr) {}
  72. if (pkg && opts.packageFilter) {
  73. pkg = opts.packageFilter(pkg, dir);
  74. }
  75. return { pkg: pkg, dir: dir };
  76. }
  77. function loadAsDirectorySync(x) {
  78. var pkgfile = path.join(x, '/package.json');
  79. if (isFile(pkgfile)) {
  80. try {
  81. var body = readFileSync(pkgfile, 'UTF8');
  82. var pkg = JSON.parse(body);
  83. if (opts.packageFilter) {
  84. pkg = opts.packageFilter(pkg, x);
  85. }
  86. if (pkg.main) {
  87. if (pkg.main === '.' || pkg.main === './') {
  88. pkg.main = 'index';
  89. }
  90. var m = loadAsFileSync(path.resolve(x, pkg.main));
  91. if (m) return m;
  92. var n = loadAsDirectorySync(path.resolve(x, pkg.main));
  93. if (n) return n;
  94. }
  95. } catch (e) {}
  96. }
  97. return loadAsFileSync(path.join(x, '/index'));
  98. }
  99. function loadNodeModulesSync(x, start) {
  100. var dirs = nodeModulesPaths(start, opts);
  101. for (var i = 0; i < dirs.length; i++) {
  102. var dir = dirs[i];
  103. var m = loadAsFileSync(path.join(dir, '/', x));
  104. if (m) return m;
  105. var n = loadAsDirectorySync(path.join(dir, '/', x));
  106. if (n) return n;
  107. }
  108. }
  109. };