using a coffeescript node module in a nodejs project - node.js

I am playing with a node module called filings
when I first used it, I did a git clone to get that project into a local directory, where I ran npm install and then grunt to build all of the coffeescripts into JS and get dependencies installed.
That works fine and I end up with a /lib directory with 13 files in it.
Now, i'm trying to use that module within a separate node project, so I installed it with npm install filings and a node_modules/filings/lib directory was created, but it only has 6 files in it, and a bunch of functionality is missing.
I've never installed a coffeescript node module into a regular node project before, is there something I can do to get it to properly build within my project?

This is a problem with the package on npmjs.org: If we clone a module from the repository, install it, and make package with npm pack then we get a very different contents of the package to install than the package manager on the site:
http://registry.npmjs.org/filings/-/filings-0.2.0.tgz

coffee-script require (generally spoken)
you can require coffee-script files from a javascript-file if you use coffee-script/register before.
therefore you need to install coffee-script locally:
$ npm install coffee-script --save
and use it in your code:
require('coffee-script/register');
require('youre-coffee-script-module');
using the filings-module
basic setup of filings
the module itself has its main-script set to ./lib/filings.js
the lib-folder is compiled by the grunt-task publish
the publish-Task itself is triggered via the prepublish-script. so anytime the package-auther publishes his package via npm publish the lib-sources are build, an afterwards the compiled package is published.
in the .npmignore file all the source and testfiles are ignore, and therefore not published to npm!
how to fix your problem
i just see 2 more or less clean possibilities:
open an issue, and ask the package-auther to publish a new version to npm
create a fork, and use the fork
a) fork the repo
b1) add a postinstall-Property which runs the grunt-default-task grunt:
"scripts": {
"postinstall": "grunt"
}
or b2) create a index.js file where you require the coffee-sources like i pointed out above
c) install the package from your repo: npm install git+ssh://git#github.com:YOURGITHUBUSERNAME/filings.git
d) maybe create a pull-request if you do version b2

Related

npm install command - please explain

I am starting to learn React Native and I am very new to npm package manager. I read that npm can install packages localy or globaly but I am trying to understand what does that mean.
I am reading this page https://docs.npmjs.com/getting-started/installing-npm-packages-locally, can someone explain to me what does this mean please.
If you want to depend on the package from your own module using something like Node.js' require, then you want to install locally, which is npm install's default behavior. On the other hand, if you want to use it as a command line tool, something like the grunt CLI, then you want to install it globally.
Since I am very new to npm, React Native, Node (never used it), I am confused by the very first sentence in this quote. What does it mean "my own module?
If I want to use CRNA, I guess, I would have to install it globally?
If I am to install a package, say CRNA locally or globally, where do I see it installed on my MacBook Pro?
The difference between local and global install is that local install puts it into the node_modules directory of your project (this is what is referred to as "your own module") while global puts it into a system directory (the exact location depends on your OS, on OSX it should be /usr/local/lib/node_modules).
Basically:
Local install ties the installed module to your project: other projects on your computer do not get it but if your project is copied to another computer the module will be installed there too
global install ties it to your computer: you can use it on all of
your projects on your computer but if your project is copied to
another computer the installed module will not be there
And yes, CRNA should be installed globally as it is a general tool not a project's library dependence.
When you install package globally npm install -g <package name> modules drops in {prefix}/lib/node_modules.
Locally - npm install <package name> - drops package in the current working directory.
If you are going to require module in your project you have to install it locally.
If you want to run in from command line you need to install it globally.
If you need more extenden explanation take a look
Since I am very new to npm, React Native, Node (never used it), I am confused by the very first sentence in this quote. What does it mean "my own module?
If you have package.json file, then everything in the same folder is treated as "module". You add dependencies to it by doing npm install --save foo (--save option adds it under dependencies in your package.json).
If I want to use CRNA, I guess, I would have to install it globally?
Not sure what "CRNA" is. But general rule is that mostly everything (libraries...) are installed locally. Which means that they are added to your package.json and installed in same folder under node_modules.
Only case when you want to install something globally (can be added to package.json but is NOT installed in the same folder under node_modules but probably in your home directory), by doing npm install --global bar (--global installs it globally). Is when tool (not library) is project independent, as you can access it from everywhere. Something like create-react-app.
TLDR:
Local are dependencies (libraries) installed in same folder and (usually) added in your package.json as dependencie.
Global are tools installed in your user home folder and (usually) NOT added in your package.json as dependencie.
Let first start with how nodejs finds package.
Suppose you have some folder structure like-
root
-pixel
-project1
-project2
So, if your are working on project1 and required some npm package, nodejs tries to find a folder named node_modules in current directory. If fails, it goes parent(pixel folder) and tries to find node_modules and goes recursively upto root(which is global).
So, if there any package installed globally, you don't need to install it in your current working directory.
So, why don't we install all packages globally? Isn't it saves our harddisk memory?
Yes, true. But as npm packages are updating and changing its version everytime, its necessary to use specific package in your current working package to avoid collusion.
Then how global packages is useful?
Its good idea to install some cli packages to run directly from command line i.e webpack to easy our task.

How much damage can I do by installing a module in the wrong place with npm?

I've got an iOS app, using google cloud functions and want to install the Request module/package https://www.npmjs.com/package/request in the node_modules folder.
My folder structure is:
- Desktop
- myApp
- firebase
- functions
- node_modules
I was reading up on npm about npm install and there was some stuff about installing locally, globally and some other things I didn't quite get.
Is there a standard way to install packages with npm?
And if I wanted to install "Request" in the terminal do i "cd" to the node_modules folder and npm install from there or is it from within the functions folder?
Thanks.
In the same directory where you have the node_module directory (i.e. in your functions directory) you should also have package.json file. If you are in that directory and you run npm install request --save then you will install the module and put it in the dependencies in package.json file. That is what installing locally means. For more info see:
https://cloud.google.com/functions/docs/writing/dependencies
(Cloud functions for Firebase work pretty much the same as Google Cloud Functions)
Update
The --save is the default behavior of npm install since v5.0 so you don't need to use the --save flag since the saving is done automatically (there is --no-save to prevent saving).
See the release notes for more info:
https://github.com/npm/npm/releases/tag/v5.0.0

Why doesn't npm install correctly build dependency from a fork of a package on npm?

I have a project that uses an older version of react-bootstrap
in my package.json I had
"react-boostrap": "^0.13.3"
And there is a bug in there that is causing an issue, the fix for it is very simple so I forked the repo, rolled back to the commit for v0.13.3 doing:
git reset --hard <commit-hash>
made my 1 line fix, then force pushed back to my fork.
Then I updated my package.json in the main project to point to my fork:
"react-boostrap": "mygithubrepo/react-bootstrap"
I deleted the node_modules directory and ran sudo npm cache clear to make sure everything was nice and fresh. Then I ran npm install which did pull down my version of react-bootstrap from the repo.
However, the version it now pulls down isn't in the same format in the node_modules folder. Essentially, it doesn't seem as if it's built the project.
If I use:
"react-boostrap": "^0.13.3"
then the node_modules folder contains the built code like so:
+node_modules
--+react_bootstrap
----+utils
-----Acordion.js
etc.....
But when I point it to my forked version of the repo:
"react-boostrap": "mygithubrepo/react-bootstrap"
Then I get just the source repo structure in node modules (and it doesn't seem to be built)
+node_modules
--+react_bootstrap
----+docs
----+ie8
----+src
-------+utils
--------Acordion.jsx
........etc.....
----+tools
etc.....
Now when I reference react bootstrap using require('react-bootstrap') then it doesn't work (because the files haven't been built).
So what is different between me pointing to the file on npmjs rather than on github? There isn't any prepublish/publish/postpublish script in react-bootstrap package.json so I'm not sure if they manually built it before pushing to npmjs.
Basically, I need to get my forked version automatically built when I run npm install on my main project. Any ideas?
Edit 1
The errors I get running npm install on the main project repo after updating my fork of react-bootstrap as per Jonathan Muller's answer below:
>> Local Npm module "grunt-contrib-uglify" not found. Is it installed?
>> Local Npm module "grunt-amd-wrap" not found. Is it installed?
>> Local Npm module "grunt-react" not found. Is it installed?
>> Local Npm module "grunt-contrib-clean" not found. Is it installed?
>> Local Npm module "grunt-contrib-watch" not found. Is it installed?
>> Local Npm module "grunt-contrib-copy" not found. Is it installed?
>> Local Npm module "grunt-browserify" not found. Is it installed?
>> Local Npm module "grunt-contrib-requirejs" not found. Is it installed?
Warning: Task "clean:amd" not found. Use --force to continue.
Aborted due to warnings.
In your package.json, add the following to build it when you npm install it:
{
"scripts": {
"postinstall": "grunt build"
}
}
This way the package will be built after install
Then to get it working with require, add the following to the package.json:
{
"main": "amd/react-bootstrap.js"
}
So the correct file can be found when you "require" it. Otherwise it search for index.js

Install Certain NPM Modules Globally?

I'm debating how I should setup certain node modules.
Lets say I have a folder called "Projects". This will hold various code projects for node that I'll create under this going forward.
Now I can install stuff like cucumber, lodash, mocha, etc...stuff that I know I'll probably use across most all my projects:
1) npm install -g
- here, any package.json can find it on my PC I think
2) npm install [whatver] in the root of my "Projects" folder so that now I have an npm_modules folder sitting at the root so any projects created's package.json will able to find those type of modules at the root of my Projects folder
- here, I'd have to npm install once at the root of my Projects folder if not already installed globally and I didn't go with option #1
3) npm install into each project under projects. But this seems like it's not efficient. If I have to make people install stuff like cucumber every time they clone down a project, that means when they run npm install, it'll have to install cucumber again and again, for each project which seems stupid to me to do something like that if it's really a global package I plan on using across many projects
-- so here for example I might have several projects I create or clone: Projects**MyProject1**, Projects**MyProject2**, and so on. Each of those projects has its own package.json of course looking for dependencies like cucumber, mocha, etc. If I do it this way I'll have to wait for npm to install those into each's own node_module folder so for example Projects\MyProject1\node_modules\cucumber, Projects\MyProject2\node_modules\cucumber and so on. Seems stupid and duplication all over to do that...?
Suggestions on which option is best and why you think that based on your experience managing projects in node?
npm install -g - here, any package.json can find it on my PC I think
This won't work because global modules cannot be picked up by require in your node scripts.
npm install [whatver] in the root of my "Projects" folder so that now I have an npm_modules folder sitting at the root so any projects created's package.json will able to find those type of modules at the root of my Projects folder
This will work for sure as long as the projects in your "Projects" folder will always be there. If you publish a project then the dependencies for that project will have to go with it.
npm install into each project under projects. But this seems like it's not efficient. If I have to make people install stuff like cucumber every time they clone down a project, that means when they run npm install, it'll have to install cucumber again and again, for each project which seems stupid to me to do something like that if it's really a global package I plan on using across many projects
Why is this stupid? As long as you do npm install cucumber --save then your dependency on cucumber will be saved to your project's package.json file. All anyone who clones your project should have to do is this:
$ git clone project.git
$ cd project && npm install
npm install without any additional arguments will install all the dependencies listed in the package.json file for the project. It only has to do this once. After that all the dependencies are downloaded and installed within the node_modules directory for your project. The only time they'd need to run npm install again from the root of the project directory would be if they deleted the node_modules folder or you made a change and added a new dependency to package.json.
Installing modules in your "Projects" directory will make them available to any scripts requireing the module from within any subdirectories. Keep in mind that if I were to clone your repository I won't have your "Projects" directory. I'll just have the directory for your project, wherever I cloned it to. I need to get those dependencies somehow and the easiest way is for me to cd into the project and run npm install where you should have a package.json file that lists all the required dependencies.
PS - npm install [module-name] --save only saves the dependency version if you already have a package.json file in the root of your project. If you don't have one yet, then initialize one first.
$ npm init

How generate nodejs express dependencies package.json

As I started to develop my first nodejs express application, I added many packages with npm.
I would like to know if there is a way to generate a package.json file containing all the current dependencies or the list of the current packages under the nodes_modules directory.
Just run npm init in the same directory as your project.
You'll be asked a list of questions (name, version, description, etc.) and once complete, it will generate a package.json file with all of the dependencies as currently installed in the node_modules directory.
Run npm list to see what you have installed. Run npm shrinkwrap to build a npm-shrinkwrap.json file, which you can use as a starting reference to build a proper package.json. My workflow is always to update package.json and then run npm install. I never run npm install foo to get some package because it creates risk of forgetting to add it to package.json and then having your application fail to start on deployment.
Updated to add: These days I do run npm install --save foo or npm install --save-dev foo since I have now decided the ~0.4.3 version numbers it adds to package.json are better than my former preference for 0.4.x since the ~ gives you a more precise minimum version number.

Resources