Skip to content
This repository has been archived by the owner on Jul 8, 2020. It is now read-only.

Adding functionality to get values from system env #6

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -28,32 +28,33 @@ $ npm install metro-react-native-babel-preset --save-dev

## Usage

Add your app configuration in an **.env** file.
Add your app configuration in an **.env** file. Prefix your values with `$` to obtain from system env.

```
API_KEY=lorem
ANOTHER_CONFIG=foobar
ANOTHER_API_KEY=$API_KEY_FROM_SYSTEM_ENV
```

Now you can import it in your **.js** file.

```js
import { API_KEY, ANOTHER_CONFIG } from 'react-native-dotenv'
import { API_KEY, ANOTHER_CONFIG, ANOTHER_API_KEY } from 'react-native-dotenv'

ApiClient.init(API_KEY, ANOTHER_CONFIG)
ApiClient.init(API_KEY, ANOTHER_CONFIG, ANOTHER_API_KEY)
```

## How does it work?

As you can see, it's implemented as a babel plugin. All referenced imported members are replaced as the values specified in the **.env** file.
As you can see, it's implemented as a babel plugin. All referenced imported members are replaced as the values or environment variables specified in the **.env** file

The example above will get compiled as below.
The example above will get compiled as below, assuming your system environment variable `API_KEY_FROM_SYSTEM_ENV` is `this_value_is_from_system_env`

```js

ApiClient.init('lorem', 'foobar')
ApiClient.init('lorem', 'foobar', 'this_value_is_from_system_env')
```


## FAQ

### Changes to .env file is not updated
6 changes: 5 additions & 1 deletion babel-plugin-dotenv/README.md
Original file line number Diff line number Diff line change
@@ -25,7 +25,7 @@ $ npm install babel-plugin-dotenv
```
DB_HOST=localhost
DB_USER=root
DB_PASS=s1mpl3
DB_PASS=$SECRET_KEY_FROM_SYSTEM_ENV
```

In **whatever.js**
@@ -38,3 +38,7 @@ db.connect({
password: DB_PASS
});
```

## Troubleshooting

- Make sure the required system environment variables are properly exported in your build system / dev machine
28 changes: 23 additions & 5 deletions babel-plugin-dotenv/index.js
Original file line number Diff line number Diff line change
@@ -34,12 +34,30 @@ module.exports = function (data) {
throw path.get('specifiers')[idx].buildCodeFrameError('Try to import dotenv variable "' + importedId + '" which is not defined in any ' + configFile + ' files.')
}

var binding = path.scope.getBinding(localId);
binding.referencePaths.forEach(function(refPath){
refPath.replaceWith(t.valueToNode(config[importedId]))
});
})
let valueToBeReplaced
const actualValueFromConfigFile = `${config[importedId]}`
if (actualValueFromConfigFile.startsWith('$')) {
const systemEnvVarName = actualValueFromConfigFile.substring(1)
if (!process.env[systemEnvVarName]) {
throw path
.get('specifiers')
[idx].buildCodeFrameError(
'Trying to use system environment variable "' +
actualValueFromConfigFile +
'" which is not defined'
)
}
valueToBeReplaced = process.env[systemEnvVarName]
} else {
valueToBeReplaced = actualValueFromConfigFile
}

var binding = path.scope.getBinding(localId)
binding.referencePaths.forEach(function(refPath) {
refPath.replaceWith(t.valueToNode(valueToBeReplaced))
})
})

path.remove();
}
}
9 changes: 9 additions & 0 deletions babel-plugin-dotenv/test/fixtures/system-env/.babelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"plugins": [
"babel-plugin-transform-es2015-modules-commonjs",
["../../../", {
"replacedModuleName": "babel-dotenv",
"configDir": "test/fixtures/system-env"
}]
]
}
1 change: 1 addition & 0 deletions babel-plugin-dotenv/test/fixtures/system-env/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_KEY=$ENV_API_KEY
2 changes: 2 additions & 0 deletions babel-plugin-dotenv/test/fixtures/system-env/source.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import { API_KEY } from 'babel-dotenv';
console.log(API_KEY);
15 changes: 15 additions & 0 deletions babel-plugin-dotenv/test/test.js
Original file line number Diff line number Diff line change
@@ -32,6 +32,21 @@ describe('myself in some tests', function() {
expect(result.code).to.be('\'use strict\';\n\nconsole.log(\'abc123\');\nconsole.log(\'username\');')
})

it('should load env from system env', function(){
process.env.ENV_API_KEY='THISISNOTASECRET'
var result = babel.transformFileSync('test/fixtures/system-env/source.js')
expect(result.code).to.be('\'use strict\';\n\nconsole.log(\'THISISNOTASECRET\');')
})

it('should throw if imported system env is not present', function() {
delete process.env.ENV_API_KEY
expect(function(){
babel.transformFileSync('test/fixtures/system-env/source.js')
}).to.throwException(function (e) {
expect(e.message).to.contain("Trying to use system environment variable ");
});
});

it('should load empty variable as empty string ', function(){
var result = babel.transformFileSync('test/fixtures/empty-values/source.js')
expect(result.code).to.be('\'use strict\';\n\nconsole.log(\'abc123\');\nconsole.log(\'username\');\nconsole.log(\'\');')