UNPKG

3.83 kBJavaScriptView Raw
1'use strict';
2
3// Dependencies
4var path = require('path');
5
6// Load global paths
7var globalPaths = require('module').globalPaths;
8
9// Guess at NPM's global install dir
10var npmGlobalPrefix;
11if ('win32' === process.platform) {
12 npmGlobalPrefix = path.dirname(process.execPath);
13} else {
14 npmGlobalPrefix = path.dirname(path.dirname(process.execPath));
15}
16var npmGlobalModuleDir = path.resolve(npmGlobalPrefix, 'lib', 'node_modules');
17
18// Save OS-specific path separator
19var sep = path.sep;
20
21// If we're in webpack, force it to use the original require() method
22var requireFunction = ("function" === typeof __webpack_require__ || "function" === typeof __non_webpack_require__)
23 ? __non_webpack_require__
24 : require;
25
26const isInstalledWithPNPM = function(resolved) {
27 const pnpmDir = sep + '.pnpm';
28
29 for (const globalPath of globalPaths) {
30 if (-1 !== globalPath.indexOf(pnpmDir) && -1 !== resolved.indexOf(pnpmDir)) {
31 return true;
32 }
33 }
34 return false;
35}
36
37const getFirstPartFromNodeModules = function(resolved) {
38 const nodeModulesDir = sep + 'node_modules';
39
40 if (-1 !== resolved.indexOf(nodeModulesDir)) {
41 const parts = resolved.split(nodeModulesDir);
42 if (parts.length) {
43 return parts[0];
44 }
45 }
46
47 return null;
48}
49
50// Resolver
51module.exports = function resolve(dirname) {
52 // Check for environmental variable
53 if (process.env.APP_ROOT_PATH) {
54 return path.resolve(process.env.APP_ROOT_PATH);
55 }
56
57 // Defer to Yarn Plug'n'Play if enabled
58 if (process.versions.pnp) {
59 try {
60 var pnp = requireFunction('pnpapi');
61 return pnp.getPackageInformation(pnp.topLevel).packageLocation;
62 } catch (e) {}
63 }
64
65 // Defer to main process in electron renderer
66 if ('undefined' !== typeof window && window.process && 'renderer' === window.process.type) {
67 try {
68 var remote = requireFunction('electron').remote;
69 return remote.require('app-root-path').path;
70 } catch (e) {}
71 }
72
73 // Defer to AWS Lambda when executing there
74 if (process.env.LAMBDA_TASK_ROOT && process.env.AWS_EXECUTION_ENV) {
75 return process.env.LAMBDA_TASK_ROOT;
76 }
77
78 var resolved = path.resolve(dirname);
79 var alternateMethod = false;
80 var appRootPath = null;
81
82 // Check if the globalPaths contain some folders with '.pnpm' in the path
83 // If yes this means it is most likely installed with pnpm
84 if (isInstalledWithPNPM(resolved)) {
85 appRootPath = getFirstPartFromNodeModules(resolved);
86
87 if (appRootPath) {
88 return appRootPath;
89 }
90 }
91
92 // Make sure that we're not loaded from a global include path
93 // Eg. $HOME/.node_modules
94 // $HOME/.node_libraries
95 // $PREFIX/lib/node
96 globalPaths.forEach(function(globalPath) {
97 if (!alternateMethod && 0 === resolved.indexOf(globalPath)) {
98 alternateMethod = true;
99 }
100 });
101
102 // If the app-root-path library isn't loaded globally,
103 // and node_modules exists in the path, just split __dirname
104 if (!alternateMethod) {
105 appRootPath = getFirstPartFromNodeModules(resolved);
106 }
107
108 // If the above didn't work, or this module is loaded globally, then
109 // resort to require.main.filename (See http://nodejs.org/api/modules.html)
110 if ((alternateMethod || null == appRootPath)) {
111 if (requireFunction.main) {
112 appRootPath = path.dirname(requireFunction.main.filename);
113 } else {
114 // This is the case when app-root-path is bundle'd to a commonjs2 format and is being called from an esm file.
115 // In those cases require.main is undefined (See https://nodejs.org/api/modules.html#accessing-the-main-module)
116 // At that point we can only get the root from looking at the callee
117 appRootPath = path.dirname(process.argv[1]);
118 }
119 }
120
121 // Handle global bin/ directory edge-case
122 if (alternateMethod && -1 !== appRootPath.indexOf(npmGlobalModuleDir) && (appRootPath.length - 4) === appRootPath.indexOf(sep + 'bin')) {
123 appRootPath = appRootPath.slice(0, -4);
124 }
125
126 // Return
127 return appRootPath;
128};