Search code examples
reactjsnpmnpm-package

React Component env variables from project for imported component


I have a Create React Project that has some local env variables for config. I have a component that uses the env variables to configure itself. It imports the variables using

process.env.MY_VAR;

I wanted to move the component out into a npm package but retain the ability to use the process.env.MY_VAR. When I build and publish the package it will build it with the current MY_VAR and not the MY_VAR that is in my project I want to import it into. Is there a way I can do what I am after.

I have considered refactoring the component to take the env vars as props, but that's not something I really want to do.

Is there a way I can do what I am after.


Solution

  • How about treating your component library as a npm package that already is built fully/independent of build variables and ready to be consumed by npm clients?

    Unless you want to use the library as some sort of internal package that naturally has a lot of coupling to the surrounding build environment, it is probably easier to embrace the classic npm approach. And it makes sense especially, if you want to publish the package. In your importing app project, you could still use process.env.MY_VAR. For the library part , I would suggest to hand in a configuration object.

    If process.env.MY_VAR is important for the whole library containing multiple components, start with a package initialization step:

    import { init } from "my-comp-library"
    
    const config = {
      myVar: process.env.MY_VAR
    }
    
    const lib = init(config)
    const MyComp = lib.myComp()
    
    const App = () => <MyComp />
    

    If only relevant to a single component inside library, you could pass it as props directly:

    const App = () => <MyComp myVar={process.env.MY_VAR} />
    

    In app you could e.g. create a wrapper component MyAppComp that already includes its configuration in order to avoid redundant initialization logic for MyComp. Additional benefit here is that you would just have one place in app to change code, if library public API changes.

    MyAppComp.js in app project:

    import { MyComp } from "my-comp-library"
    
    export const MyAppComp = props => <MyComp myVar={process.env.MY_VAR} {...props} />
    

    Independent build management of your app and component project removes coupling, which makes them easier to maintain.