From 3f106f441258a5889455cc175bfd89d8349655fd Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Sat, 22 Sep 2018 21:13:41 -0400 Subject: [PATCH 1/8] Add intro, principles, and concepts --- README.md | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/README.md b/README.md index 32926d2..e58fd38 100644 --- a/README.md +++ b/README.md @@ -1 +1,81 @@ # Immutable Web Apps + +## Introduction + +_Immutable Web Applications_ is a framework-independent methodology for building static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: + +- Minimizes risk and complexity of live releases. +- Simplifies and maximizes caching. +- Minimizes the need for servers and systems administration. +- Enables continuous delivery through simple, flexible, atomic deployments. + +## Principles + +The methodology is based on the principles of ___strictly separating___: + +- Configuration from code. +- Release tasks from build tasks. +- Dynamic content from static content. + +These principles are inspired by [The Twelve-Factor App](https://12factor.net/). + +## Concepts + +The following concepts define the core requirements for an _Immutable Web Application_. They are framework and infrastructure independent. + +### _Permabundles_ + +Permabundles are the static assets that make up a single-page application. + +- They must be available at a [permalink](https://en.wikipedia.org/wiki/Permalink) that is uniquely versioned or fingerprinted and _independent of the web application environment(s)_. + +- They must be configured for long-term caching. (`cache-control: public, max-age=31536000, immutable`) + +- __They must not contain any environment-specific configuration.__ + +### `index.html` ___is___ configuration + + An `index.html` exists for each deployment environment. + +- They must contain fully-qualified references to the _permabundle_ assets. + +- They must define all environment configuration on the global javascript scope. + +- They must never be cached by the browser or a public cache that cannot be purged on-demand. (`cache-control: no-store`) + +_The `index.html` of your Angular app might look like this... it's all configuration!_: + +```html + + + + + Immutable Web App Example + + + + + + + + + + + + + + + + + + + + + +``` From 846a88a3489ae4dfa99821a2b2e69f27bf06160b Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Sun, 23 Sep 2018 22:24:40 -0400 Subject: [PATCH 2/8] Change framework-independent to framework-agnostic --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e58fd38..c24bb79 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Introduction -_Immutable Web Applications_ is a framework-independent methodology for building static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: +_Immutable Web Applications_ is a framework-agnostic methodology for building static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: - Minimizes risk and complexity of live releases. - Simplifies and maximizes caching. @@ -21,7 +21,7 @@ These principles are inspired by [The Twelve-Factor App](https://12factor.net/). ## Concepts -The following concepts define the core requirements for an _Immutable Web Application_. They are framework and infrastructure independent. +The following concepts define the core requirements for an _Immutable Web Application_. They are framework and infrastructure agnostic. ### _Permabundles_ From f5c2e41cd629bcee6cf87b0b862d04ed97240042 Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Mon, 24 Sep 2018 22:42:49 -0400 Subject: [PATCH 3/8] clarify intro, rearrange concepts for symmetry, remove prescriptive detail --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c24bb79..a16fc4b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Introduction -_Immutable Web Applications_ is a framework-agnostic methodology for building static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: +_Immutable Web Applications_ is a framework-agnostic methodology for building and deploying static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: - Minimizes risk and complexity of live releases. - Simplifies and maximizes caching. @@ -39,10 +39,10 @@ Permabundles are the static assets that make up a single-page application. - They must contain fully-qualified references to the _permabundle_ assets. -- They must define all environment configuration on the global javascript scope. - - They must never be cached by the browser or a public cache that cannot be purged on-demand. (`cache-control: no-store`) +- __They must define all environment-specific configuration.__ + _The `index.html` of your Angular app might look like this... it's all configuration!_: ```html From 579d55768ab222cb543a5cde363f6c1cfec06447 Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Tue, 25 Sep 2018 22:04:22 -0400 Subject: [PATCH 4/8] fix pluralization --- README.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a16fc4b..6ae6df6 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Introduction -_Immutable Web Applications_ is a framework-agnostic methodology for building and deploying static [single-page application](https://en.wikipedia.org/wiki/Single-page_application) that: +_Immutable Web Applications_ is a framework-agnostic methodology for building and deploying static [single-page applications](https://en.wikipedia.org/wiki/Single-page_application) that: - Minimizes risk and complexity of live releases. - Simplifies and maximizes caching. @@ -79,3 +79,18 @@ _The `index.html` of your Angular app might look like this... it's all configura ``` + +## Development Lifecycle + + + +### Staged Deployments + +1. Implementation +2. Build +3. Publish + +### Atomic Releases + +1. Build `index.html` +2. \ No newline at end of file From 124875b83ede70bbfd37130a2f8980161703965d Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Thu, 27 Sep 2018 23:56:50 -0400 Subject: [PATCH 5/8] draft of workflow --- README.md | 42 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6ae6df6..f74a935 100644 --- a/README.md +++ b/README.md @@ -80,17 +80,43 @@ _The `index.html` of your Angular app might look like this... it's all configura ``` -## Development Lifecycle +## Workflow +The workflow is defined by its separation of build tasks and release tasks. Specifically, the publishing of permabundles as a _build_ and the publishing of index.html as a _release_. +### Publishing of permabundles as a build -### Staged Deployments +Write code. Build assets. Publish permabundles. -1. Implementation -2. Build -3. Publish +It could be that simple. Of course, the specifics of this process will vary by the project and the team. The important part is that it is a process that results in published permabundles. -### Atomic Releases +The publishing of a permabundle will typically be triggered from a manual action. Once the permabundle is published it must not be changed. Any required changes must result in publishing a different permabundle. -1. Build `index.html` -2. \ No newline at end of file +### Publishing of `index.html` as a release + +When a permabundle is published and ready to be deployed, a new version of the `index.html` can be created that references the permabundle. Publishing the new `index.html` will instantly and atomically release the new version of the web application. + +### Promoting permabundles + +The _value_ of Immutable Web Apps occurs between the publishing of the permabundle and a live release of the web application. Between those events the permabundle can be promoted to production through a process of validation. + +This validation might take the form of: + +- Automation, regression, or exploratory testing +- Integration in a staging environment +- Canary testing in a production replica +- Blue/green deployment of backing services + +If the permabundles fails any of this validation it is abandoned. If it succeeds it is immediately available to be released by publishing a new `index.html`. If an issue is found in production, rolling back is instant and atomic by simply publishing the previous revision of `index.html`. + +## Setup + +- Separate the management of `index.html` from the code repository that builds the static assets + +- Manage your permabundles like they are a Javascript Library CDN, for example [http://cdnjs.org](https://cdnjs.com/libraries/jquery) + +- Configure your web application host(s) to serve `index.html` for any path, no exceptions + +- Use a CDN + +- Favor a serverless cloud platform From 1ebcd3c59b559c65773f3fd869313bbb86d549bf Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Sat, 29 Sep 2018 17:12:47 -0400 Subject: [PATCH 6/8] decomposing web apps as a way to explain immutable apps --- README.md | 215 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 193 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index f74a935..a3b5e46 100644 --- a/README.md +++ b/README.md @@ -6,44 +6,182 @@ _Immutable Web Applications_ is a framework-agnostic methodology for building an - Minimizes risk and complexity of live releases. - Simplifies and maximizes caching. -- Minimizes the need for servers and systems administration. +- Minimizes the need for servers and administration of runtime environments. - Enables continuous delivery through simple, flexible, atomic deployments. ## Principles The methodology is based on the principles of ___strictly separating___: +- Dynamic content from static content. - Configuration from code. - Release tasks from build tasks. -- Dynamic content from static content. These principles are inspired by [The Twelve-Factor App](https://12factor.net/). -## Concepts +## Decomposing a web application -The following concepts define the core requirements for an _Immutable Web Application_. They are framework and infrastructure agnostic. +The _Immutable Web App_ methodology was developed by through a process of decomposing web applications based on the principles declared above and then reconsidering the relationship between the different components. Before defining the methodology, this document will step through the decomposition. It starts with a monolithic web application. -### _Permabundles_ +### The Monolithic Web-Application -Permabundles are the static assets that make up a single-page application. +There generally are three types of network traffic commonly made in by web application from the browser: -- They must be available at a [permalink](https://en.wikipedia.org/wiki/Permalink) that is uniquely versioned or fingerprinted and _independent of the web application environment(s)_. +#### static assets -- They must be configured for long-term caching. (`cache-control: public, max-age=31536000, immutable`) +- javascript, css, images, bundled assets +- long term cached +- artifacts live on the client -- __They must not contain any environment-specific configuration.__ +#### xhr/fetch -### `index.html` ___is___ configuration +- dynamic +- no cache - An `index.html` exists for each deployment environment. +#### the document -- They must contain fully-qualified references to the _permabundle_ assets. +- typically in the form of `index.html` +- no caching +- returned for all routes that aren't physical files -- They must never be cached by the browser or a public cache that cannot be purged on-demand. (`cache-control: no-store`) +> An image of typical network traffic for a simple single page application -- __They must define all environment-specific configuration.__ +A monolithic web application will handle the requests for all three types of requests. Express, a very popular node framework for building web applications, generally supports handling all three types of requests. Running the `express-generator` will create an application skeleton that supports routes for each: + +```javascript +var express = require('express'); +var path = require('path'); +var cookieParser = require('cookie-parser'); +var logger = require('morgan'); + +var indexRouter = require('./routes/index'); +var usersRouter = require('./routes/users'); + +var app = express(); + +app.use(logger('dev')); +app.use(express.json()); +app.use(express.urlencoded({ extended: false })); +app.use(cookieParser()); + +/* serves static assets */ +app.use(express.static(path.join(__dirname, 'public'))); + +/* serves the document */ +app.use('/', indexRouter); + +/* serves dynamic requests */ +app.use('/users', usersRouter); + +module.exports = app; +``` + +A monolithic web application will also include a web application framework, like Angular, for building the single-page application assets. Using Express and Angular together in a single code base will results in a multi-stage build: + +- First the static Angular apps are generated and +- Then the assets are embedded in the creation of the executable package (docker image, rpm). + +The package is then typically stored in a versioned repository of packages before it is deployed to a runtime environment. + +> An image of the monolith build process: code => build static assets => build docker image with assets baked in => publish image to docker repo => deployed to server + +#### Characteristics of the monolithic web application + +- separation release tasks from build tasks (good) +- high cohesion between the backend and frontend contract (good) +- ability to test the same build artifact in multiple environments (good) +- if the backend goes down, so does the frontend - serving static assets is much more reliable then dynamic backends, and gracefully handling backend outages is a better user experience than 404s and 500s (bad) +- zero downtime deploys can be tricky considering caching and existing browser sessions (bad) +- complicated project dependencies that represent two very different jobs (bad) + - building a static web application assets + - running a web server + +### Separate frontend from backend + +The first stage of decomposition is to separate the client from the server. This aligns with the principle of strict separation of dynamic content from static content. + +> An image of the two separated build processes: +> code => build static assets => publish to static web server with routing rules +> code => build docker image => publish image to docker repo => deploy to server + +#### The static web application + +code base generates static assets, + +The static assets can be deployed to a static web server that will have much higher reliability than the backend. + +The static web apps should generally be cached for the long term, the backend should have caching turned off. + +#### The backend api + +code base generates an executable package. + +generally you can read up on 12 factor app for help here, as it has been decoupled from many of the web application specific concerns + +#### Characteristics of the frontend/backend web application + +deployments require a little more careful sequencing to avoid zero-downtime. The backend may need to support multiple versions of an app as the frontend is deployed from one version to another. this is good, because it makes an preexisting problem more visible. + +Code bases for generating the backend and the code base for generating the static application is separated. + +Client side assets are often environment specific and deployed right after they are built as a part of a release. + +### index.html as a special file + +The second stage of decomposition continues to emphasize the strict separation of dynamic content from static content by separating `index.html`. + +The document, `index.html`, is a bit of a special case. It may be a static file from the perspective of a specific deployment, but over the lifetime of multiple deployments, it is a dynamic file... evident by the fact that it cannot be cached at any location by the browser. Moreover, it has routing responsibilities that are unlike any of the other static assets or apis. + +> An image of the three separated build processes: +> code => build static assets => publish to static web server +> code => build docker image => publish image to docker repo => deploy to server +> index.html => publish to static web server that always returns index.html + +#### `index.html` -_The `index.html` of your Angular app might look like this... it's all configuration!_: +can be hosted by a static web server that for whatever path it is requested it always returns `index.html` + +#### `static assets` + +it allows us to simplify the hosting of all other static assets, all other static assets can be hosted in a completely different domain, and cached for long term if they are versioned or fingerprinted + +#### Characteristics of the index/frontend/backend web application + +assets can be build prior to deployment, a live release is effectively the act of updating `index.html`, but opportunities for testing them are limited. + +### Separating code from config + +Now that the app is decomposed into long term cached static assets, backend apis, and the special case of `index.html`, the relationships between the three parts look like this: + +> An image of the three components and lines showing their dependencies (BEFORE) + +- `index.html` has a strict dependency on static assets + +- javascript in the static assets has strict dependencies on the backend apis (based on how modern web app frameworks handle configuration) + +```typescript +// This file can be replaced during build by using the `fileReplacements` array. +// `ng build --prod` replaces `environment.ts` with `environment.prod.ts`. +// The list of file replacements can be found in `angular.json`. + +export const environment = { + production: false +}; +``` + +- the backend apis generally have no dependencies on either the static assets or index.html + +The environment configuration that creates a strict dependency between the javascript and the api violates the principle of strict separation of configuration from code. This practice forces the static assets to be rebuilt for each environment and for any configuration change. Rebuilding the static assets introduces risk and promotes a workflow that does not distinguish between build tasks and deploy tasks, adding even more risk and complexity to releases. + +By expanding the perception of dynamic and static, index.html can be perceived as static from the perspective of one deployment, but dynamic over the lifetime of multiple deployments. Similarly, Javascript that contains configuration is static from the perspective of one environment, but it is _conceptually_ dynamic over multiple environments because of the differences in configuration. This dynamic quality is addressed by building the assets multiple times and publishing to multiple locations. + +Moving the configuration out of the static javascript allows it to be _truly_ static. __It can be generated once, published once, cached forever and used in multiple different environments with multiple configurations.__ + +Where does the configuation live? It must live in a location that is dynamic (and therefore never cached), it must be unique to the environment and unique to the deployment. `index.html` has all of these qualities. If configuration is moved into `index.html`, the relationships now look like this: + +> An image of the three components and lines showing their dependencies (AFTER) + +Consider what it looks like to have all environment configuration defined on the global scope of the `index.html` generated by the `angular-cli`: ```html @@ -60,7 +198,7 @@ _The `index.html` of your Angular app might look like this... it's all configura - - - - + + + + + + ``` +This file has interesting qualities. + +- It is 100% configuration! +- It is strikingly similar to a kubectrl deployment YAML or a docker-compose.yaml + +MORE STUFF HERE + +### Conclusions + +## Concepts + +The following concepts define the core requirements for an _Immutable Web Application_. They are framework and infrastructure agnostic. + +### _Permabundles_ + +Permabundles are the static assets that make up a single-page application. + +- They must be available at a [permalink](https://en.wikipedia.org/wiki/Permalink) that is uniquely versioned or fingerprinted and _independent of the web application environment(s)_. + +- They must be configured for long-term caching. (`cache-control: public, max-age=31536000, immutable`) + +- __They must not contain any environment-specific configuration.__ + +### `index.html` ___is___ configuration + + An `index.html` exists for each environment. + +- They must contain fully-qualified references to the _permabundle_ assets. + +- They must never be cached by the browser or a public cache that cannot be purged on-demand. (`cache-control: no-store`) + +- __They must define all environment-specific configuration.__ + ## Workflow The workflow is defined by its separation of build tasks and release tasks. Specifically, the publishing of permabundles as a _build_ and the publishing of index.html as a _release_. From 6ba89b59348c0d949a2b8070e701a2f05147d0b7 Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Tue, 2 Oct 2018 09:25:31 -0400 Subject: [PATCH 7/8] adding more structure to the 'decomposition' section, unfinished. --- README.md | 120 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 68 insertions(+), 52 deletions(-) diff --git a/README.md b/README.md index a3b5e46..f11d45e 100644 --- a/README.md +++ b/README.md @@ -21,48 +21,48 @@ These principles are inspired by [The Twelve-Factor App](https://12factor.net/). ## Decomposing a web application -The _Immutable Web App_ methodology was developed by through a process of decomposing web applications based on the principles declared above and then reconsidering the relationship between the different components. Before defining the methodology, this document will step through the decomposition. It starts with a monolithic web application. +The _Immutable Web App_ methodology was developed by through a process of decomposing web applications based on the principles declared above and then reconsidering the relationship between the different components. Before defining the methodology, this document will step through the decomposition. -### The Monolithic Web-Application +### The anatomy of a single-page application -There generally are three types of network traffic commonly made in by web application from the browser: +The infrastructure for a single-page application must support serving three different types of requests. These three types of requests have different characteristics that should impact the infrastructure that supports them. -#### static assets +#### document + +- Entry point to the single-page application. +- A small HTML document that returns references to the static assets and just enough to bootstrap the loading of the application. +- Must not be cached by the browser so that changes to the document or static assets are immediately available. Changes are usually in the form of a deployment. +- Served for all routes that do not refer to static assets or apis to support client-side routing. -- javascript, css, images, bundled assets -- long term cached -- artifacts live on the client +#### static assets -#### xhr/fetch +- The javascript, css, images and other physical files that compose the single-page application. +- Properly versioned or fingerprinted static assets can be cached over a long term. +- Delivery is stable and unlikely to cause failures or web server downtime. -- dynamic -- no cache +#### api -#### the document +- All other dynamic http requests, usually executed as an XHR. +- Responses are seldom be cached by the browser. +- The complexity of api requests is higher, contain more dependencies, and more likely to cause failures than delivering static assets. -- typically in the form of `index.html` -- no caching -- returned for all routes that aren't physical files +### The Single-Page “Monolith” > An image of typical network traffic for a simple single page application -A monolithic web application will handle the requests for all three types of requests. Express, a very popular node framework for building web applications, generally supports handling all three types of requests. Running the `express-generator` will create an application skeleton that supports routes for each: +All of the requests for an application can be handled by a single process. Express, a very popular Node.js web application framework, supports handling all three types of requests as a part of the same node process: ```javascript var express = require('express'); var path = require('path'); -var cookieParser = require('cookie-parser'); -var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var app = express(); -app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); -app.use(cookieParser()); /* serves static assets */ app.use(express.static(path.join(__dirname, 'public'))); @@ -70,73 +70,89 @@ app.use(express.static(path.join(__dirname, 'public'))); /* serves the document */ app.use('/', indexRouter); -/* serves dynamic requests */ +/* serves the api */ app.use('/users', usersRouter); module.exports = app; ``` -A monolithic web application will also include a web application framework, like Angular, for building the single-page application assets. Using Express and Angular together in a single code base will results in a multi-stage build: +#### Architecture -- First the static Angular apps are generated and -- Then the assets are embedded in the creation of the executable package (docker image, rpm). +> Image of a machine running the express nod app with static files in it serving all three request types -The package is then typically stored in a versioned repository of packages before it is deployed to a runtime environment. +- Web application + +#### Workflow > An image of the monolith build process: code => build static assets => build docker image with assets baked in => publish image to docker repo => deployed to server -#### Characteristics of the monolithic web application +1. First the static Angular apps are generated and +2. Then the assets are embedded in the creation of the executable package (docker image, rpm). +3. The package is then typically stored in a versioned repository of packages +4. It is deployed to a runtime environment. -- separation release tasks from build tasks (good) -- high cohesion between the backend and frontend contract (good) -- ability to test the same build artifact in multiple environments (good) -- if the backend goes down, so does the frontend - serving static assets is much more reliable then dynamic backends, and gracefully handling backend outages is a better user experience than 404s and 500s (bad) -- zero downtime deploys can be tricky considering caching and existing browser sessions (bad) -- complicated project dependencies that represent two very different jobs (bad) - - building a static web application assets - - running a web server +#### Characteristics -### Separate frontend from backend +There are several benefits to the encapsulation of an entire web application: -The first stage of decomposition is to separate the client from the server. This aligns with the principle of strict separation of dynamic content from static content. +- There is high cohesion between the contract of the client and the server. +- Creating a single executable package decouples the build from the deploy and enables the ability to test the package in multiple environments before promoting it to production, reducing risk during a live release. -> An image of the two separated build processes: -> code => build static assets => publish to static web server with routing rules -> code => build docker image => publish image to docker repo => deploy to server +However there are several drawback: + +- Serving the static assets and api in the same process means that if the api causes a crash the web application is completely unavailable. +- The dependencies to run a web application are very different than the dependencies to generates the static assets. It can be difficult to manage the dependencies of the project in a way that does not bloat the codebase. + +### The Single-Page Frontend/Backend + +The first stage of decomposition is to separate the client from the server. This aligns with the principle of strict separation of dynamic content from static content. It also aligns with the best practices recommended by many web application platforms, like Angular. -#### The static web application +#### Architecture -code base generates static assets, +> Image of an web server with static files serving static assets and document, image of a web api serving api calls -The static assets can be deployed to a static web server that will have much higher reliability than the backend. +- Web server with static assets -The static web apps should generally be cached for the long term, the backend should have caching turned off. +- Web API -#### The backend api +#### Workflow -code base generates an executable package. +> An image of the two separated build processes: +> code => build static assets => publish to static web server with routing rules +> code => build docker image => publish image to docker repo => deploy to server + +#### Characteristics + +There are some improvements from the _single-page monolith_: -generally you can read up on 12 factor app for help here, as it has been decoupled from many of the web application specific concerns +- Two separate code bases are streamlined to handle their single responsibility. -#### Characteristics of the frontend/backend web application +- Independently hosting the static assets will allow the app to continue to operate even if the api is unavailable. -deployments require a little more careful sequencing to avoid zero-downtime. The backend may need to support multiple versions of an app as the frontend is deployed from one version to another. this is good, because it makes an preexisting problem more visible. +But we have also introduced some complexity: -Code bases for generating the backend and the code base for generating the static application is separated. +- Application platforms, like Angular, recommend defining environment specific configuration at build time. This eliminates the portability of the assets and effectively eliminates the separation of deploy tasks from build tasks. -Client side assets are often environment specific and deployed right after they are built as a part of a release. +- There is less cohesion between the frontend and the backend. Because they are not deployed atomically, deployments must be phased to support multiple running versions of the application. The reality is that this is also a problem with single-page monoliths, it is just not as obvious. -### index.html as a special file +### The Single-Page Decomposed App -The second stage of decomposition continues to emphasize the strict separation of dynamic content from static content by separating `index.html`. +The second stage of decomposition is going to separate the document (typically, `index.html`) from the static assets. The document, `index.html`, is a bit of a special case. It may be a static file from the perspective of a specific deployment, but over the lifetime of multiple deployments, it is a dynamic file... evident by the fact that it cannot be cached at any location by the browser. Moreover, it has routing responsibilities that are unlike any of the other static assets or apis. +#### Architecture + > An image of the three separated build processes: > code => build static assets => publish to static web server > code => build docker image => publish image to docker repo => deploy to server > index.html => publish to static web server that always returns index.html +#### Workflow + + + + #### `index.html` can be hosted by a static web server that for whatever path it is requested it always returns `index.html` @@ -145,7 +161,7 @@ can be hosted by a static web server that for whatever path it is requested it a it allows us to simplify the hosting of all other static assets, all other static assets can be hosted in a completely different domain, and cached for long term if they are versioned or fingerprinted -#### Characteristics of the index/frontend/backend web application +#### Characteristics assets can be build prior to deployment, a live release is effectively the act of updating `index.html`, but opportunities for testing them are limited. From 7be61858a769e267ee7f9f1a624e4376b2597e18 Mon Sep 17 00:00:00 2001 From: geneconnolly Date: Thu, 18 Oct 2018 00:12:38 -0400 Subject: [PATCH 8/8] minor changes --- README.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f11d45e..af518b6 100644 --- a/README.md +++ b/README.md @@ -13,25 +13,25 @@ _Immutable Web Applications_ is a framework-agnostic methodology for building an The methodology is based on the principles of ___strictly separating___: -- Dynamic content from static content. - Configuration from code. - Release tasks from build tasks. +- Dynamic content from static content. These principles are inspired by [The Twelve-Factor App](https://12factor.net/). ## Decomposing a web application -The _Immutable Web App_ methodology was developed by through a process of decomposing web applications based on the principles declared above and then reconsidering the relationship between the different components. Before defining the methodology, this document will step through the decomposition. +The _Immutable Web App_ methodology was developed by decomposing web applications based on the principles above and then reconsidering the relationship between the different components. Before defining the methodology, this document will step through the decomposition. ### The anatomy of a single-page application -The infrastructure for a single-page application must support serving three different types of requests. These three types of requests have different characteristics that should impact the infrastructure that supports them. +The web server infrastructure for a single-page application must support three different types of HTTP requests. These three types of requests have different characteristics that should impact the infrastructure. #### document - Entry point to the single-page application. - A small HTML document that returns references to the static assets and just enough to bootstrap the loading of the application. -- Must not be cached by the browser so that changes to the document or static assets are immediately available. Changes are usually in the form of a deployment. +- Must not be cached by the browser so that changes to the document or static assets are instantly available. - Served for all routes that do not refer to static assets or apis to support client-side routing. #### static assets @@ -307,3 +307,16 @@ If the permabundles fails any of this validation it is abandoned. If it succeeds - Use a CDN - Favor a serverless cloud platform + + + + + + + + + + + + +The best practices for all of the leading application frameworks ([Angular CLI](https://github.com/angular/angular-cli/wiki/stories-application-environments), [Create React App](https://cli.vuejs.org/guide/mode-and-env.html#using-env-variables-in-client-side-code), [Ember CLI](https://ember-cli.com/user-guide/#Environments), [Vue CLI 3](https://cli.vuejs.org/guide/mode-and-env.html#using-env-variables-in-client-side-code)) all include specific environment variables during the build. \ No newline at end of file