> Static assets must be hosted at locations that are unique and independent of the web application environment(s)
> Why?
Broadly, for the same reason that separating content, structure, and style is considered a good idea. (We can debate separately about whether HTML/CSS/JS applied this principle appropriately.)
From another angle, this is just another way of saying that static assets should not depend directly on the environment, and that only `index.html` should differ, since it's the effective manifest of your application. It's okay for different environments to go to a different URL for `index.html`.
> I assume meaning will never ever change, so images are not "static assets"?
An individual image is a static asset. If you want to use a different image, you should change the URL. This is where the "immutable" part comes in.
> So, static assets are only immutable when they don't have anything environment specific. Oh, and static assets always don't have anything environment specific.
Not every static asset is a build artifact, but every build artifact should be a static asset. This is not true in general, but it is what the whole idea of an "immutable application" is trying to achieve. The environmental bindings are pushed out to the top level, where they belong.
I agree it could have been worded better; the phrase "static asset" is a bit overloaded here.
Can you clarify, if I add a JS line to my file, I should version that JS file as a never-ever-changing static asset to be cached? It is a build artifact. And if I make a change daily (or more frequently w/ CD), have 365 of those versions (i.e. maybe versioned as date or hash)? Or should I start embedding that frequently changing JS in the pages that need it, thereby duplicating content, just to avoid breaking the rule that all build artifacts are static assets and all static assets are immutable?
> Can you clarify, if I add a JS line to my file, I should version that JS file as a never-ever-changing static asset to be cached?
It only has to be cached as long as there exist deployments that need to reference it. But as long as there exist references to it, the content at the referenced address should not change. So yes, you should version that file -- or that deployment as a whole, if you'd rather not get that fine-grained -- but it only has to be "never-ever-changing" up to the point that nobody's observing it anymore.
If you only officially maintain one version, you'd want to keep the one prior for the sake of smooth deployment. Just document your support policy so downstream consumers aren't surprised (and they should be able to pin to an `index.html` address, generally, whose contents _are_ allowed to change over time.)
> Or should I start embedding that frequently changing JS in the pages that need it, thereby duplicating content, just to avoid breaking the rule that all build artifacts are static assets and all static assets are immutable?
Well, the article is about SPAs, so there's only one page by fiat. But in the general case (MPAs?), there would be a question about why that specific piece of JS must change so frequently, and whether that constitutes a dependency on the environment that can therefore be factored into the top-level.
I understand the general note about caches not lasting forever, no longer referenced files, etc.
This response skipped over the most important question "And if I make a change daily (or more frequently w/ CD), have 365 of those versions (i.e. maybe versioned as date or hash)?". Simply asked, is every generated JS file a static asset? Must the (indefinite) cache headers be present for every static asset be returned? So if I deploy a new static asset every hour via continuous deployment let's say, I must give it a new unique path? These questions apply to SPAs.
>So if I deploy a new static asset every hour via continuous deployment let's say, I must give it a new unique path?
I would answer yes to that. More specifically, if an old cached component could reference the new file and break, then the old component should never know about the new content.
> And if I make a change daily (or more frequently w/ CD), have 365 of those versions (i.e. maybe versioned as date or hash)?
It's a good practice for any web application. You place huge caching times for your assets, and make their URLs unique.
At the backend, you either have a compilation step that adds the unique marker (a hash is more common) to your links or you have the backend add it at runtime.
If I were to build an application 100% in the style of the article, my answer to all three questions would be "yes". But I'd probably opt to version at the level of a whole deployment, rather than at the level of each file. There's a case for versioning non-build static assets separately, but I'd rather version all of the output of a build process together.
Unique file names also solve poorly behaved caches. I spent too long at a previous job trying to figure out why a particular user kept hitting the same error even after it was fixed: it turned out to be his computer's clock being off significantly enough that assets that should have expired from his cache were not expiring.
> Why?
Broadly, for the same reason that separating content, structure, and style is considered a good idea. (We can debate separately about whether HTML/CSS/JS applied this principle appropriately.)
From another angle, this is just another way of saying that static assets should not depend directly on the environment, and that only `index.html` should differ, since it's the effective manifest of your application. It's okay for different environments to go to a different URL for `index.html`.
> I assume meaning will never ever change, so images are not "static assets"?
An individual image is a static asset. If you want to use a different image, you should change the URL. This is where the "immutable" part comes in.
> So, static assets are only immutable when they don't have anything environment specific. Oh, and static assets always don't have anything environment specific.
Not every static asset is a build artifact, but every build artifact should be a static asset. This is not true in general, but it is what the whole idea of an "immutable application" is trying to achieve. The environmental bindings are pushed out to the top level, where they belong.
I agree it could have been worded better; the phrase "static asset" is a bit overloaded here.