Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
inxilpro committed Oct 31, 2019
2 parents bdd59ea + 26cd05e commit 54d06fe
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 21 deletions.
6 changes: 5 additions & 1 deletion README.md
Expand Up @@ -90,6 +90,10 @@ you want. `app-root-path` is aware of this edge-case and will strip the `/bin` a

## Change Log

### 3.0.0
- Improved Yarn Plug'n'Play support
- Fixed bug when used with webpack

### 2.2.1
- Better handling of webpack

Expand Down Expand Up @@ -148,4 +152,4 @@ This helps ensure that commits match the expected format. Commits to `master` w
[david-dm-img]: https://david-dm.org/inxilpro/node-app-root-path.svg
[david-dm]: https://david-dm.org/inxilpro/node-app-root-path
[codecov-img]: https://codecov.io/gh/inxilpro/node-app-root-path/branch/master/graph/badge.svg
[codecov]: https://codecov.io/gh/inxilpro/node-app-root-path
[codecov]: https://codecov.io/gh/inxilpro/node-app-root-path
45 changes: 37 additions & 8 deletions lib/resolve.js
Expand Up @@ -23,6 +23,30 @@ var requireFunction = ("function" === typeof __webpack_require__ || "function" =
? __non_webpack_require__
: require;

const isInstalledWithPNPM = function(resolved) {
const pnpmDir = sep + '.pnpm';

for (const globalPath of globalPaths) {
if (-1 !== globalPath.indexOf(pnpmDir) && -1 !== resolved.indexOf(pnpmDir)) {
return true;
}
}
return false;
}

const getFirstPartFromNodeModules = function(resolved) {
const nodeModulesDir = sep + 'node_modules';

if (-1 !== resolved.indexOf(nodeModulesDir)) {
const parts = resolved.split(nodeModulesDir);
if (parts.length) {
return parts[0];
}
}

return null;
}

// Resolver
module.exports = function resolve(dirname) {
// Check for environmental variable
Expand Down Expand Up @@ -55,6 +79,16 @@ module.exports = function resolve(dirname) {
var alternateMethod = false;
var appRootPath = null;

// Check if the globalPaths contain some folders with '.pnpm' in the path
// If yes this means it is most likely installed with pnpm
if (isInstalledWithPNPM(resolved)) {
appRootPath = getFirstPartFromNodeModules(resolved);

if (appRootPath) {
return appRootPath;
}
}

// Make sure that we're not loaded from a global include path
// Eg. $HOME/.node_modules
// $HOME/.node_libraries
Expand All @@ -67,19 +101,14 @@ module.exports = function resolve(dirname) {

// If the app-root-path library isn't loaded globally,
// and node_modules exists in the path, just split __dirname
var nodeModulesDir = sep + 'node_modules';
if (!alternateMethod && -1 !== resolved.indexOf(nodeModulesDir)) {
var parts = resolved.split(nodeModulesDir);
if (parts.length) {
appRootPath = parts[0];
parts = null;
}
if (!alternateMethod) {
appRootPath = getFirstPartFromNodeModules(resolved);
}

// If the above didn't work, or this module is loaded globally, then
// resort to require.main.filename (See http://nodejs.org/api/modules.html)
if (alternateMethod || null == appRootPath) {
appRootPath = path.dirname(require.main.filename);
appRootPath = path.dirname(requireFunction.main.filename);
}

// Handle global bin/ directory edge-case
Expand Down
65 changes: 53 additions & 12 deletions test/index.js
Expand Up @@ -4,9 +4,16 @@ var path = require('path');
var assert = require('assert');
var mockery = require('mockery');

function globalPathsContainPnpm() {
return undefined !== require('module').globalPaths.find(function(e) {
return e.indexOf('.pnpm') !== -1
});
}

describe('The path resolution method', function() {
var resolve = require('../lib/resolve.js');
var originalReqMainFilename = require.main.filename;
const isPnpm = globalPathsContainPnpm();

// Make sure env variable isn't set for tests
if (process.env.APP_ROOT_PATH) {
Expand All @@ -21,14 +28,53 @@ describe('The path resolution method', function() {
require.main.filename = originalReqMainFilename;
});

// Check global paths
it('should use require.main.filename if the path is in the globalPaths array', function() {
var expected = path.dirname(require.main.filename);
require('module').globalPaths.forEach(function(globalPath) {
var testPath = globalPath + path.sep + 'node-app-root-path';
assert.equal(resolve(testPath), expected);
if (isPnpm) {
it('should use require.main.filename if the path is in the globalPaths array (PNPM)', function() {
var expected = path.dirname(require.main.filename);
var root = path.resolve(__dirname, '..');

require('module').globalPaths.forEach(function(globalPath) {
var testPath = globalPath + path.sep + 'node-app-root-path';

if (-1 !== testPath.indexOf('.pnpm')) {
assert.equal(resolve(testPath), root);
} else {
assert.equal(resolve(testPath), expected);
}
});
});

// Check pnpm
it('should use String.split() if installed with pnpm', function() {
var cases = [
'/var/www/node_modules/.pnpm/node_modules/node-app-root-path',
'/var/www/node_modules/.pnpm/custom_registry/node-app-root-path',
];
var expected = '/var/www';

cases.forEach(function(testPath) {
assert.equal(resolve(testPath), expected);
});
});
});

// Check root path
it('should still use String.split() in the root directory (PNPM)', function() {
assert.equal(resolve('/node_modules'), path.dirname(require.main.filename));
});
} else {
it('should use require.main.filename if the path is in the globalPaths array', function() {
var expected = path.dirname(require.main.filename);
require('module').globalPaths.forEach(function(globalPath) {
var testPath = globalPath + path.sep + 'node-app-root-path';
assert.equal(resolve(testPath), expected);
});
});

// Check root path
it('should still use String.split() in the root directory', function() {
assert.equal(resolve('/node_modules'), '');
});
}

// Check bin/ dir in global path
it('should correctly handle the global bin/ edge case', function() {
Expand All @@ -54,11 +100,6 @@ describe('The path resolution method', function() {
});
});

// Check root path
it('should still use String.split() in the root directory', function() {
assert.equal(resolve('/node_modules'), '');
});

// Check unexpected path
it('should use require.main.filename on unexpected input', function() {
var cases = [
Expand Down

0 comments on commit 54d06fe

Please sign in to comment.