1. 9

    Static assets must not contain anything that is environment-specific

    I agree so hard on this. It’s pretty common to see many people adding environment variables in compile time, so, they can’t deploy a valid build from dev to production without rebuilding (for example). This should be done by default in most web applications. Simplifies a lot the continuous integration.

    I’ve found useful in some applications to set the frontend’s variables But there’s a point I would consider optional, because it depends on your infrastructure. (In general, the document assumes that you have and need many different endpoints, and maybe you’re okay with just one).

    index.html contains fully-qualified references to the static assets

    <script src="https://assets.myapp.com/apps/1.0.2/main.js" type="text/javascript"></script>
    

    It’s not giving much benefit from fully-qualifying the asset path, instead of linking to a path that includes the version and just assuming it’s on the same domain. (or relying on the version hash included in the final asset, like many automated tools already do).

    You need to do this when you’re on an environment that separates API, Web Server and Static Assets server… not because a good practice, but because a technical requirement of the needed infrastructure (if you need it).

    EDIT:

    The values for the environment variables are set on an index.html that is unique to each environment.

    I’ve found useful, sometimes, to set the frontend’s env vars in the backend, and serve a computed .js file with the variables from the back, so the front on the same domain can consume it. This way your whole frontend build part doesn’t have any environment variable involved (including the index.html).

    1. 4

      Hey, author of the document here!

      I am really excited about the idea of server-side rendering the index.html with the environment variables included.

      We’ve been working on a project that renders the index.html from a Lambda@Edge aws-lambda-edge-example which makes bumping the version as simple as pushing a config value that points the lambda to render index.html from a different template. And it is hosted from the edge network on a CloudFront distribution, which effectively serves the entire app.

      Thanks for the great feedback!

      1. 3

        You’re welcome! Thanks for your contribution :)

    1. 7

      I wholeheartedly agree with the premise of the article. Follow are some nitpicks:

      Static assets must be hosted at locations that are unique and independent of the web application environment(s).

      It’s not really clear until the very end why this is a good thing. The main reason is to use a store that also keeps all the previously published versions. The fact that it’s a separate service doesn’t really matter.

      index.html must never be cached

      this is only true because Google Chrome is so aggressive with caching unfortunately. If it was respecting the spec then the cache could be revalidated with If-Modified-Since/Etag headers.

      type=“text/javascript”

      is this still necessary?

      Versioned assets are published to a unique location in an AWS S3 bucket.

      The important part is that they are unique. Maintaining a versioning scheme is unnecessary overhead when the application is tightly coupled with the code. Especially SemVer which just doesn’t apply in this context. Instead, use the sha256 of the content as the key of each asset so it’s one less thing to think about.

      1. 4

        Hey, author of the document here!

        Thanks for the great feedback. I agree with a lot of it. The tone of the document is maybe too dogmatic about some of the details, mostly just to reinforce the underlying principles.

        • There are cases and projects where index.html can cached by the browser. For example, if it is ok that all clients do not need to be running the same version at the same time and there is no need for instantaneous rollback you could add max-age.

        • I agree that using a fingerprint of the content in the filename is a better way of achieving uniqueness, so long as you have a mechanism to indicate which assets work together for each version of the app. We have been creating immutable index.html templates that we version and publish. They group together all of the related, fingerprinted assets. A deployment renders index.html from a from json configuration that contains a link to the template and the environment variables and then publishes the index.html.

        • I don’t mean to advocate for keeping all previous versions of the app. Just enough to safely rollback in case of an incident. I do intend to advocate for publishing future versions of the app, so that you can test them where they live before doing a live release.