Skip to content

Commit ee998b9

Browse files
waliscXhmikosR
authored andcommitted
catering for nested/local node_modules
1 parent dc6fc69 commit ee998b9

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

index.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const fs = require('node:fs');
4+
const path = require('node:path');
45
const { debuglog } = require('node:util');
56
const cabinet = require('filing-cabinet');
67
const precinct = require('precinct');
@@ -161,6 +162,7 @@ function traverse(config = {}) {
161162
for (const dependency of dependencies) {
162163
const localConfig = config.clone();
163164
localConfig.filename = dependency;
165+
localConfig.directory = getDirectory(localConfig);
164166

165167
if (localConfig.isListForm) {
166168
for (const item of traverse(localConfig)) {
@@ -192,3 +194,26 @@ function dedupeNonExistent(nonExistent) {
192194
i++;
193195
}
194196
}
197+
198+
//If the file is in a node module, use the root directory of the module
199+
function getDirectory(localConfig){
200+
function _getProjectPath(filename) {
201+
try{
202+
const nodeModuleParts = filename.split('node_modules')
203+
const packageSubPathPath = nodeModuleParts.pop().split(path.sep).filter(function(v){ return !!v})
204+
const packageName = packageSubPathPath[0].startsWith("@") ? `${packageSubPathPath[0]}${path.sep}${packageSubPathPath[1]}` : packageSubPathPath[0]
205+
206+
return path.join(...nodeModuleParts, 'node_modules', packageName)
207+
}
208+
catch(err){
209+
debug(`Could not determine the root directory of package file ${filename}. Using default`);
210+
return null
211+
}
212+
}
213+
214+
if (!localConfig.filename.includes('node_modules')){
215+
return localConfig.directory
216+
}
217+
218+
return _getProjectPath(path.dirname(localConfig.filename)) || localConfig.directory
219+
}

test/test.mjs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,79 @@ describe('dependencyTree', () => {
472472
});
473473
});
474474

475+
describe("It uses package specific node_module directory when resolving package dependencies", () => {
476+
testTreesForFormat('commonjs');
477+
478+
it('It can find sub package in node module package', () => {
479+
mockfs({
480+
[path.join(__dirname, '/es6')]: {
481+
'module.entry.js': 'import * as module from "parent_module_a"',
482+
node_modules: { // eslint-disable-line camelcase
483+
'parent_module_a': {
484+
'index.main.js': 'import * as child_module from "child_node_module"; module.exports = child_module;',
485+
'package.json': '{ "main": "index.main.js"}',
486+
node_modules: {
487+
child_node_module: {
488+
'index.main.js': 'module.exports = "child_node_module_of_parent_a"',
489+
'package.json': '{ "main": "index.main.js"}',
490+
}
491+
}
492+
}
493+
}
494+
}
495+
});
496+
497+
const directory = path.join(__dirname, '/es6');
498+
const filename = path.normalize(`${directory}/module.entry.js`);
499+
500+
const treeList = dependencyTree({
501+
filename,
502+
directory,
503+
isListForm: true
504+
});
505+
506+
assert.ok(treeList.includes(path.normalize(`${directory}/node_modules/parent_module_a/node_modules/child_node_module/index.main.js`)));
507+
});
508+
509+
510+
it('it usues correct version of sub package in node module package', () => {
511+
mockfs({
512+
[path.join(__dirname, '/es6')]: {
513+
'module.entry.js': 'import * as module from "parent_module_a"',
514+
node_modules: { // eslint-disable-line camelcase
515+
child_node_module: {
516+
'index.main.js': 'module.exports = "child_node_module"',
517+
'package.json': '{ "main": "index.main.js", "version": "2.0.0"}',
518+
},
519+
parent_module_a: {
520+
'index.main.js': 'import * as child_module from "child_node_module"; module.exports = child_module;',
521+
'package.json': '{ "main": "index.main.js"}',
522+
node_modules: {
523+
child_node_module: {
524+
'index.main.js': 'module.exports = "child_node_module_of_parent_a"',
525+
'package.json': '{ "main": "index.main.js", "version": "1.0.0"}',
526+
}
527+
}
528+
}
529+
}
530+
}
531+
});
532+
533+
const directory = path.join(__dirname, '/es6');
534+
const filename = path.normalize(`${directory}/module.entry.js`);
535+
536+
const treeList = dependencyTree({
537+
filename,
538+
directory,
539+
isListForm: true
540+
});
541+
542+
assert.ok(!treeList.includes(path.normalize(`${directory}/node_modules/child_node_module/index.main.js`)));
543+
assert.ok(treeList.includes(path.normalize(`${directory}/node_modules/parent_module_a/node_modules/child_node_module/index.main.js`)));
544+
545+
});
546+
})
547+
475548
describe('module formats', () => {
476549
describe('amd', () => {
477550
testTreesForFormat('amd');

0 commit comments

Comments
 (0)