How to use grunt-html installed globally? - node.js

I would like to use grunt-html task to check my HTML files.
I install the task locally with npm install grunt-html and use it in grunt.js as follows:
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-html');
grunt.initConfig({
htmllint:{
all:['*.html']
},
});
};
Now I would like to install the grunt-html task globally.
Unfortunately after removing the local grunt-html node module and installing it globally grunt fails to load the task. While running grunt htmllint I get:
>> Local Npm module "grunt-html" not found. Is it installed?
If I remove grunt.loadNpmTasks('grunt-html'); from the grunt.js file I get:
Task "htmllint" not found. Use --force to continue.
So my question is how to use grunt-html installed globally?

gruntjs doesn't currently support loading globally-installed grunt modules from loadNpmTasks, per the documentation of grunt.loadNpmTasks:
This plugin must be installed locally via npm, and must be relative to the grunt.js gruntfile.
Of course, if you really insist on installing it globally, a hack would be to create a symlink (ln -s) from your local node_modules directory to your global node_modules/grunt-html directory.
If you're doing module development, another alternative would be to use the under-appreciated npm link command that lets you locally install a module that exists elsewhere on you system (see npm help link for usage information).
Both of these approaches, though, don't allow you to truly install the grunt-html package globally.

Related

What is the difference between installing a package locally and globally using npm?

What is the difference between installing a package locally and globally using npm?
From my understanding:
Locally install: npm install <package>
This package/module will find on your local node_modules folder and
can only be usable for this project.
This package/module can be accessible in using require("package")
from code.
This package/module can't be accessible in command line interface.
Globally install: npm install <package> -g
This package/module will find on where node is installed in your machine like /usr/local and can be usable everywhere.
This package/module can't be accessible in using require("package")
from code.
This package/module can be accessible in command line interface.
Please let me know. If I could misunderstand anything here. Thanks!
You are correct except for 1 point.
The local packages exposing CLI utilities can be accessed from the command line. Newer versions of NPM create this .bin/ directory inside the local node_modules/.
Whenever you try to use a tool (let's take babel for example), if you use it from the command line and you have it installed in your project, npm will properly identify that package and run it's CLI for you.
Here's a useful article on the topic.
http://www.2ality.com/2016/01/locally-installed-npm-executables.html
Global modules are mostly tools like gulp, yoman or any other module you use in your daily work.
Local modules are the dependencies of your project. You should never depend on a global module in your project. Even dependencies as gulp should be a local dependency in your dev-dependency section.

Where to install gulp?

I'm trying to leverage from Elixer so I started to get up and running. I've installed Node and Npm. Later I also installed Gulp using sudo npm install gulp -g. But this installed Gulp in my project directory, resulting in a massive file transfer from my local host to the webserver. Is it necessary to install Gulp inside the project directory? Or is there a better way to install it somewhere else and use it for any project needed?
Sorry if this is a total beginners question but I can't seem to find an answer online. Thanks.
There is only few steps to start use it.
Install globally $ npm install --global gulp
Install directly to your project root dir $ npm install --save-dev gulp
Create gulpfile.js in root dir
Then in your new gulpfile do the follow:
var gulp = require('gulp');
gulp.task('default', function() {
// place code for your default task here
});
and after that just type gulp command in terminal to execute default task
here is documentation to help you started with gulp docs and here you can find packages to use it npmjs.com
Tip: if you on OSX use sudo to install npm/jspm/gulp etc
sudo npm install gulp -g shouldn't be installing gulp in your project directory. However, Gulp does always need to be installed locally in the project folder in order for it to work. Otherwise, you will get an error when trying to run Gulp. The -g global installion of Gulp is only needed for linking the shell to the binary $ gulp; it will dispatch to the local gulp program as soon as it is called.
Gulp, bower, ... are dependencies.
The command npm install ... will download the module to the directory named node_modules. They need to be (litterally) a part of your project. Think of it as a pure JS library (as it actually is).

What does the -g option for npm install and npm list do?

The Node.js npm (Node Package Manager) has a -g command line argument, which I often see referenced. For example, the documentation for the Microsoft Azure x-plat (cross-platform) CLI tool says to install it by using npm install -g azure-cli.
Question: What does the -g option do?
What options do I have to install node modules?
After writing this I quickly found and old but still applicable post by Isaac (yes, the npm #isaacs). But I still think the below post is informational.
You can install npm modules globally or locally - you already know that, but why?
Globally: npm install -g some-module-a: This module is intended to be used as an executable (i.e. CLI, file watcher, code minifier, logger, etc.).
Locally: npm install some-module-b: To be imported and used in your app via import, var someModule = require('some-module)
global modules are one of the best ideas of npm. We can easily create executables using node/javascript. If your node app is meant to be run as an executable, then you will want others to install it globally. If it's a utility, helper, application, etc. then you usually don't want it installed globally. So, unless the module explicitly states that you should install it with -g, then don't.
One more time: if you are wanting to use some module called some-module in your node app - var someModule = require('some-module'), then npm install some-module from the root of your node app to pull it into your local node_modules directory. If you've installed some-module globally and not locally, it will usually not load and will show you an error about not finding the module (even though it can be made to load the global module - hint: just don't!)
So what exactly happens when you install globally?
npm install -g [some module] installs the specified node module in a directory higher up in your file system (i.e. usually /usr/local/lib/node_modules in unix systems). The biggest use case for global modules is for CLIs written using node (think npm, bower, gulp, grunt, et. al.).
Let's look at what happens when you install bower globally:
*follow these steps in your command line/terminal
step: npm install -g bower
explanation: the module - all of it's files and dependencies - are saved in your global directory (e.g. /usr/local/lib/node_modules/bower).
Something else happened here. Somehow you can now run bower in your command line. Awesome!
step: bower -v --> results in the installed bower version (i.e. 1.6.5)
explanation: It's now a fully executable node app using bower as the keyword. Inside bower's package.json file you'll find a bin property:
"bin": {
"bower": "bin/bower"
}
So how did that all work?
npm will create a symlink from where most executables live, /usr/local/bin/bower over to /usr/local/lib/node_modules/bower/bin/bower, where the module lives. That symlink makes it so when the executable runs, it can reference other files in the original module, including it's local node_modules. Pretty cool, huh?
*Note on executables: If you create a file called awesomeness in /usr/local/bin/ and chmod u+x (user + executable) it. Then write some scripting in it (in this case javascript using #!/usr/bin/env node at the top). Then you can run it anywhere in your command line/terminal just by typing awesomeness.
Hope that helped. I know doing a deeper dive into it helped me early on.
Node.js packages can be installed one of two ways:
Globally
Locally
The -g option instructs npm to install the package globally. You would install a Node.js package globally, if you want to be able to call the command directly from the terminal.
From the documentation:
There are two ways to install npm packages: locally or globally. You choose which kind of installation to use based on how you want to use the package.
If you want to use it as a command line tool, something like the grunt CLI, then you can want to install it globally. On the other hand, if you want to depend on the package from your own module using something like Node's require, then you want to install locally.
To download packages globally, you simply use the command npm install -g , e.g.:

Locally installed versus globally installed NPM modules

In my package.json file, I have bower listed as a dependency. After I run npm install, bower gets installed locally. When I try to run bower after installing it locally I get an error
"bower" is not recognized as an internal or external command
It seems the only way to resolve this is to install bower globally. Why should I have to do this? If my project contains a local copy of bower, why won't node use it?
Installing locally makes bower available to the current project (where it stores all of the node modules in node_modules). This is usually only good for using a module like so var module = require('module'); It will not be available as a command that the shell can resolve until you install it globally npm install -g module where npm will install it in a place where your path variable will resolve this command.
Edit: This documentation explains it pretty thorougly.
You can execute your local instance by typing the line below in cmd:
node_modules/bower/bin/bower <bower args>
We use both PHP and JavaScript, so we have composer and npm.
Each of the projects we work on have different packages both for runtime of the package as well as build/dev tools.
As there are version constraints in each project, installing version x of a package globally (that would be run from the command line), would cause us issues, we install all the tooling in each package. Much easier to define in the appropriate composer.json / package.json files.
But running the CLI tools is a pain if you have to constantly add an additional path to the command.
To that end, we have recommend to the team that the following paths are added to your $PATH in the appropriate .bashrc (or equivalent):
./vendor/bin:./node_modules/.bin
(EDIT: For Windows, the paths would be .\vendor\bin;.\node_modules\.bin;)
So, whilst in project X, we have access to the CLI tools for that project. Switch to project Y, and we get that projects tools.
Sure, you are going to get duplications, but each project is maintained by different teams (and some people are in multiple teams), so again, having 1 version in the global setup is an issue there.
Usually you install NPM modules globally if you want them included in your path to be ran from the command line. Since it is installed locally you will have to run it from the node_modules folder.

Skip local installation of Gulp

Can I somehow skip local installation of Gulp to the project?
I installed Gulp globally, added it to package.json as a dependency. But still Gulp wants to be installed locally also with the Local gulp not found in ... message. If I do local install, Gulp is copied into my project by node.
Is there a way to skip local installation of Gulp? I want to be able to run it across the whole server from command line and manage it installation globally.
One clean way to do this is without have it locally is to install gulp globally like as you did and then run in your directory the command :
npm link gulp
It will create a symbolic link in your node_modules folder to your global gulp install. You need to be careful on the versions since all your symlinks and therefore your local project(s) will use the global one, no matter of the defined version in the package.json, which could cause errors on a deployed environment.
This is also applicable for every node package, and allow you to update the local install you've created that way of multiple projects at once.

Resources