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 beta

flutter upgrade

flutter config --enable-web

flutter create myapp

cd myapp

flutter run -d chrome

flutter config --enable-web

添加flutter对web的支持,可以使用Chrome

原理

image.png

为了使得一套代码可以共享到各个平台,并且没有差别,开发者保留最顶层的dart:ui,在浏览器用Web技术重新实现一次完整的dart:ui API。

将flutter项目编译成web项目并且在浏览器中展示,一共分为三个阶段:

  1. 创建Widgets
  2. 元素布局
  3. 页面绘制

 

创建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表达图片,我们会回到画布。

 

 

 

渲染结果 ⬇️

 

image.png

docker

概念

docker官方解释是一个软件容器平台。douker中有几个重要的概念。

  • Image 镜像:镜像是轻量级的,可独立执行的软件包。比如在服务器上使用flutter来编译项目时,传统配置,我们需要下载Android sdk ,flutter sdk ,在没有软件的情况下,我们可能还需要java sdk,并且配置系统path等复杂的环境配置,如果换一套电脑,又需要重新配置环境。但是使用docker镜像,只要在执行文件中引入镜像,就可以完成环境的配置。只要执行文件不变,在任何一台机器上面,都可以快速搭建相同的环境。
  • Container 容器:像是镜像运行时的一个载体,在引入镜像,并且使用镜像进行一系列操作后,存放产物的“容器”,比如说编译完成的网站。依托 Docker 的虚拟化技术,给容器创建了独立的端口、进程、文件等“空间”,Container 就是一个与宿机隔离 “容器”。

优势

  • 在这次实践中,明显感觉到,传统配置环境的复杂,并且复用性很差,迁移服务器则需要重新配置。但是使用docker,只要执行文件不变,就能保证环境的一致性。
  • 另外容器中的镜像可以相互复用,但是容器与容器之间却是相互隔离的,更加便于管理,不会出现环境冲突等问题。
  • 轻量。多个 Docker 容器可以共享这台机器的操作系统内核,启动迅速,占用少量的内存空间。镜像是通过文件系统层进行构造的,并共享一些公共文件。这样就能尽量降低磁盘用量,并能更快地下载镜像。

Jenkins

原理

持续集成

持续集成是一种软件开发实践,倡导开发者可以每天多次集成项目,每次的集成都是通过自动化的构建来验证,包括合并代码、打包、测试和通知分发的一系列软件工程开始的操作。

Jenkins

最流行的开源免费持续集成工具,由java语言开发,用于监控持续重复的工作,包括:持续的软件版本发布/测试项目,监控外部调用执行的工作。

 

⬇️Jenkins工作流程图

image.png

实践过程

环境搭建

准备一台云服务器,我是用的腾讯云 Linux.Centos7.6环境。但是,如果在远程打包,最好是mac环境,linux版本的Flutter不支持build web。

安装docker和Jenkins,并且设置Jenkins自动拉取代码。

参考⬇️(虽然是最后部署Vue,原理是一样的)

juejin.im/post/5d369d…

大体过程

  1. 将代码部署在github上,本地打包完成之后,生成build/web 文件夹,将代码上传github。
  2. 当master分支上传项目时,会Jenkins的自动构建,拉取github上的项目。
  3. Jenkins拉取完成之后,执行项目中的构建脚本文件 setup.sh。
  4. 文件中会执行docker命令,配置nginx服务器,将build/web中的文件放入指定目录。

然后就可以通过网址访问了。

相关配置文件

(只留下关键代码,未做详细配置)

setup.sh

 

#!/usr/bin/env bash

image_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 nginx

COPY 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来查看生成的镜像。镜像是可以重复引用,提高构建效率。

image.png

docker ps -a来查看当前所有运行中的容器。

image.png

只有up状态的才表示正在运行中。如果运行失败,可以通过查看容器日志来寻找错误。

 

使用Flutter web 优缺点

  1. 对于客户端开发人员来说,特别是涉及到flutter开发的,可以零成本过渡到web项目的开发。对于现有的flutter项目,再剔除安卓特有的功能后,项目代码保持100%的可移植性。
  2. 各个端的表现差异不大,不必过于担心适配问题。

 

  1. Linux版本不支持flutter build web, 无法在远程打包,可能需要一台mac服务器专门部署项目。
  2. flutter插件与镜像支持web的数量过少,很多如发送请求的插件可能都需要自己进行封装,目前只推荐做宣传页等逻辑偏少的静态界面。
  3. 很主要的一点,项目打包体积过大。单纯一个hello world 可以打包出2M的大小,直接导致白屏时间长。
  4. 由于web端一大部分由canvas进行绘制,当频繁缩放屏幕等需要进行页面重绘的操作时,很容易面临性能的问题。
  5. 由于自身Flutter Web并没有专门的开发者工具,而Chrome自带的工具无法准确找到关键元素,导致后续开发调试困难。

综上所述,flutter web当前并不适用与生产环境,官方也不推荐,1.19.x版本还是处于技术预览阶段。但是其良好的分层设计,各个端的代码零成本移植还是有非常大的前景。Dart现如今几乎只为flutter所服务,谷歌对Flutter投入也很大,期待其新版本技术的成熟。

 

以上是 Flutter web持续集成实践 的全部内容, 来源链接: utcz.com/a/23353.html

回到顶部