Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npm install "no such file or directory '.../package.json'" for custom modules

Tags:

node.js

npm

I have some folders symlinked to node_modules in order to be able to import them as modules. For example, I have src/client/apps/admin directory which is symlinked to node_modules/@admin. But npm gives me these warnings when I'm trying to install or remove any modules

$ npm i -S connect-roles
...

npm WARN ENOENT ENOENT: no such file or directory, open '/Users/Admin/Code/www/learn/src/client/apps/admin/assets/package.json'
npm WARN ENOENT ENOENT: no such file or directory, open '/Users/Admin/Code/www/learn/src/client/apps/admin/components/package.json'
npm WARN ENOENT ENOENT: no such file or directory, open '/Users/Admin/Code/www/learn/src/client/apps/admin/reducers/package.json'
npm WARN ENOENT ENOENT: no such file or directory, open '/Users/Admin/Code/www/learn/src/client/apps/admin/package.json'

Of course, I can just add package.json to every such folder but I don't want to. There has to be another better way to do that. Is there?

PS: npm v3.5.3

like image 425
artnikpro Avatar asked Jan 10 '16 12:01

artnikpro


1 Answers

You are trying to use nodes module require/import in a way that is bound to cause you problems later on. It would be much better to structure your project in a way that does away with these symlinks.

When importing a module you can specify a core module, a module installed inside your projects node_modules, or a relative path:

Core modules (eg require('http'))
Core modules are included as part of node and can be imported simply by name.

Installed modules (eg require ('bluebird'))
Modules that have been installed via npm, and are inside your projects _node_modules_ directory, can be installed using the name declared in their package.json.

Relative paths (eg require('../settings/menu'))
Modules (that could be single files with no package definition) can be imported using a path relative from the importing file.

Because you are not providing a package.json, npm is failing because it's unable to lookup the name property of each package. You will be much better off if you simply require these files using a relative path.

For instance, if your project looks something like:

apps  
│
└───admin
    │   assets.js
    │   components.js
    |   reducers.js
    │
    ├───subfolder
    │   │   thing.js

You can import one file to another with a relative path.

Eg, in components.js:

require ('./assets')

Or in thing.js:

require ('../assets')

If you have a lot of very nested paths, this can become a little cumbersome, but there are a number of suggested ways this can be dealt with. One method is to use path.resolve() which will resolve the relative path, given a path from the project route.

For example:

require ('../assets')

could be re-written as

require (path.resolve('app/admin/assets'))

This has the nice result of all your require paths being 'absolute' from your project root.

You can read more suggested ways to deal with this in Better local require() paths for Node js

like image 89
duncanhall Avatar answered Nov 17 '22 22:11

duncanhall