Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
688 views
in Technique[技术] by (71.8m points)

reactjs - React configuration file for post deployment settings

I've built a reactjs site and trying to get it to be deployable.

right now all configuration is done via a config.js which is imported into all modules.

But when I build the app, this gets compiled into the deployment js and isn't configurable.

I want to have a separate file which a sys admin can configure various settings specific to their enviroment, such as the API end points (the app may not be running on the same server as the backend, and there will not be any access to DNS).

Is there a way to do this in react? I do not wish to use 3rd party libraries for this either.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Not sure about the linux approach, but I am using create-react-app (cra), Docker & kubernetes a lot and initially struggled with similar problem. I was then inspired by https://github.com/inloop/cra-docker and was able to find a solution for the configuration file problem with create-react-app at runtime in both Docker and kubernetes. Below are the steps in my solution:

  1. Have your custom configuration (eg: config.js) ready. The contents inside your config file should look like this:

     window.ENV = {
         "ENVIRONMENT":"stg",
         ...other key-value configuration as you'll need
     }
    

    Your configurations will be accessible anywhere in your code by accessing window.ENV.your_configuration_key (eg: the ENVIRONMENT value above is available at window.ENV.ENVIRONMENT)

  2. Under public directory, edit the index.html and add

     <script type="text/javascript" src="%PUBLIC_URL%/config.js"></script>
    

    in your head before the body. And put config.js under public directory.

    Your goal in solving the external configuration for cra is that you want to put your config.js file outside source directory and put it under the static public directory. If you put the config under source directory, the config will get compiled during build time so you won't able to change the config during runtime easily (well, templating works too but it's not ideal to me). Do note that serving files from static directory require a server, but since I'm already using nginx anyway to serve my static react app, I have absolutely no trouble doing this.

  3. Since I was already using nginx to serve the static files for my react app, I don't need to make changes to my Dockerfile to cater for additional config.js as it will be available under the build directory after compiled (due to it being placed under public directory). My Dockerfile looks something like this:

     # Step 1: Build static react app
     FROM node AS builder
    
     # Define working directory and copy source
     WORKDIR /app
    
     COPY . .
    
     # Install dependencies and build whatever you have to build 
     RUN yarn install && yarn build
    
     # Step 2: Run image
     FROM nginx
    
     COPY --from=builder /app/build /usr/share/nginx/html
     RUN rm /etc/nginx/conf.d/default.conf
    
     COPY nginx.conf /etc/nginx # this step is not required, only when you have custom nginx configuration
    

    Then afterwards build your docker image:
    docker build -t [your-docker-image]:latest .

  4. Last but definitely not least, you'll want to replace your config.js file during runtime. This can now be done easily.

    If you're running using docker, you can replace files by using the -v command. So your docker runtime command should look something similar to this:

     docker run --name [app-container-name] -d -p [host_port]:80 
         -v [path_to_config.js_file_in_certain_environment]:/usr/share/nginx/html/config.js 
     [your-docker-image]
    

    If you're running using kubernetes, you can replace files in an existing directory under your container by using configMap, volume, volumeMounts and subPath.

    • First put your config.js under k8s ConfigMap:

      kubectl create configmap [k8s_config_name] --from-file=config.js=[path_to_config.js_file_in_certain_environment]

    • Mount your configMap in your k8s deployment:

      containers:        
        ...
        volumeMounts:
        - name: [k8s_config_name_volume]
          readOnly: true
          mountPath: "/usr/share/nginx/html/config.js"
          subPath: "config.js"
      
      volumes:
        - name: [k8s_config_name_volume]
          configMap:
            name: [k8s_config_name]
      

    Note that both mountPath and subPath parameters are necessary to replace a file under a directory that already has some files existing in it. If subPath is omitted during volume mount to an existing directory which already contains some files the result is unfavourable in our case cos it will override the existing directory by copying the new file into the directory but removing all other previously existing files.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...