UNPKG

2.9 kBJavaScriptView Raw
1const { sep, join, dirname } = require('path');
2const { existsSync, statSync, readFileSync } = require('fs-extra');
3
4function startsWith(prevString, nextString) {
5 return prevString.indexOf(nextString) === 0;
6}
7
8function loadAsFile(module, extension) {
9 if (existsSync(module + extension) && statSync(module + extension).isFile()) {
10 return module + extension;
11 }
12
13 if (existsSync(module) && statSync(module).isFile()) {
14 return module;
15 }
16}
17
18function loadAsDirectory(module, extension) {
19 if (!existsSync(module)) {
20 return;
21 }
22
23 let stat = statSync(module);
24
25 if (stat.isDirectory()) {
26 let packagePath = module + '/package.json';
27 if (existsSync(packagePath) && statSync(packagePath).isFile()) {
28 let pkg = JSON.parse(readFileSync(packagePath, 'utf-8'));
29 let main = join(module, pkg.main || 'index' + extension);
30 return loadAsFile(main) || loadAsDirectory(main);
31 } else if (existsSync(module + '/index' + extension) && statSync(module + '/index' + extension).isFile()) {
32 return join(module, '/index' + extension);
33 }
34 } else if (stat.isFile()) {
35 return loadAsFile(module, extension);
36 }
37}
38
39function nodeModulesPaths(start) {
40 let parts = start.split(sep);
41
42 if (!parts[parts.length - 1]) {
43 parts.pop();
44 }
45
46 let i = parts.length - 1;
47 let dirs = [];
48 while (i >= 0) {
49 if ('node_modules' === parts[i]) {
50 i -= 1;
51 continue;
52 }
53 let dir = join(parts.slice(0, i + 1).join(sep) || sep, 'node_modules');
54 dirs.push(dir);
55 i -= 1;
56 }
57 return dirs;
58}
59
60function loadNpmModules(module, start, extension) {
61 let target;
62 let paths = nodeModulesPaths(start);
63
64 for (let i = 0; i < paths.length; ++i) {
65 let dependencyPath = join(paths[i], module);
66 target = loadAsFile(dependencyPath, extension) || loadAsDirectory(dependencyPath, extension);
67
68 if (target) {
69 break;
70 }
71 }
72 return target;
73}
74
75/**
76 * Resolve node path.
77 * @param {string} script
78 * @param {string} dependency
79 * @param {string} extension
80 * @return {*}
81 */
82function moduleResolve(script, dependency, extension = '.js') {
83 let target;
84
85 if (startsWith(dependency, './') || startsWith(dependency, '/') || startsWith(dependency, '../')) {
86 let dependencyPath = join(script, dependency);
87 target = loadAsFile(dependencyPath, extension) || loadAsDirectory(dependencyPath, extension);
88 } else {
89 target = loadNpmModules(dependency, dirname(script), extension);
90 }
91 return target;
92};
93
94/**
95 *
96 *
97 * @param {string} script
98 * @param {string} dependency
99 * @param {array<string>} [extensions=[]]
100 * @returns
101 */
102function multipleModuleResolve(script, dependency, extensions = []) {
103 for (let extension of extensions) {
104 const target = moduleResolve(script, dependency, extension);
105 if (target) {
106 return target;
107 }
108 }
109 return null;
110}
111
112module.exports = {
113 moduleResolve,
114 multipleModuleResolve
115};