前言
我们之前已经对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>如何调试
当你环境搭建好并且项目创建好后,你可以直接在终端中运行“webdev serve”来启动,或者也可以通过vscode中的调试窗口启动调试。
这个时候webdev会自动构建并且会启动一个默认浏览器窗口来打开web页面
这里也是支持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样式,因为在这里是不会被识别的。
我们发现只加载了index.html和main.dart.js文件,不再像debug模式的那样加载一大堆文件,还有一个FontManifest.json文件,这个文件没有会不会影响呢,我们注意到控制台有这么一句话Asset manifest does not exist at `assets/AssetManifest.json` – ignoring.
如何发布
后记
欢迎关注我们团队微信公众号,了解我们最新的技术动态。