TL;DR
Working with Ionic sometimes means to handle different versions of Ionic/Cordova and Ionic/Cordova Plugins. My goal was, to setup an Ionic environment specify for each project. And I want do activate the environments automatically.
I started with autoenv, but unfortunately there is no unload/deactivate mechanism. So, finally, i switched to direnv. But i also tried different solutions with Vagrant or Docker.
Requirements
You will need a package manager to install the different software packages. There are a variety of package manager for the different platforms.
For macOS, i will use Homebrew.
Things about my directory structure
Mostly, i try to group files in different directories, depending on their functionality.
Environment files goes to a directory .env. But, wait: there could be more environments (node.js, ruby, python), which all could be used in my project.
So, i decide to use subfolders for each possible environment. Here it looks like:
$ tree myproject
myproject
└── .env
├── nvm
├── pyenv
└── ruby
Some small example
Suppose, you have this directory structure
.
├── home
│ ├── .envrc
│ └── bath
│ └── .envrc
└── office
└── .envrc
If you walk between this different rooms, you will see how direnv follow you
~/tmp$ cd home
direnv: loading .envrc
You are at home
~/tmp/home$ cd bath
direnv: loading .envrc
You are in the bath
~/tmp/home/bath$ cd ..
direnv: loading .envrc
You are at home
~/tmp/home$ cd ..
direnv: unloading
~/tmp$ cd office
direnv: loading .envrc
You are at work
~/tmp/office$ cd ../home/bath
direnv: loading .envrc
You are in the bath
~/tmp/home/bath$
Installation
There is a detailed installation instruction here, but for macOS, here is the simple step
$ brew install direnv
==> Downloading https://homebrew.bintray.com/bottles/direnv-2.14.0.high_sierra.bottle.tar.gz
Already downloaded: /home/user/Library/Caches/Homebrew/direnv-2.14.0.high_sierra.bottle.tar.gz
==> Pouring direnv-2.14.0.high_sierra.bottle.tar.gz
/usr/local/Cellar/direnv/2.14.0: 8 files, 3.7MB
Finally, check if installation has succeed
$ direnv version
2.14.0
Configuration
Directory specific configuration is made through the file .envrc. It’s like a normal Shell profile script, so mostly all commands are allowed and possible.
Entering the directory triggers this configuration file, so a normal cd into the directory does the environment setup.. pretty cool!
In my simple example, i used this configuration files
~/tmp$ find . -name .envrc
./home/.envrc
./home/bath/.envrc
./office/.envrc
~/tmp$ find . -name .envrc -exec cat {} \;
echo "You are at home"
echo "You are in the bath"
echo "You are at work"
Setting up a sample project
Ionic heavily depends on node.js So, the challenge is to setup different node.js environments. Luckily, there is already a solution for that: Node Version Manager nvm.
Install nvm
For macOS, this is quit simple (details could be found here)
$ brew install nvm
Or, manually
$ wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
Setup directory structure
Create the desired directory structure
$ cd $HOME/tmp
$ mkdir -p myproject2/.env/nvm
Configure direnv
Add the following lines (with some additional lines) into your direnv configuration file .envrc
#!/bin/bash
export NVM_DIR=$HOME/tmp/.env/nvm
echo setup nvm with NVM_DIR=$NVM_DIR
. /usr/local/opt/nvm/nvm.sh
nvm --version
Hint: When you created the file (for example with vi), you get the error message, that the .envrc file is blocked
$ vi .envrc
direnv: error .envrc is blocked. Run `direnv allow` to approve its content.
Follow the suggested solution: run direnv allow
$ direnv allow
direnv: loading .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8
direnv: export +NVM_CD_FLAGS +NVM_DIR +NVM_RC_VERSION
Now, test the configuration: Leave the directory and enter it again
$ cd ..
direnv: unloading
$ cd myproject
direnv: loading .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8
direnv: export +NVM_CD_FLAGS +NVM_DIR +NVM_RC_VERSION
Hint: If this does not work, try to start the configuration file manually for the first time,
$ cd $HOME/tmp/myproject
$ . .envrc
setup nvm with NVM_DIR=/home/user/tmp/myproject/.env/nvm
0.33.8
Fix possibile warnings and errors
If you get this error message
nvm is not compatible with the npm config "prefix" option: currently set to ...
Then, issue this command
$ npm config delete prefix
Install node
Now, the real task: install node.js
$ cd $HOME/tmp/myproject
$ nvm --version
0.33.8
$ node --version
-bash: node: command not found
$ nvm install 9.4.0
Downloading and installing node v9.4.0...
Downloading https://nodejs.org/dist/v9.4.0/node-v9.4.0-darwin-x64.tar.xz...
######################################################################## 100,0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v9.4.0 (npm v5.6.0)
Creating default alias: default -> 9.4.0 (-> v9.4.0)
Test the installation
$ which node
/home/user/tmp/myproject/.env/nvm/versions/node/v9.4.0/bin/node
$ node --version
v9.4.0
If you want to use an additional node version (maybe the latest LTS version), just install it
$ nvm install lts/carbon
Downloading and installing node v8.9.4...
Downloading https://nodejs.org/dist/v8.9.4/node-v8.9.4-darwin-x64.tar.xz...
######################################################################## 100,0%
Computing checksum with shasum -a 256
Checksums matched!
Now using node v8.9.4 (npm v5.6.0)
You can switch between the different versions with nvm use
$ nvm use lts/carbon
Now using node v8.9.4 (npm v5.6.0)
$ node --version; npm --version
v8.9.4
5.6.0
$ nvm use default
Now using node v9.4.0 (npm v5.6.0)
$ node --version; npm --version
v9.4.0
5.6.0
Setting up Ionic Environment
After this required preparation, we can start setting up our Ionic Environment
For this example, I choose the following start path: ~/Workspace/Ionic3
Setup directory structure
$ mkdir -p $HOME/Workspace/Ionic3/.env/nvm
$ cd $HOME/Workspace/Ionic3
$ vi .envrc
Create the direnv configuration file
Configuration file
#!/bin/bash
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
HERE="$PWD"
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
_USE_NODE_VERSION=9.4.0
#-------------------------------------------------------------------------------
#
#-------------------------------------------------------------------------------
export NVM_DIR="$HERE/.env/nvm"
echo "setup nvm: $NVM_DIR"
. /usr/local/opt/nvm/nvm.sh
nvm use $_USE_NODE_VERSION --silent
echo "enabled nvm : $(nvm --version) $(which nvm | sed 's#'$NVM_DIR'/##')"
echo "enabled node: $(node --version) $(which node | sed 's#'$NVM_DIR'/##')"
echo "enabled npm : $(npm --version) $(which npm | sed 's#'$NVM_DIR'/##')"
Allow the configuration file for use
$ direnv allow
direnv: loading .envrc
setup nvm: /home/user/Workspace/Ionic3/.env/nvm
enabled nvm : 0.33.8
enabled node: v9.4.0 versions/node/v9.4.0/bin/node
enabled npm : 5.6.0 versions/node/v9.4.0/bin/npm
direnv: export +NVM_CD_FLAGS +NVM_DIR
Test the configuration
~$ cd
~$ cd Workspace/Ionic3
direnv: loading .envrc
setup nvm: /home/user/Workspace/Ionic3/.env/nvm
enabled nvm : 0.33.8
enabled node: v9.4.0 versions/node/v9.4.0/bin/node
enabled npm : 5.6.0 versions/node/v9.4.0/bin/npm
direnv: export +NVM_CD_FLAGS +NVM_DIR
Well done!
Setup Ionic
Install required parts
$ npm -g install ionic@latest cordova@latest
Test your installation
~/Workspace/Ionic3$ ionic --version
3.19.1
~/Workspace/Ionic3$ cordova --version
8.0.0
~/Workspace/Ionic3$ $ which ionic
/home/user/Workspace/Ionic3/.env/nvm/versions/node/v9.4.0/bin/ionic
And, finally, work with Ionic
$ ionic start super super --cordova --no-link
$ cd super
$ ionic serve
Next steps
Happy with this, maybe you want to try other things.