Ionic-cli: Using locally installed Cordova instead of globally installed

Created on 29 Jun 2016  ·  26Comments  ·  Source: ionic-team/ionic-cli

Hi,

since I like to have as less as global node modules as possible and since its not always possible to update global modules, I would like to know, where is the reason Ionic-CLI needs a global Cordova installation and can't (from docs page) cannot be used from a local installation of project itself?

Another question about which I'm really not sure is... why does the docs page state you have to use sudo? The documentation should state in case of permission problems, you should use sudo. Installing apps as sudo is never a good idea.

needs investigation

Most helpful comment

I would like to suggest an alternative approach, that I use all the time with the Angular CLI.
AFAICT, installing a package globally is quite the same as installing it locally, except that its bin is automatically put in PATH.

Using a combination of local install, npm scripts and an optional shell alias we can achieve quite the same thing.

Just to make sure no global cordova is installed: npm uninstall -g cordova

Install cordova locally: 'npm install --save cordova@^8.0.0` (or the version that better suits you).

Add the following into your package json:

  "scripts": {
    "cordova": "cordova",
    "run-device": "cordova run android --device",
    "build-android": "cordova build android --release -- --keystore ..\\mobile.keystore --alias=it.seavision --storePassword=password  --password=password"
  },

So we can use good 'ol npm run cordova -- (-- without anything appended) exactly as it was cordova installed globally. We can even use a shell alias to effectively use the cordova alias in place of npm run cordova --.

Like in npm run cordova -- platform add android (exactly the same as cordova platform add android).

And the most commonly used commands are available directly via scripts, like npm run run-device and npm run build-android.

All 26 comments

Regarding question 2, I'll piggyback and say I think they should suggest nvm to avoid sudo.

This was most likely listed based on the cordova documentation. https://cordova.apache.org/docs/en/latest/guide/cli/ I agree that we should update the docs to mention using sudo only in some situations which is similar to the cordova docs.

While many people use nvm (myself included) this is not a requirement for ionic so we are not likely to include another step for beginners.

I will assign myself this issue and use it to track updating the docs to more closely align with the verbiage used on cordova's docs.

Thank you for your reply @jthoms1. What about the question 1?

👍

I think this may be related to: https://github.com/driftyco/ionic-cli/issues/388 and https://github.com/driftyco/ionic-cli/issues/235

This is a _huge_ issue for us as our team relies upon using npm to pull in everything needed and can't use globally installed npm modules.

This is an absolute must have. I have an Ionic app in the app stores written in Ionic 2. This app will not be upgraded to Ionic 3, but is being maintained. I am now writing another app in Ionic 3. It is currently very difficult (actually I haven't yet succeeded) in having a development environment that supports both versions.

An npm-based project should be able to maintain it's dependencies locally. In fact, I believe this is one of the main advantages of this type of project; it is self-contained and explicitly defines all of its dependencies, both for compile-time (devDependencies) and run-time (dependencies).

The ability for Ionic (and Cordova for that matter) to be installed locally should be baked in and, IMHO, should be the default usage scenario.

When I run dev tools I run them from './node_modules/.bin'. When a dev tool runs another dev tool (which Ionic seems to do) it should also run it from './node_modules/bin'.

@gmaughan Look into Vagrant if you haven't already. I haven't messed with it in a while, but that might be your best bet.

Thanks @patrickmcd Vagrant would do the job for development. But it seems like overkill. Setting up separate virtual environments for each version would be cumbersome, especially given we do all our back-end development in .NET under Visual Studio and would have to set that up as well.

Having a self-contained project, which includes all of its devDependencies, just seems like the right way to do it for me. It means that builds are predictable, can be performed on minimally configured machines, and minimise surprises because of changes to global tools.

I've basically come back to an app developed months ago to fix a production issue, only to find I can no longer build it because I upgraded Cordova and Ionic to develop a new app.

@gmaughan I agree, if Cordova is installed locally it should use that local cordova installation. I haven't heard of anyone doing this before. It seems to me like even if Cordova was installed locally, it would still depend on system dependencies such as Android SDK or Xcode version, and even the Java version, which are tougher to compartmentalize inside individual projects.

We are talking about the node module package and not any other system-based services, that node module actually uses.

And yes, we're using the cordova locally, but for that, we always have to change the PATH variable. Wouldn't it be enough if ionic config could have a flag "useLocalCordova', which the ionic's cordova-cli commands would also use then?

I mean, if you change the PATH variable in the same way then ionic will use your local cordova. No magic there. I think I will change it though such that if it detects a local installation, it will just use it.

@lordgreg The fix should be in the alpha CLI! Would you be interested in testing?

npm i -g ionic@canary

@dwieeb thank you very much for the implementation. I will do the tests first thing in the morning and give you feedback. Until then, thank you and best regards 👍

@dwieeb Sorry it took so long. I've finally got time to test it out.

  • I've removed the globally installed cordova completely
  • I've installed cordova 7.0.1 locally into ionic project
  • I've updated ionic cli to canary (global!)
  • ???
  • Profit.

👍

Couple quick questions, out of ignorance:
1) Is this useLocalCordova flag now available?
2) How would I use it - I've never messed with ionic config settings

I ask because I've recently got the need for 2 different versions of cordova CLI. When I ditched the global NPM module and installed locally, I get below. My Ionic Info is below too.

The Cordova CLI was not found on your PATH. Please install Cordova globally:

cli packages:

@ionic/cli-utils  : 1.18.0
ionic (Ionic CLI) : 3.18.0

global packages:

cordova (Cordova CLI) : not installed

local packages:

@ionic/app-scripts : 3.0.1
Cordova Platforms  : none
Ionic Framework    : ionic-angular 3.8.0

System:

Android SDK Tools : 25.2.5
Node              : v6.11.1
npm               : 3.10.10
OS                : Windows 10

@brassier There's no configuration needed. The Ionic CLI uses the local Cordova CLI when it is installed locally and global Cordova CLI when it's not installed locally. If the Cordova CLI is installed neither locally nor globally, which appears to be your case, then you'll get that error.

@dwieeb - that's what I started to understand when I peeked at the commit for this. Unfortunately it doesn't seem to work with my setup. I do have cordova installed locally. Anything else I could be doing wrong, or anything I can show for troubleshooting info?

> npm ls cordova --depth=0
[email protected] C:\dev\Customer\customerApp
`-- [email protected]

@brassier That's odd. I uninstalled my global cordova, did this:

» npm ls cordova --depth 0
[email protected] /Users/dan/apps/myapp
└── [email protected]

And it uses the local Cordova.

Do you have a binary at node_modules/.bin/cordova ?

I do -

> ls node_modules/.bin/cordova
Directory: C:\dev\Customer\customerApp\node_modules\.bin
Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       11/14/2017   4:03 PM            309 cordova

Very strange! We add node_modules/.bin to PATH in this function: https://github.com/ionic-team/ionic-cli/blob/master/packages/@ionic/cli-utils/src/lib/shell.ts#L119-L121

Perhaps I'm doing this incorrectly for Windows. My understanding is I can modify the PATH of a subprocess by giving it a PATH environment variable when spawning the process. Perhaps I need to modify process.env directly for Windows?

I wish I knew more about how this CLI is spawning processes, and how it differs on the various OS's. It does seem like something Windows-specific is missing here though. Can you reproduce what I'm seeing on a Windows machine, just to remove the possibility of it being something else in my configuration?

@brassier I will investigate!

Why was this closed if we never addressed the need to depend on Cordova locally?

I would like to suggest an alternative approach, that I use all the time with the Angular CLI.
AFAICT, installing a package globally is quite the same as installing it locally, except that its bin is automatically put in PATH.

Using a combination of local install, npm scripts and an optional shell alias we can achieve quite the same thing.

Just to make sure no global cordova is installed: npm uninstall -g cordova

Install cordova locally: 'npm install --save cordova@^8.0.0` (or the version that better suits you).

Add the following into your package json:

  "scripts": {
    "cordova": "cordova",
    "run-device": "cordova run android --device",
    "build-android": "cordova build android --release -- --keystore ..\\mobile.keystore --alias=it.seavision --storePassword=password  --password=password"
  },

So we can use good 'ol npm run cordova -- (-- without anything appended) exactly as it was cordova installed globally. We can even use a shell alias to effectively use the cordova alias in place of npm run cordova --.

Like in npm run cordova -- platform add android (exactly the same as cordova platform add android).

And the most commonly used commands are available directly via scripts, like npm run run-device and npm run build-android.

"scripts": {
"cordova": "cordova",
"run-device": "cordova run android --device",
"build-android": "cordova build android --release -- --keystore ..\mobile.keystore --alias=it.seavision --storePassword=password --password=password"
},

j ai pas le droit de modifier le fichier package. json
meme j ai modifier les permission par cette commande : ### mac$ sudo chmod 755 /Users/mac/.npm-global/lib/node_modules/cordova/package.json
qq je doit faire ?

I would like to suggest an alternative approach, that I use all the time with the Angular CLI.
AFAICT, installing a package globally is quite the same as installing it locally, except that its bin is automatically put in PATH.

Using a combination of local install, npm scripts and an optional shell alias we can achieve quite the same thing.

Just to make sure no global cordova is installed: npm uninstall -g cordova

Install cordova locally: 'npm install --save cordova@^8.0.0` (or the version that better suits you).

Add the following into your package json:

  "scripts": {
    "cordova": "cordova",
    "run-device": "cordova run android --device",
    "build-android": "cordova build android --release -- --keystore ..\\mobile.keystore --alias=it.seavision --storePassword=password  --password=password"
  },

So we can use good 'ol npm run cordova -- (-- without anything appended) exactly as it was cordova installed globally. We can even use a shell alias to effectively use the cordova alias in place of npm run cordova --.

Like in npm run cordova -- platform add android (exactly the same as cordova platform add android).

And the most commonly used commands are available directly via scripts, like npm run run-device and npm run build-android.

thank you so much man, this really helped me out! :rocket:

You could also use npx cordova if cordova is locally installed in the "node_modules" directory. See https://docs.npmjs.com/cli/v7/commands/npx

Was this page helpful?
0 / 5 - 0 ratings