jeudi 30 avril 2020

EmberJS: Set environment variables in index.html

We have an Ember (3.5) application. For technical reasons we need environment variables to be set on page load, as opposed to build time. We're trying to set them in index.html the following way:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>App</title>
    <meta name="description" content="">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <script type="application/javascript">
      // Object.assign polyfill
      Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
      window.env = {};

      var request = new XMLHttpRequest();
      request.open('GET', '/api/frontend_settings', true);
      request.send(null);

      request.addEventListener('readystatechange', () => {
        if (request.status === 200) {
          if (request.readyState === 4) {
            Object.assign(window.env, JSON.parse(request.response).settings);
          }
        }
      }, false);
    </script>

    <link integrity="" rel="stylesheet" href="assets/vendor.css">
    <link integrity="" rel="stylesheet" href="assets/app-frontend.css">

    
  </head>
  <body>
    <script integrity="" src="assets/vendor.js"></script>
    <script integrity="" src="assets/app-frontend.js"></script>
  </body>
</html>

We added a script which makes a request to some endpoint (/api/frontend_env_vars) in the snippet. This endpoint responds with a JSON with the key-values of environment variables which we then assign to window.env.

The problem we have is that sometimes Ember scripts load before the variables have been assigned (since we do a request that takes some time to complete), which makes the application crash.

We tried the following alteration to the script, but it didn't work (the error was different, though):

<script type="application/javascript">
  // Object.assign polyfill
  Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(e,r){"use strict";if(null==e)throw new TypeError("Cannot convert first argument to object");for(var t=Object(e),n=1;n<arguments.length;n++){var o=arguments[n];if(null!=o)for(var a=Object.keys(Object(o)),c=0,b=a.length;c<b;c++){var i=a[c],l=Object.getOwnPropertyDescriptor(o,i);void 0!==l&&l.enumerable&&(t[i]=o[i])}}return t}});
  window.env = {};
  var request = new XMLHttpRequest();
  request.open('GET', '/api/frontend_env_vars', true);
  request.send(null);
  function loadScript(src) {
    const script = document.createElement('script');
    script.src = src;
    document.body.append(script);
  }
  request.addEventListener('readystatechange', () => {
    if (request.status === 200) {
      if (request.readyState === 4) {
        Object.assign(window.env, JSON.parse(request.response).settings);
        loadScript('assets/vendor.js');
        loadScript('assets/app-frontend.js');
      }
    }
  }, false);
</script>



Aucun commentaire:

Enregistrer un commentaire