variabler
v2.0.1
Published
Environment configs made easy
Downloads
6
Maintainers
Readme
If you like this project, please support it with a star 🌟
Variabler
Variabler is a simple tool for managing environment-dependent variables in JavaScript projects.
Installation
Globally
# npm
npm install -g variabler
# yarn
yarn global add variabler
If you install Variabler globally you can call it:
- As
variabler
frompackage.json
scripts - As
variabler
from CLI
As dev dependency
# npm
npm install --save-dev variabler
# yarn
yarn add -D variabler
If you install Variabler as a dev dependency you can call it:
- As
variabler
frompackage.json
scripts - As
./node_modules/.bin/variabler
from command line
Initialization
To init Variabler in your repository run the following command in your project directory:
variabler init
Description
Originally Variabler was created to manage environments and brands in React Native apps but indeed you can use it for React, Node.js or any other JavaScript framework as well. It's platform independent.
Variabler is very convinient in the following cases:
- To manage environments of the app. E.g.,
local
,staging
andproduction
- To manage branded apps that are based on the single white labeled codebase
Usually environments and branded apps have different bundle ids, have different setting files (like sentry.settings
for Sentry or branch.json
for Branch.io), have different constants (color themes, titles, etc...) and can even have different version numbers.
To manage it all in React Native you need to create its own Android flavour and iOS target for each environment and somehow manage all the differences between environemnts and branded apps. Variabler make it way much easier. Let's say we want to create staging
and production
apps.
First, we create config:
{
"configurations": {
"default": {
"variables": {
"VERSION": "1.2.3"
}
},
"env": {
"local": {
"variables": {
"API_URL": "http://localhost:8080",
"APP_NAME": "Local"
}
},
"staging": {
"variables": {
"API_URL": "https://staging.example.com",
"APP_NAME": "Staging"
}
},
"production": {
"variables": {
"API_URL": "https://production.example.com",
"APP_NAME": "Production"
}
}
}
},
"templates": [
{ "from": "api.js", "to": "src/api.js" },
{ "from": "build.gradle", "to": "android/app/build.gradle" }
]
}
After, we create template files:
api.js
:
const baseURL = '@API_URL@'
export const get = url => fetch('GET', `${baseUrl}/${url}`)
build.gradle
:
...
applicationId "@BUNDLE_ID@"
versionName "@VERSION@"
...
Finally, we add file destination paths to .gitignore
:
/android/app/build.gradle
/src/api.js
That's it! Now we can easily set environment using the command:
variabler set env:staging
It will create two files.
android/app/build.gradle
:
...
applicationId "com.example.app.staging"
versionName "1.2.3"
...
src/api.js
:
const baseURL = 'https://staging.example.com'
export const get = url => fetch('GET', `${baseUrl}/${url}`)
Commands
add
Makes file managed by Variabler:
- Moves the file from original path to
variabler/templates
- Removes the original file from git (you need to commit this change)
- Adds path to the original file to
.gitignore
- Adds original path and template path to
variabler/config.json
After running this command you can open the template file and put into it variable keys from variabler/config.json
Example:
variabler add ./path/to/file
Options
Name
If there already exists a template with the same name you will be asked to choose a new name. Other way you need to provide name option to the command:
Example:
# long way
variabler add ./path/to/file.txt --name myfile.txt
# short way
variabler add ./path/to/file.txt -n myfile.txt
File
If you want to add file not as template but as file you can use the following options:
Example:
# long way
variabler add --file assets/icon.png
# short way
variabler add -f assets/icon.png
check
Checks the consistency:
- Between variable keys used in templates and variables defined in config
- Between file destinations and file sources defined in config
Result:
- Shows warning if variable is defined in config but not used in templates
- Shows error if variable is used in templates but not defined in config
Example:
variabler check
init
Initializes Variabler in your repository:
- Adds
variabler
directory that contains files, templates and config - Adds variabler files section into
.gitignore
By default it creates two dummy templates (api.js
and settings.json
) and dummy icon files.
It's needed just to help you understand how to use Variabler.
Example:
variabler init
set
Sets variables:
- Takes the files from
variabler/templates
directory - Fills the values from
variabler/config.json
to these files - Copies the files to the project structure according to the paths defined in
variabler/config.json
Copies files:
- Take the files from
variabler/files
directory - Copies the files to the project structure according to the paths defined in
variabler/config.json
Example:
variabler set
variabler set env:staging
variabler set env:production brand:pepsi
If you don't pass any values to this command or don't pass enough of them, it will ask you to select one of the available options.
Advanced configuration
Working with files
Variabler can copy environment-dependent files. Usually it's needed for copying brand-specific icons or environement-specific binary files.
Let's say we need to use different icons for different app environments.
We create directory variabler/files/icon
and put three files there:
local.png
staging.png
production.png
Then we add file configuration to config.json
:
{
"configurations": {
"default": {
"variables": {
...
}
},
"env": {
"local": {
"files": {
"appIcon": "icon/local.png"
},
"variables": {
...
}
},
"staging": {
"files": {
"appIcon": "icon/staging.png"
},
"variables": {
...
}
},
"production": {
"files": {
"appIcon": "icon/production.png"
},
"variables": {
...
}
},
}
},
"files": [
{ "id": "appIcon", "to": "assets/icon.png" }
],
"templates": [
...
]
}
That's it!
Now variabler set
command will copy the icon for selected environment to assets/icon.png
destination.
Multiple variable lists
It's possible to use a few lists of variables.
Let's say, we have a white labeled app that can:
- Be branded as
cola
orpepsi
- Be built for
staging
andproduction
environments.
First, we create variables config:
{
"configurations": {
"default": {
"variables": {
"VERSION": "1.2.3"
}
},
"brand": {
"cola": {
"variables": {
"BUNDLE_ID": "com.example.cola"
}
},
"pepsi": {
"variables": {
"BUNDLE_ID": "com.example.pepsi"
}
}
},
"env": {
"staging": {
"variables": {
"BUNDLE_EXTENSION": ".staging"
}
},
"production": {
"variables": {
"BUNDLE_EXTENSION": ""
}
}
}
},
"templates": [{ "from": "build.gradle", "to": "./android/app/build.gradle" }]
}
After, we create build.gradle
file template:
...
applicationId "@BUNDLE_ID@@BUNDLE_EXTENSION@"
versionName "@VERSION@"
...
Finally, we add file destination paths to .gitignore
:
/android/app/build.gradle
Now we can set variables:
variabler set brand:pepsi env:staging
After we set variables, we gonna see the following code in android/app/build.gradle
:
...
applicationId "com.example.pepsi.staging"
versionName "1.2.3"
...
Extending variable lists
Let's say we need to have production candidate environment that is the same as production one but with a different bundle id.
To do that we can inherit configurations in config.json
with extends
claim:
{
"configurations": {
"default": {
"variables": {
"VERSION": "1.2.3"
}
},
"env": {
"staging": {
"variables": {
"API_URL": "https://staging.example.com",
"BUNDLE_ID": "com.example.app.staging"
}
},
"production": {
"variables": {
"API_URL": "https://production.example.com",
"BUNDLE_ID": "com.example.app"
}
},
"production.candidate": {
"extends": "production",
"variables": {
"BUNDLE_ID": "com.example.app.candidate"
}
}
}
},
"templates": [
{ "from": "api.js", "to": "src/api.js" },
{ "from": "build.gradle", "to": "android/app/build.gradle" }
]
}
When you set env to production.candidate
, it takes all the variables defined in the common
section, takes all the variables defined in the production
section and overrides/extends them with the variables defined in the production.candidate
section. So the full list of variables filled into template is:
API_URL: https://production.example.com
BUNDLE_ID: com.example.app.candidate
VERSION: 1.2.3
Integrations
Vault
Variabler can take variables from Vault secret manager.
Let's say, you want to put production environment variables into Vault.
You need to create a secret in a key-value storage and put the path to this secret to config.json
:
{
"configurations": {
"default": {
"variables": {
"VERSION": "1.2.3"
}
},
"env": {
"staging": {
"variables": {
"API_URL": "https://staging.example.com",
"APP_NAME": "Staging"
}
},
"production": {
"variables": "vault://secret/production"
}
}
},
"templates": [
{ "from": "api.js", "to": "src/api.js" },
{ "from": "build.gradle", "to": "android/app/build.gradle" }
]
}
Variabler doesn't handle connection to Vault by itself. To use Vault integration you need Vault CLI to be installed on your machine and you should be logged into Vault. So you need to check that the following command works in your terminal:
vault kv get secret/production
If it works, it shows you something like this:
===== Secret Path =====
secret/data/production
====== Data ======
Key Value
--- -----
API_URL https://production.example.com
APP_NAME Production