Flutter web持续集成实践
引言
2018 年 12 月,Google 发布了 Flutter 1.0 正式版,并在2019年9月在发布Flutter 的最新稳定版本:Flutter 1.9,同时,宣布将flutter web 合并到master。flutter web立志于开发人员可以使用相同的代码,更快地发布功能,并确保其跨设备(Android、iOS、Web)体验的一致性。
然而就最新的Flutter1.9.x而言,Flutter Web还处于技术预览版阶段,离真正应用到生产环境中还是有一些距离的。官方也不建议将其运用在生产上,后期将会有很多的优化,而且很多flutter的库还未兼容web环境,实践中也发现很多的坑。
目标
将Flutter web 的Demo用docker与Jenkins完成自动化部署。
www.laohubzy.cn:9527/
技术栈
Flutter Web
因为Flutter将web整合进项目当中,所以在创建web项目时,只要保证分支版本在1.5以上即可。
创建过程:
flutter channel betaflutter upgrade
flutter config --enable-web
flutter create myapp
cd myapp
flutter run -d chrome
flutter config --enable-web
添加flutter对web的支持,可以使用Chrome
原理
为了使得一套代码可以共享到各个平台,并且没有差别,开发者保留最顶层的dart:ui,在浏览器用Web技术重新实现一次完整的dart:ui API。
将flutter项目编译成web项目并且在浏览器中展示,一共分为三个阶段:
- 创建Widgets
- 元素布局
- 页面绘制
创建Widgets
Widget的构建机制不依赖于应用程序运行的环境。该过程只需要实例化内存中的对象并跟踪它们的状态,当状态改变时,计算布局和绘画所需的最小更新。将此部分移植到Web上非常简单,当Dart团队在dart2js中实现了super-mixin支持之后,编译器将所有widget和widget框架编译为JavaScript时几乎没有任何问题;
元素布局
布局系统有点棘手。最大的挑战是文本布局。其他所有Widget - Center,Row, Column, Stack, Scrollable, Padding, Wrap等 - 这些widget都由框架布局,因此无需修改即可编译到Web上运行。我们用来测量文本布局属性的技巧是让浏览器将其布局,然后从DOM元素中读回相关属性。
页面绘制
通过HTML+CSS+Canvas的组合方法,我们将框架生成的图片分类为使用HTML + CSS表达的图片,以及使用Canvas 2D表达的图片。然后,我们输出结合了HTML,CSS和2D画布的HTML DOM。
我们更喜欢HTML + CSS,因为它有浏览器的现实列表支持。这意味着我们可以优化图片的光栅化在浏览器上的渲染引擎。这也意味着我们可以应用任意变换,尤其是旋转和缩放,而不必担心像素化。我们将此画布实现称为“DomCanvas”。
如果我们无法使用HTML + CSS表达图片,我们会回到画布。
渲染结果 ⬇️
docker
概念
docker官方解释是一个软件容器平台。douker中有几个重要的概念。
- Image 镜像:镜像是轻量级的,可独立执行的软件包。比如在服务器上使用flutter来编译项目时,传统配置,我们需要下载Android sdk ,flutter sdk ,在没有软件的情况下,我们可能还需要java sdk,并且配置系统path等复杂的环境配置,如果换一套电脑,又需要重新配置环境。但是使用docker镜像,只要在执行文件中引入镜像,就可以完成环境的配置。只要执行文件不变,在任何一台机器上面,都可以快速搭建相同的环境。
- Container 容器:像是镜像运行时的一个载体,在引入镜像,并且使用镜像进行一系列操作后,存放产物的“容器”,比如说编译完成的网站。依托 Docker 的虚拟化技术,给容器创建了独立的端口、进程、文件等“空间”,Container 就是一个与宿机隔离 “容器”。
优势
- 在这次实践中,明显感觉到,传统配置环境的复杂,并且复用性很差,迁移服务器则需要重新配置。但是使用docker,只要执行文件不变,就能保证环境的一致性。
- 另外容器中的镜像可以相互复用,但是容器与容器之间却是相互隔离的,更加便于管理,不会出现环境冲突等问题。
- 轻量。多个 Docker 容器可以共享这台机器的操作系统内核,启动迅速,占用少量的内存空间。镜像是通过文件系统层进行构造的,并共享一些公共文件。这样就能尽量降低磁盘用量,并能更快地下载镜像。
Jenkins
原理
持续集成
持续集成是一种软件开发实践,倡导开发者可以每天多次集成项目,每次的集成都是通过自动化的构建来验证,包括合并代码、打包、测试和通知分发的一系列软件工程开始的操作。
Jenkins
最流行的开源免费持续集成工具,由java语言开发,用于监控持续重复的工作,包括:持续的软件版本发布/测试项目,监控外部调用执行的工作。
⬇️Jenkins工作流程图
实践过程
环境搭建
准备一台云服务器,我是用的腾讯云 Linux.Centos7.6环境。但是,如果在远程打包,最好是mac环境,linux版本的Flutter不支持build web。
安装docker和Jenkins,并且设置Jenkins自动拉取代码。
参考⬇️(虽然是最后部署Vue,原理是一样的)
juejin.im/post/5d369d…
大体过程
- 将代码部署在github上,本地打包完成之后,生成build/web 文件夹,将代码上传github。
- 当master分支上传项目时,会Jenkins的自动构建,拉取github上的项目。
- Jenkins拉取完成之后,执行项目中的构建脚本文件 setup.sh。
- 文件中会执行docker命令,配置nginx服务器,将build/web中的文件放入指定目录。
然后就可以通过网址访问了。
相关配置文件
(只留下关键代码,未做详细配置)
setup.sh
#!/usr/bin/env bashimage_version=`date +%Y%m%d%H%M`;
# 设置镜像
#
docker build . -t flutter/web:$image_version;
# 运行容器
docker run -p 9527:80 -d --name flutter_web flutter/web:$image_version;
# 查看日志
docker logs flutter_web;
docker build
最后的 .
号,其实是在指定镜像构建过程中的上下文环境的目录,执行当前上下文中的Dockerfil文件构建镜像容器。将容器的80端口映射到服务器的9527端口。之后可以通过 域名(IP地址):9527访问
Dockerfile
FROM nginxCOPY conf.nginx /etc/nginx/nginx.conf
RUN mkdir /app
WORKDIR /app
COPY ./build/web /app/
EXPOSE 80
在Dockerfile中,主要是构建了一个nginx容器。因为Linux版本的Flutter项目并不支持build web, 所以只能本地打包,更改.gitignore文件,将build出来的文件也传到gitlub上面。这边的docker只是将文件复制到nginx容器当中。
*若未来版本中支持Linux打包之后,Dockerfile可以直接拉取flutter与Android sdk镜像,远程打包生成build文件。我在尝试中,远程是可以打包出apk文件,但是无法打出web文件
conf.nginx nginx的相关配置。
events {worker_connections 1024;
}
http {
server {
listen 80;
location / {
root /app/;
index index.html index.htm;
try_files $uri$uri/ /index.html;
}
}
}
执行之后,可以通过docker images
来查看生成的镜像。镜像是可以重复引用,提高构建效率。
docker ps -a
来查看当前所有运行中的容器。
只有up状态的才表示正在运行中。如果运行失败,可以通过查看容器日志来寻找错误。
使用Flutter web 优缺点
优
- 对于客户端开发人员来说,特别是涉及到flutter开发的,可以零成本过渡到web项目的开发。对于现有的flutter项目,再剔除安卓特有的功能后,项目代码保持100%的可移植性。
- 各个端的表现差异不大,不必过于担心适配问题。
劣
- Linux版本不支持flutter build web, 无法在远程打包,可能需要一台mac服务器专门部署项目。
- flutter插件与镜像支持web的数量过少,很多如发送请求的插件可能都需要自己进行封装,目前只推荐做宣传页等逻辑偏少的静态界面。
- 很主要的一点,项目打包体积过大。单纯一个hello world 可以打包出2M的大小,直接导致白屏时间长。
- 由于web端一大部分由canvas进行绘制,当频繁缩放屏幕等需要进行页面重绘的操作时,很容易面临性能的问题。
- 由于自身Flutter Web并没有专门的开发者工具,而Chrome自带的工具无法准确找到关键元素,导致后续开发调试困难。
综上所述,flutter web当前并不适用与生产环境,官方也不推荐,1.19.x版本还是处于技术预览阶段。但是其良好的分层设计,各个端的代码零成本移植还是有非常大的前景。Dart现如今几乎只为flutter所服务,谷歌对Flutter投入也很大,期待其新版本技术的成熟。
以上是 Flutter web持续集成实践 的全部内容, 来源链接: utcz.com/a/23353.html