官网
不可变 Web 应用程序是一种与框架无关的办法,用于构建和部署动态单页应用程序:
- 最大限度地升高实时公布的危险和复杂性。
- 简化和最大化缓存。
- 最大限度地缩小对服务器和运行时环境治理的需要。
- 通过简略、灵便的原子部署实现继续交付。
准则
该办法基于严格拆散的准则:
- 从代码配置。
- 从构建工作中开释工作。
- 来自动态内容的动静内容。
以下概念定义了不可变 Web 应用程序的外围要求。它们与框架和基础设施无关。
Static assets are independent of the web application environment(s)
动态资产是从 Web 利用程序代码库的构建生成的文件(javascript、css、图像)。当它们不蕴含任何特定于环境的内容并且它们被公布到一个独特的、独立的地位时,它们就会变得不可变。
Static assets must not contain anything that is environment-specific
所有当先的应用程序框架(Angular CLI、Create React App、Ember CLI、Vue CLI 3)都倡议在编译时定义环境变量。这种做法要求为每个环境生成动态资产,并针对环境的任何更改从新生成动态资产。
不可变 Web 应用程序援用在全局范畴内定义的环境变量并援用以下两种形式之一:
- 间接从窗口对象
- 通过包装环境变量的注入服务
一个例子:
动态资产必须托管在惟一且独立于 Web 应用程序环境的地位。
不蕴含任何特定环境的动态资产能够构建一次,公布到惟一地位,而后在 Web 应用程序的多个环境中应用。
这些动态资产与内容交付网络 (CDN)(Google 托管库、cdnjs、jsDelivr、UNPKG)上托管的 javascript 库具备雷同的品质:
https://ajax.googleapis.com/a…
下面的 jquery 库的地位,被有数的 web 应用程序援用,既独立于应用程序,又是惟一的版本。
https://assets.myapp.com/apps…
同样,Web 应用程序 javascript 文件的地位是惟一的,并且托管在专用于动态资产的地位。动态资产 Web 服务器是 Web 应用程序版本的存储库。
Configure the static assets for long-term caching
不蕴含任何特定于环境的内容并托管在惟一且永恒地位的动态资产能够配置为由浏览器(简直)无限期地缓存:
cache-control: public, max-age=31536000, immutable
index.html 是可部署的配置
单页应用程序的 HTML 文档(通常是 index.html)不是动态的。它因环境和部署目的地的不同而有所差别。HTML 文档是特定于环境的配置和定义 Web 应用程序的不可变动态资产的组合。
index.html 蕴含对动态资产的齐全限定援用。
看个例子:
index.html must never be cached
留神:为了容许立刻更改 Web 应用程序环境,index.html 绝不能被浏览器或无奈按需革除的公共缓存缓存:
cache-control: no-store
不可变 Web 应用程序将公布工作与构建工作拆散为两个不同的工作流。
构建
不可变 Web 应用程序的代码库负责构建动态资产并将它们公布到动态 Web 服务器。代码库的每个状态都能够由位于惟一地位的一组动态资产示意。并非代码库的每个状态都须要公布,但代码库的任何单个状态都不须要屡次公布。
通常,代码库是与继续集成系统集成的源控制代码存储库,该零碎可能构建、版本控制并将动态资产公布到动态 Web 服务器。
这方面的一个例子可能是:
一个托管在 GitHub 存储库中的 Angular 我的项目。当提交被推送到主分支时,repo 与 TravisCI 集成以构建和版本资产。版本化资产公布到 AWS S3 存储桶中的惟一地位。
公布
index.html 文件独立于代码库进行治理,它们充当每个环境的清单。它们应被视为配置文件并进行相应治理。此外,须要有一种机制来批改或替换每个 Web 应用程序环境中的 index.html。更改 index.html 的行为实际上是一种部署。
这方面的一个例子可能是:
一组 index.html 文件,每个环境一个,托管在 Github 存储库中。该存储库与 TravisCI 集成以在批改为 AWS S3 存储桶时公布 index.html 文件。有一个专用于每个 Web 应用程序环境的 index.html 和 S3 存储桶。
这种构建和公布拆散的工作流,其底层根底设置如下图所示:
反对不可变 Web 应用程序的基础架构由三局部组成:
- Web 应用程序服务器:通过提供 index.html 来托管 Web 应用程序环境的动态 Web 服务器。
- 动态资产服务器:用于托管不可变动态资产的动态 Web 服务器。
- API:一个或多个公开裸露的端点以与 Web 应用程序后端交互。
构建动态资产是一个简单的过程,通常波及:
- 依赖解析
- 下载库文件
- Transpiling
- Minifying
- Bundling
- Uglifying, Code Splitting, Tree Shaking, * Autoprefixing…
这些过程十分耗时,重大依赖内部依赖性,并且通常以看似不确定的形式运行。它们不是应该通过立刻将生成的资产公布到生产环境而无需验证来完结的过程。即便公布多个大型动态资产的行为也是一个可能被中断并使 Web 应用程序环境处于损坏状态的过程。
不可变 Web 应用程序生成一次并公布一次到某个地位。此过程产生在实时公布之前。它们能够在暂存环境中进行验证并晋升到生产环境,而无需以显着升高的危险从新生成。
Atomic live releases – 原子实时公布
不可变 Web 应用程序的实时公布是公布单个 index.html 文件的行为。部署是即时的,所有资产都能够立刻应用,而没有任何缓存在公布时被毁坏的危险。
回滚与部署一样有危险,而且通常危险更大。对于不可变 Web 应用程序,部署的雷同品质实用于回滚。值得注意的是,在回滚的状况下,大多数浏览器仍会缓存以前的资产。
万一浏览器尝试加载旧版本的 index.html,以前版本的所有资产依然可用且未损坏。
简化的缓存策略
治理缓存管制标头可能令人生畏,尤其是当 Web 应用程序基础架构利用 CDN 应用的公共缓存时。缓存中最简略的两个概念是:“始终缓存”和“从不缓存”。不可变 Web 应用程序蕴含这些概念,将能够“始终缓存”的代码与“从不缓存”的配置齐全离开。
简化的路由策略
当先的应用程序框架在其部署倡议中没有将动态资产的地位与 index.html 离开。相同,他们倡议向 Web 服务器增加路由规定,为所有未解析为物理文件的门路返回 index.html。
这些路由规定的实现可能因 Web 服务器而异,谬误通常会导致门路解析为谬误的资源。
将 index.html 的托管和动态资产离开能够打消这种危险。动态资产服务器始终提供由 url 示意的物理文件,而 Web 应用程序服务器始终为任何 url 提供 index.html。
不可变的 Web 利用通常与下列这些概念具备亲密关联:
- 古代应用程序框架:Angular、React、Vue 和 Ember 使团队可能构建越来越简单的单页动态应用程序。像 webpack 这样的工具进步了创立、优化和治理构建工件的能力。
- DevOps:DevOps 文化使 Web 应用程序开发人员可能合成和从新评估其 Web 应用程序基础架构,以更好地满足其 Web 应用程序的需要。
- 成熟的应用程序模式和实际:后端应用程序和服务正在围绕一组反对可移植性、可扩展性和高可用性的最佳实际进行交融。这种趋势极大地减少了可用的工具和服务,尤其是与容器和容器编排相干的工具和服务。许多这些实际刚刚开始利用于动态单页 Web 应用程序。
更多 Jerry 的原创文章,尽在:” 汪子熙 ”: