Running executable after installing via JSPM - jspm

I'm trying to understand how executables can be run after installing a module using the JSPM. For instance if I run jspm install gulp, then I would expect to be able to run the following command:
./jspm_packages/npm/gulp\#3.8.11/bin/gulp.js
Actually it would be better if jspm would handle this so that there is a hidden bin directory containing all retrieved executables (such as gulp) at the following location:
./jspm_packages/.bin
That way I could just have a single addition to my PATH environment variable that would allow these executables to run.
Currently when I attempt to run a jspm-installed gulp, I get the following error message:
[jspm-test]$ ./jspm_packages/npm/gulp\#3.8.11/bin/gulp.js
./jspm_packages/npm/gulp#3.8.11/bin/gulp.js: line 1: /bin: Is a directory
./jspm_packages/npm/gulp#3.8.11/bin/gulp.js: line 2: syntax error near unexpected token `('
./jspm_packages/npm/gulp#3.8.11/bin/gulp.js: line 2: `(function(process) {'
Is there some other way I should be going about this?

In my experience this is weird with JSPM as JSPM is more geared towards deps for your app that are actually in production in the browser. What I do in my projects is install modules I need to run with scripts/in dev (gulp, karma, express etc) using NPM, then you can run them with node:
node ./node_modules/karma/bin/karma.js <args>
It's kind of weird, but if you think of it as NPM handling local, "executable" deps that aren't used in production and JSPM handling the deps for your application that are going to get bundled and shipped it makes sense.

I agree with #SleepyProgrammer response.
JSPM is a package manager specifically for front-end dependencies, much like bower.
It is odd to install gulp with the front-end dependencies of your project.
You'd rather install gulp, karma, express and the likes with npm as dev dependencies, to bundle and process things on your local dev server, then serve the result as js, css, html files...
a simple $(npm bin)/gulp -v make
That being said, I installed enzyme with jspm for my tests to be able to import it.
If you want to use jspm in your node projects, you can always use this command:
jspm run script
See documentation: http://jspm.io/docs/nodejs-usage.html

Related

Path of the express

Why express command not found. Here is the path for express.
/usr/lib/node_modules/express
When I install the express, the terminal shows the path. I used
npm install -g express-generator
npm install -g express
But when I run express, it doesn't work. In this directory, express is globally right? But why can't be found. I don't understand the logic.
You need to install express locally, rather than globally.
http://blog.nodejs.org/2011/03/23/npm-1-0-global-vs-local-installation
In general, the rule of thumb is:
If you’re installing something that you want to use in your program, using require('whatever'), then install it locally, at the root of your project.
If you’re installing something that you want to use in your shell, on the command line or something, install it globally, so that its binaries end up in your PATH environment variable.
Based on this, you want to install express-generator using the -g flag as you will use it as a command line tool, but you want to install express without this flag as it's a module you will want to require() it in your application.
Take a look at the installation guide:
http://expressjs.com/starter/generator.html
It says to install the express-generator module as a global module as you will use it as a command line utility to scaffold your new applications.
Once you have scaffolded an application using the express myapp command, you just have to run npm install in the myapp directory which will download the rest of the dependencies to your projects local ./node_modules directory. It does this by reading the contents of the generated package.json file.
Lesson to take away: Don't install with the -g flag unless the modules instruction guide explicitly says to do so.

NPM on OSX, error getting global installed packages

I have nodejs installed on a MBP which runs OSX 10.9, I have installed as a package downloaded from the nodejs website. Then I have installed the MEAN stack following instructions on mean.io.
The commands are:
sudo npm install -g mean-cli
mean init yourNewApp
That works correctly
Now the real issue is when after my app is created I enter the dir using the terminal, and write gulp, and it thows me some errors that some mandatory modules are not found.
The modules are written in the package.json file that mean generated, and they are installed as global modules on ~/.npm
I browsed the folder and there are all the required packages folders, inside the folders there is a package.tgz file which has the code of the package and a package folder which holds a package.json file describing the package itself.
Now I don't understand why the packages are compressed and why if they are installed globaly can not be accessed from gulp on my project folder.
Thanks in advance.
If you install some global module then you better don't put it into the package.json of your app because when you run your app that's the first place where is going to search and if it is there your app is going to look at node_modules folder and if it is not there your app will crash.
My advice is try to install your modules inside your app, npm install your_module --save because your app is gonna be portable and with a simple npm install you will be able to install all your needed packages.
But if you still wanna install global packages you maybe wanna follow this rules:
If you’re installing something that you want to use in your program, using require('whatever'), then install it locally, at the root of your project.
If you’re installing something that you want to use in your shell, on the command line or something, install it globally, so that its binaries end up in your PATH environment variable.
If you have the time to read the link then you will see that there are exceptions and how to handle them.

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.

How to add browserify as a dependency of your node.js application?

My node.js application depends on the fact browserify is available on the command line, as it uses it on a shell script. How can I make sure it is available on the application without having to require my client to install it manually via npm install?
Since you're not giving too much context, I'm assuming that your external dependencies are located in ./node_modules in your app's directory.
In that case, just install browserify as an extra (local) dependency, which will make it available as ./node_modules/.bin/browserify. That's also how you can refer to it from your shell script.
An even better option is to install browserify as follows:
npm install --save browserify
This not only installs browserify for you, but also adds it as a dependency to your dependencies in your package.json file.
Now when someone installs your module i.e. via npm install yourmodule, browserify will be installed automatically into its ./node_modules.
This of course works for any module you depend on, not only browserify.

How to use grunt-html installed globally?

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.

Resources