Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pass environment variables during babel build phase for importing different files

I'm building a web (react with webpack & babel) and mobile apps (react-native with expo) for a project. I therefore created a common library for business logic and redux/api library.

Some code will be slightly different between web and mobile. In my case it's localStorage vs AsyncStorage, which I use for authentication among other things...

I'm trying to pass an environment variable for the build stage to switch import of certain files so that the correct file is loaded for each build which are simply path linked (ie no pre-build of my library, I just do import '../mylib') ex:

if(PLATFORM === 'mobile'){
   import StorageModule from './mobile-storage-module`
} else {
   import StorageModule from './mobile-storage-module`
}
export default StorageModule

Try 1

@babel/preset-env to say if it's mobile or web so that it imports different libraries depending on build like so:

My .babelrc has this:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "platform": "mobile"
      }
    ]
  ]
}

And then in local storage file I do this:

export default () => {
    const platform = process.env.platform
    if (platform === 'mobile') {
        return import './storage-modules/storage-mobile'
    }
    return import './storage-modules/storage-web'
}

That didn't work, and this also didn't work for me.

Try 2

I installed react-native-dotenv and created a .env file with: PLATFORM=mobile And set the plugin in my .babelrc:

{
  "presets": [
    "babel-preset-expo",
    "react-native-dotenv"
  ]
}

And in my example file, I tried this:

import { PLATFORM } from 'react-native-dotenv'
export default PLATFORM === 'mobile' ? import './storage-modules/storage-mobile' : import './storage-modules/storage-web'

But now my build doesn't work. Any idea how I do dynamic imports during the build process that works for babel in react-native app and webpack build (also uses babel)?

like image 285
denislexic Avatar asked Sep 28 '18 22:09

denislexic


People also ask

How do I use environment variables in react native?

All you have to do is write or define your variable in your root folder. Then, you can import the variable in your component before calling it. While env variables are very useful in React Native, it is not advisable to use them to store sensitive information like API keys, authentication keys, or passwords.

How do you set up .env file in react native?

If you are developing your app using expo(managed workflow), you will have to create a file called app. config. js inside the root directory of your project and add the following code to the file: const myValue = "My App"; export default () => { if (process.

What is .env file in react native?

Using environment file (. env) to configure most critical variables like database credentials, api keys, is the most common practice in software development.


1 Answers

First, @babel/preset-env does not do what you think it does. This is not for specifying your own variables, it is a plugin to automatically use the right target and pollyfills for the browsers you want to support.

The easiest way to get environment variables is with the webpack define plugin (which is part of webpack, so no need to install anything extra)

Just add this to your webpack config.

plugins: [
    new webpack.DefinePlugin({
        'process.env': {
            platform: 'mobile',
        },
    }),
],

Next, you can't use normal import statements inside of ifs. import gets resolved before any code runs, either on build by webpack, or in supported environments on script load. To import something on runtime, you need to use dynamic imports.

Here is an example of how this could look like.

export default new Promise(async resolve => {
    resolve(
        process.env.platform === 'mobile'
            ? (await import('./mobile.js')).default
            : (await import('./desktop.js')).default
    );
});

You can now import from this file like you normally would, but be aware that the default export is a promise.

like image 156
lukas-reineke Avatar answered Oct 20 '22 21:10

lukas-reineke