前言
我们之前已经对Flutter For Web做过了简单的入门介绍,之后我们团队就探索了下使用Flutter开发web的可行性,根据我们的调研结果,对Flutter For Web的前景非常看好,于是,我们在Preview版本上,做了率先吃螃蟹的人。
没错,我们不是尝试、不是介绍,是真的使用Flutter开发了第一个web需求并且发布了。
我们首先分析了下自己的需求,我们的需求并不是一些简单的展示页面,是一个包含图片、列表、文字、富文本、输入框、单选框、复选框、按钮、loading框、网络请求、页面跳转、跟客户端jsbride交互等各种操作并且包含六个页面的一个完整需求(由于项目还没发布,这里暂时不上截图了,具体需求可以见Now直播客户端下一个版本的注销账户页面)。这样的需求基本上客户端上web页面的一个完整需求。
基于上面需求,我们再来回头看下Flutter For Web的一些基本要求,一个正常的需求,我们需要了解如何开发、如何调试、如何构建、如何发布。
如何开发
我们首先分析下Flutter Web Project,看下面的截图
重点分析下项目中的三个文件夹
- .****vscode:这一个文件夹是vscode创建项目自动生成的,为什么要提下呢,因为这里面有个文件叫launch.json,这个文件后面分析下。
- lib:这就是写dart代码的主要区域,这里面你可以像移动端的Flutter项目一样写dart代码。我们的项目目录由pages、utils、widget等组成,并且下面有一个自动生成的main.dart文件。
- web:这就是web的主目录了,这个目录主要是包含index.html和一个main.dart文件。但是如果你需要有资源文件、js文件等web所需资源,比如我们的assets文件夹用来放图片资源。
这里再重点看下项目中的这五个文件,
- launch.json: 为什么要提下自动生成的文件呢,我们先看下这个文件中的内容,
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Dart",
"program": "lib/main.dart",
"request": "launch",
"type": "dart"
}
]
}
这个文件有指出,需要调用的主dart是lib/main.dart,这里是可以配置的,如果错误的设置成bin/main.dart,会报错。
- pubspec.yaml:这个文件主要是flutter的项目配置文件,对比flutter for mobile项目,还不支持plugin。 项目依赖还是flutter_web。
- web下的main.dart:
import 'package:flutter_web_ui/ui.dart' as ui;
import 'package:logout_account/main.dart' as app;
main() async {
await ui.webOnlyInitializePlatform();
app.main();
}
这个文件是整个web app启动的入口,这里会调用平台初始化任务,然后调用整个app的mian来调用lib下的main.dart中的main方法来启动页面。
- lib下的main.dart:
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '注销账户',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: '注销账户'),
);
}
}
这里就和flutter for mobile中的main.dart是一样的,主要是main方法run app,开始启动MaterialApp,加载widget。
- web下的index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注销账户</title>
<script defer src="main.dart.js" type="application/javascript"></script>
</head>
<body>
</body>
</html>
这里就更简单了,这里就是一个简单的html文件,这个html引入一个叫main.dart.js的文件,你会发现新建的项目中是没有这个js文件的,那么这个文件是从哪里来的呢?这里其实是项目自动生成的一个js文件。我们后面会分析下这里。我们不建议在这个html文件中创建任何element、css样式等,但是你可以在这里面加载js文件,如果你需要在dart中调用js文件的方法,请记得加载顺序。
通过上面的分析,你应该知道,这里的开发其实比较简单,如果你完全不需要任何js的引入,那么你直接可以在lib下面开发你的功能就可以,如果你需要引入一些第三方js库或者实现其他的一些js方法,那么你可以在web目录下面开发,在index.html中引入,如果你想自己在index.html中嵌入element、css样式的话,你会发现并不行,但是如果你想嵌入html页面的话,后面我们会教你如何去做。
如何调试
当你环境搭建好并且项目创建好后,你可以直接在终端中运行“webdev serve”来启动,或者也可以通过vscode中的调试窗口启动调试。
这个时候webdev会自动构建并且会启动一个默认浏览器窗口来打开web页面
可以看到log里面将web部署在了64951端口上,并且同时在65028端口上打开了devtools。web的devtools目前还并不完善,但是可以用一些基础的比如查看控件等功能。
这里也是支持hot reload的,如果你修改了dart文件或者其他文件只要你在当前文件点击ctrl+s就会自动构建,刷新页面就可以执行新的功能,非常方便。
代理调试工具是前端开发代理是必不可少的,我们建议使用的工具是whistle,whistle是基于Node实现的跨平台web调试代理工具,非常轻量也非常好用,并且有多中匹配方式。而chrome的代理设置工具则是直接用的SwitchyOmega这个插件。两者配合使用非常方便,但是这种方式在PC端是没有问题的,而当手机代理到PC上访问却会有问题,具体的问题我们将在之后的文章中分析解决。
如何构建
开发完成后我们需要将生产的文件发布,那需要发布哪些文件呢?我们来对Flutter For Web的构建和产物来做下分析。上面的调试在启动后,其实是会在.dart_tool文件夹下生成一个build文件夹,这个文件夹中都是生成的中间产物。
而由于需要支持hot reload,所以在debug模式下会生成多个JS文件,这点我们可以在一个页面加载的资源中看到
可以看到,这个页面加载了很多js、html等文件。
那我们如果需要发布的时候,是不是也需要这么多文件呢,如果这样的话,将会对发布造成很大负担,因为要发很多文件。根据官方的指引,我们是用“webdev build -r”命令生成发布产物看下。
执行这个命令后,会在项目目录下生成一个build文件夹,而不是在dart_tool文件夹下生成的。这个文件夹下生成的内容如下:这个目录下有两个文件夹、四个文件,那我们需要发布哪些文件呢?我们来分析下这下面的几个文件夹和文件。
- assets: 资源文件夹,打开后发现这里存的是web目录下的资源文件,那说明这个是必须要发布的。
-
packages:
这个文件夹下有大量的中间产物,那这些中间产物是不是需要发布呢,我们只需要看下会不会像debug那里被加载就可以了,如果会被加载就需要发布,如果不会就不需要发布。
- .packages:这里表示的是引用的包名,这是输出的配置文件log不需要发布。
- .build.manifest:这里是build的清单文件,输出log使用,不需要发布。
- index.html:这里和web目录下的index.html一样,是整个web app的访问入口,必须要发布。
-
main.dart.js:
这是通过dart2js将使用dart写的flutter代码生成了js便于加载,你所写的flutter ui样式、dart业务逻辑等都将转成js输出到这个文件中,然后被index.html加载,最后渲染呈现在webview上。所以这里就是为什么开始时候说不需要在index.html中写css样式,因为在这里是不会被识别的。
之后我们将这里的所有文件复制到我们的web服务器下查看加载文件(我这里以tomca为例示意):
我们发现只加载了index.html和main.dart.js文件,不再像debug模式的那样加载一大堆文件,还有一个FontManifest.json文件,这个文件没有会不会影响呢,我们注意到控制台有这么一句话Asset manifest does not exist at
assets/AssetManifest.json
– ignoring.
也就是说这个资源是可以不用配置的,我们这里没需要所以没配置,可以忽略这个错误。那这就说明了我们是不需要发布packages文件夹下的那些文件的,只需要将index.html、main.dart.js以及assets文件夹下的资源发布就可以了,这就比较简单了。
如何发布
当我们知道了需要发布哪些文件后,就比较简单了,你只需要在公司的web服务器上将自己开发的文件放在你所想要访问的目录下就可以了然后你就可以用这个地址访问你开发的这些功能了。后续我们将探索OCI集成的方式自动编译和发布。
后记
以上,是不是看起来相当简单?没错,这里只是一个开端,接下来我将带你进行一趟愉快的趟坑之旅。这些趟坑之旅包含网络问题、展示问题、输入问题、跟客户端交互等问题,教你如何写出一个Flutter For Web App。欢迎继续追踪。