Home > Enterprise >  How to get the URL in webpack - react application
How to get the URL in webpack - react application

Time:06-15

My question might be silly so please bear with me.

Background : I have a project which consists of multiple java solutions as BE and 1 react application as FE application. when we build the entire solution, a war file gets generated which we deploy on different servers to load the application.

Requirement : We need to create single war file irrespective of the env.

Issue : we cannot have separate build scripts and generate different war files, so creating config with different values will not work. the only option is to read the URL and use it. But it wont be available at the time of war generation.

env1 URL : https/abcdefg.com/abc/rma/....

env2 URL : https/abcdefg.com/def/rma/....

Till now, we kept application_context in env file, and were updating that as per the env we are deploying. I am not getting how do I update it without the access of the URL in webpack. And if it can be done in react application, how do I do it? As of now if I deploy env1 war file to env2 I get this error -

GET https/abcdefg.com/abc/rma/script/react-app/vendor/js/index.min.js net::ERR_ABORTED 404

CodePudding user response:

There are two ways you can solve this problem.

First approach involves using <base /> tag along with document.write. The idea is to generate a bundle without using any hard-coded URL. All the bundle scripts that are added to your index.html file (probably by html-webpack-plugin) should be relative URLs. The index.html file should have following code in the head tag.

<head>

  <!-- VERY FIRST STATEMENT -->
  <script>
    const [_, appname] = window.location.pathname.split('/');

    // The trailing slash `/` is important.
    document.write(`<base href="/${appname}/" />`);
  </script>

  <!-- Auto injected by html-webpack-plugin -->
  <script src="rma/script/react-app/vendor/js/index.min.js"></script>
</head>

This will cause your rma/script/react-app/vendor/js/index.min.js to be loaded as https/abcdefg.com/abc/rma/script/react-app/vendor/js/index.min.js where abc is your application name parsed from the URL.

However, using document.write is anti-pattern and discouraged. But advantage is that you can make use of Webpack's hash or chuckhash for bundle names to easily bust cache for the script on each new deployment.

The second approach involves writing an async injector for your bundled scripts. In your index.html, add the following to head tag:

<head>

  <!-- VERY FIRST STATEMENT -->
  <script>
    
    document.addEventListener('DOMContentLoaded', () => {
      const [_, appname] = window.location.pathname.split('/');
      
      const script = document.createElement('script');

      // Use root relative `src` for the scripts
      script.src = `/${appname}/rma/script/react-app/vendor/js/index.min.js`;

      document.body.append(script);
    });

  </script>

</head>

The advantage is that this is cleaner approach. The downside is that, you will have slight momentary delay and you need to no upfront the name of the generated bundle file like react-app/vendor/js/index.min.js meaning you won't be able to use Webpack's [hash] or [chunkhash] feature.

  • Related