1 | const path = require('path');
|
2 | const fs = require('fs');
|
3 | const cwd = process.cwd();
|
4 |
|
5 | // Previously, we use require.resolve(packageName + '/package.json')
|
6 | // to find the package's meta file.
|
7 | // But new field exports in package.json might now prevent resolving
|
8 | // '/package.json'.
|
9 | // So we have to use custom method to manually search the package.
|
10 | // Note some npm package (like font-awesome v4) has no main file,
|
11 | // so require.resolve(packageName) may not work too.
|
12 | function packageFolder(packageName, fromDir) {
|
13 | // eslint-disable-next-line no-constant-condition
|
14 | while (true) {
|
15 | const testDir = path.join(fromDir, 'node_modules', packageName);
|
16 | if (fs.existsSync(path.join(testDir, 'package.json'))) {
|
17 | return testDir;
|
18 | }
|
19 | const parentDir = path.dirname(fromDir);
|
20 | if (parentDir === fromDir) return;
|
21 | fromDir = parentDir;
|
22 | }
|
23 | }
|
24 |
|
25 | module.exports = function(packageName) {
|
26 | const found =
|
27 | // try from dumber first
|
28 | packageFolder(packageName, __dirname) ||
|
29 | // try from app's local folder, this is necessary to support lerna
|
30 | // hoisting where dumber is out of app's local node_modules folder.
|
31 | packageFolder(packageName, cwd);
|
32 |
|
33 | if (!found) {
|
34 | throw new Error('cannot find npm package: ' + packageName);
|
35 | }
|
36 | return found;
|
37 | };
|