require('module/component') when component.js is not in module root? - node.js

I'm trying to create a npm package of a couple React components. These will be used in a couple of other projects so I would like them in a separate package.
What I would like to be able to do is require('comps/a-component') from an app using this package. I could do this by putting all my components in the root of the module, but I don't want to do that. Instead I want to have all components in src/components/ because the root will be overcrowded.
This seems like a trivial thing to do but I have not yet succeeded. I've looked through https://docs.npmjs.com/files/package.json trying to find an option to set the root or something. Does anyone have any ideas on how to achieve this?
Thanks!

You can make symlink in you node_modules directory to your components directory. This would allow you to require your components from anywhere in your app like you said: require('comps/a-component'). To create the symlink on a linux or osx you can do something like this
cd ./node_modules; ln -snf ../src/components comps;
Another option would be to actually create npm packages out of each component, that way you could have them listed in your dependencies of your package.json.
Another promising option that was released in npm 2.0 are local dependencies. This allows you to point to a local npm package on your file system. In this case each component would have to be written as an npm package with a package.json https://docs.npmjs.com/files/package.json#local-paths

If your app is like this:
- AppFolder
|-index.js
|-Readme.md
|-/src
|-app.js
|-anotherThing.js
If I want to use anotherThing.js, I can just do var anotherThing = require('./src/anotherThing');. Unless I fail to understand your problem.
Or maybe you meant the main attribute in package.json

Related

How to modify an npm package built with TypeScript

I want to try and make some changes to a package published in npm? (I've suggest some changes as an issue but I think they are simple enough for me to attempt them).
https://www.npmjs.com/package/bt-presence#contributing--modifying
The author supplies some information on how to modify the package, but not really enough for someone doing it for the first time.
Where should I clone the GitHub repo to? The folder where the package is installed? I tried it in my home folder and that would not build (unmodified).
The command npm run build - where is this run from? The root folder of the package where the package.json is?
Will I need to modify the package.json?
In general what is the best way to develop something like this for npm? I've worked on packages before but they were simply Javascript.
If you want to work on the bt-presence package in isolation, you can put the cloned repository anywhere. If you want to use your modified version of bt-presence in combination with an application, my recommended approach is to register bt-presence as a dependency in the application's package.json file with the version set to a relative path to your bt-presence repository; then running npm install in the application will make a symlink from node_modules/bt-presence in the application to your bt-presence repository.
npm run build should indeed be run from the root folder that contains the package.json of bt-presence.
If you just want to change the code of bt-presence, you won't need to modify its package.json. You would only modify the package.json if you need to change any of the settings in there, e.g, if you need to add additional dependencies to your version of bt-presence.
None of the above is really specific to TypeScript. (Some JavaScript packages have build processes too if they need to transform or package the JavaScript files in some way.)

Finding node module from different directory?

Always feel stupid asking here because people are always confused with my questions, or I have a dumb problem, but, I'm working on a program in node.js and the text editor I'm using (NP++) doesn't seem to like to save files in the system32 directoy, (The directory where my modules are), and that is where my script is as well. (So I have .../.../node_modules/(modules) and .../.../node_modules/script.js) this becomes a pain when I want to edit the script, I have to clone the script to my desktop, then edit it, then overwrite the one in the node_modules directory. I tried saving the script to my desktop and running it, but it just gives me an error of module not found. (In my script I have the modules as var example = require('example.js')) Is there any way I can get it to get the modules from the node_modules directory, while keeping the script file somewhere easily accessible and editable? (i.e desktop?) (Sorry if this is confusing, not the best at these kind of things)
I'm not 100% sure that this is what's happening because I haven't used npm on Windows, but it sounds to me like you're installing your dependencies globally using npm -g. The more proper way to use Node is to install your dependencies locally, using npm without the -g flag. That way your dependencies get installed in your current working directory.
For example, let's say you've saved your project in a directory on your Desktop, and your script uses require("lodash"). If you cd to your directory and run npm install lodash, then the lodash module will be available to your script.

Nodejs require module from external folder

I'm developing microservice architecture on nodejs.
I moved 'core' functionality to separate git repository, and each 'service' add that core as npm dependency.
In service I use core as
require('core/module1');
In that case nodejs takes 'core' from node_modules, it's ok for production but for development I want to take 'core' from the external folder not from node_modules.
My main idea - do changes in 'core' and immidiately get the result in 'service'.
I cannot use NODE_PATH for specify external 'core' folder, because I've used it now.
I found solution to use 'app-module-path' module for adding additional directories to the Node.js module search path.
if(isDevelopment()){
require('app-module-path').addPath('path_to_core_folder');
}
It's working solution, but maybe you can suggest some more clear way?
My folders structure
- core
module1
- service1
-index.js
-node_modules
-core
Thanks.
Either one works. If you require('modulename') and it's present in your node_modules folder, it will be loaded from there. If you want it to load from another folder or from your main folder, you need to do require('./modulename") which will look for it in the current folder. Alternatively you can do require('./my_modules/modulename') which will work for a subfolder.
i would look at the mockrequire module, it allows you to redirect the directory your modules are loaded from
npm link is the answer to your problem. You can run the below command in the root directory of 'service1' (where your package.json is present)
npm link [../relative-path-to/library]
Refer to https://docs.npmjs.com/cli/v7/commands/npm-link for more details about npm link.

Private NPM modules installed via package.json without a parent directory?

I'm building custom nodes for a Node-RED app (http://nodered.org/) and published each one as a private NPM module and put them in my package.json like this:
"#di-dash/node-red-contrib-didash-output": "0.0.1",
but that makes them install inside of a parent directory like this:
/node_modules/#di-dash/node-red-contrib-didash-output
The fact that they're in a parent directory now instead of directly in the node_modules directory like they were when I was just pulling in github repos as depencencies prevents Node-RED from noticing them and including them in the app.
I wrote a grunt script to pull them out of the parent directory and put them directly into node_modules and put it as a "postinstall" script in package.json but that must happen after the app inits because the Node-RED app isn't picking up my custom nodes anymore.
Any ideas how to make the private modules install without a parent directory so that they're just like normal (non-private) NPM modules?
Like this:
node_modules/node-red-contrib-didash-output
Instead of:
/node_modules/#di-dash/node-red-contrib-didash-output
It's not that they are private modules, it's that they are scoped modules. They are supposed to be in a directory with the same name as the scope they are under. The only way to make them install in root is by removing the scope from the packages. I suggest seeking support from the Node-RED team to see if they have a workaround for scoped modules.
Edit: I took the liberty of opening an issue for you :)
https://github.com/node-red/node-red/issues/885

Substitute a package in NPM/Node

Is it possible to force an external npm dependency to use a different node.js package that offers the same API but a different implementation?
If you're willing to do that and that module is open source you could fork that on github, change their package.json to include the module you want and use github url for your own package.json like this:
"modulename": "git+https://git#github.com/user/repo.git"
You should be able to download the source of whatever module you would prefer and put that folder within your node_modules folder. From that point you simply require it within your Node.js app like any other NPM module.
I recommend downloading the code for the API you want, creating an src/assets folder, placing it in there, changing the package name in package.json to something not used in npm, then using 'require('newPackageName')' within your code.
If you decide to use some of package.json's capabilities to point towards a specific version (like using "1.4.7" as opposed to "^1.4.7") or if you point to a github address, be careful when you run npm update. It will replace your URL with the latest version in npmjs.org with that specific name. I don't know if it still does this in newer versions of npm, but in the version that works with Node.js 0.12, this is the default behavior.
I can tell you that node shrinkwrap will work, but it will prevent any other packages from being updated as well. No, you cannot just have one shrinkwrapped dependency, it has to be all of them, or npm update won't work.

Resources