前言

  Flutter作为一个跨平台UI框架,功能十分强大,仅用一套代码便能编译出Android、iOS、Web、windows、macOS、Windows、Linux等平台上的应用,各平台应用体验高度一致,目测前途一片光明,形势一片大好。

  Flutter支持Android和iOS已经很长一段时间了,相信很多同学对使用Flutter开发Android和iOS应用都已经驾轻就熟了,今天我们就来体验一把Flutter Web。目标是创建一个简单的Flutter Web项目,然后打包部署到服务器,通过浏览器进行访问。

1.创建Flutter工程

  首先我们需要创建一个Flutter工程。我使用了Android Studio来创建工程,如下:

  上图中需要注意的地方是Platforms,在Platforms栏中我们要选择程序运行的平台,因为我们最终要打包出Web项目,所以我们务必勾选Web选项。
  工程创建好之后的目录结果如下:

  除了我们熟悉的Android和iOS目录外,还多了Web目录,Web目录下存放了Web项目所需要的全部文件。

2.编写flutter代码

  接下来,我们编写flutter代码,代码非常简单,仅实现了在主页点击按钮跳转到对应子页面的功能。
  主页 main.dart 的代码如下:

import 'package:flutter/material.dart';

import 'ChildPage.dart';

void main() {
runApp(MyApp());
} class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'xy_flutter',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'xy_flutter'),
);
}
} class MyHomePage extends StatelessWidget {
MyHomePage({Key key, this.title}) : super(key: key); final String title;
final List<HomeMenu> menus = [
HomeMenu('page1', '页面1'),
HomeMenu('page2', '页面2'),
HomeMenu('page3', '页面3'),
]; @override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(title),
),
body: ListView.builder(
itemCount: menus.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(menus[index].title),
onTap: () {
HomeMenu homeMenu = menus[index];
String id = homeMenu.id;
String title = homeMenu.title;
if (id == 'page1') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChildPage(title: title)));
} else if (id == 'page2') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChildPage(title: title)));
} else if (id == 'page3') {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ChildPage(title: title)));
}
},
);
}),
);
}
} class HomeMenu {
String id;
String title; HomeMenu(this.id, this.title);
}

  子页面 child_page.dart 的代码如下:

import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart'; class ChildPage extends StatefulWidget {
final String title; const ChildPage({Key key, this.title}) : super(key: key); @override
State<StatefulWidget> createState() {
return _ChildPageState();
}
} class _ChildPageState extends State<ChildPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(widget.title)), body: Text(widget.title));
}
}

3.打包Web工程

  在工程根目录下执行以下命令进行编译打包:

flutter build web

  命令执行成功之后,编译生成的文件被输出到了 工程根目录/build/web/ 目录下,如下:

4.上传Web工程到服务器

  通过文件传输工具(例如FileZilla等)将编译后生成的所有文件上传到服务器。我上传到服务器的路径为 home/ubuntu/docker/xy_flutter/web/home/ubuntu/docker/xy_flutter/web/ 目录和工程编译出来的web目录对应,即 home/ubuntu/docker/xy_flutter/web/ 目录下的文件和工程编译出来的web目录下的文件完全一致。

5.创建Nginx Docker容器

  接下来,我们在服务器中创建一个Nginx的Docker容器,用来运行Web项目。
  如果服务器还没有安装Docker,需要先安装Docker,关于如何安装Docker可以参考我之前整理的资料 Docker游记1——安装Docker 
  如果已经安装好了Docker,但还没有拉取Nginx的Docker镜像,需要先拉取一下镜像,可以通过如下命令拉取最新的Nginx Docker镜像:

docker pull nginx:latest

  镜像拉取下来之后,可以通过如下命令查看当前所有已拉取下来的镜像:

docker images

  得到的结果如下:

REPOSITORY     TAG       IMAGE ID       CREATED        SIZE
nginx latest 87a94228f133 2 days ago 133MB

  我们可以看到已经有Nginx的镜像了。
  接着我们利用拉取下来的镜像创建一个容器,执行以下命令:

docker run --name xy_flutter -p 8088:80 -d nginx

  这行命令表示使用Nginx镜像创建并持续运行一个名为xy_flutter的容器,并将服务器的8088端口映射到容器的80端口。创建好之后,可以通过以下命令查看创建好的容器:

docker ps

  结果如下:

CONTAINER ID   IMAGE               COMMAND                  CREATED         STATUS         PORTS                                       NAMES
0c6f697a8e0c nginx "/docker-entrypoint.…" 5 seconds ago Up 3 seconds 0.0.0.0:8088->80/tcp, :::8088->80/tcp xy_flutter

  容器创建好之后,我们就可以通过浏览器访问容器对应的Nginx服务了,因为我的服务器地址IP地址是 http://49.234.163.66/ ,容器映射的服务器端口是8088,所以访问地址是 http://49.234.163.66:8088/ ,访问后跳转的页面如下:

  已经看到Nginx在欢迎我们了!

6.部署Web工程

  我们通过浏览器访问Nginx服务时,跳转的页面其实是容器中的 /usr/share/nginx/html/index.html 文件,我们可以进入容器查看。
  执行以下命令进入容器:

docker exec -it {容器ID} /bin/bash

  进入容器后,我们通过`cd`命名访问 /usr/share/nginx/html/ 目录,目录中的文件如下:

  要部署Web工程,把Web工程中的所有文件复制到容器的 /usr/share/nginx/html/ 目录就可以了,Web工程中的index.html会覆盖 /usr/share/nginx/html/index.html 文件。我们通过如下命令把服务器本地的文件复制到容器中:

docker cp {服务器中Web工程目录下的所有子文件} {容器ID}:/usr/share/nginx/html

  我的服务器中Web工程目录下的所有子文件是 home/ubuntu/docker/xy_flutter/web/. ,容器ID是 0c6f697a8e0c ,所以我执行的命令是:

docker cp home/ubuntu/docker/xy_flutter/web/. 0c6f697a8e0c:/usr/share/nginx/html

7.部署完成

  在上述步骤中,我们已经将Web工程拷贝到容器中的指定位置了,到这里部署工作其实也就完成了,我们再次在浏览器中输入 http://49.234.163.66:8088/ 访问,可以看到已经可以打开我们的Web工程了,如下:

  至此,我们就完成了从创建Flutter Web项目到部署至服务器的整个流程!

最后奉上项目地址

Flutter随笔(二)——使用Flutter Web + Docker + Nginx打造一个简单的Web项目的更多相关文章

  1. Web开发之tomcat配置及使用(环境变量设置及测试,一个简单的web应用实例)

    Tomcat的配置及测试: 第一步:下载tomcat,然后解压到任意盘符 第二步:配置系统环境变量 tomcat解压到的D盘 (路径为: D:\tomcat), 配置环境变量: 启动tomcat需要两 ...

  2. Docker容器技术-创建一个简单的Web应用

    一.创建一个简单的Web应用 1.identicon 基于某个值而自动产生的图像,这个值是IP地址或用户名的散列值. 用途: 通过计算用户名或IP地址的散列值,在网站上提供用于识别用户的图像,以及自动 ...

  3. docker nginx实现一个主机部署多个站点

    原文:docker nginx实现一个主机部署多个站点 在某站租赁的虚拟机快到期了,续费得花200多,想到在阿里云新买的服务器,不如把这个也转移过去.域名我就用真实的吧,大家别黑我网站就好了,谢谢各位 ...

  4. django创建一个简单的web站点

    一.新建project 使用Pycharm,File->New Project…,选择Django,给project命名 (project不能用test命名)   新建的project目录如下: ...

  5. 使用Servlet和JSP实现一个简单的Web聊天室系统

    1 问题描述                                                利用Java EE相关技术实现一个简单的Web聊天室系统,具体要求如下. (1)编写一个登录 ...

  6. 自己动手模拟开发一个简单的Web服务器

    开篇:每当我们将开发好的ASP.NET网站部署到IIS服务器中,在浏览器正常浏览页面时,可曾想过Web服务器是怎么工作的,其原理是什么?“纸上得来终觉浅,绝知此事要躬行”,于是我们自己模拟一个简单的W ...

  7. 用Python写一个简单的Web框架

    一.概述 二.从demo_app开始 三.WSGI中的application 四.区分URL 五.重构 1.正则匹配URL 2.DRY 3.抽象出框架 六.参考 一.概述 在Python中,WSGI( ...

  8. IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程

    一.部署Tomcat 二.创建一个简单的Web工程 2.1创建一个新工程 创建一个新工程 设置JDK及选择Web Application (创建的是Web工程) 点击Next,选择工作空间,起个工程名 ...

  9. (转)Web Service入门简介(一个简单的WebService示例)

    Web Service入门简介 一.Web Service简介 1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从I ...

随机推荐

  1. 对于MySQL远程连接中出现的一个问题总结

    2021年9月3日更新补充 (真的心累,本来是个小问题,但是网上帖子都基本差不多,基本都是相同的操作,导致搜了半个多小时才解决) 一.首先为什么要重新发一次呢,因为我发现上次写的这个记录是不完善甚至是 ...

  2. Mysql主从复制、半同步复制、并行复制

    MySQL之间数据复制的基础是二进制日志文件(binary log file).一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以"事件"的方 ...

  3. client-go实战之一:准备工作

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. spring boot 系列之七:SpringBoot整合Mybatis

    springboot已经很流行,但是它仍需要搭配一款ORM框架来实现数据的CRUD,之前已经分享过JdbcTemplete和JPA的整合,本次分享下Mybatis的整合. 对于mybatis的使用,需 ...

  5. 为 Memcached 构建基于 Go 的 Operator 示例

    Operator SDK 中的 Go 编程语言支持可以利用 Operator SDK 中的 Go 编程语言支持,为 Memcached 构 建基于 Go 的 Operator 示例.分布式键值存储并管 ...

  6. Linux下用Sed查找IP地址

    ip addr|sed -n '9p'|egrep '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'|sed -nr 's#^.*inet (.*) b ...

  7. GoLang设计模式05 - 原型模式

    原型模式也是一种创建型模式,它可以帮助我们优雅地创建对象的拷贝.在这种设计模式里面,将克隆某个对象的职责交给了要被克隆的这个对象.被克隆的对象需要提供一个clone()方法.通过这个方法可以返回该对象 ...

  8. DOM对象入门

    1.概念 2.script最好是放在后面,等html的文档内容加载完毕,不然获取不到 3.事件基本操作 第一种绑定事件html和js耦合度高,用第二种 4.灯开关事件使用

  9. EditPlus配置C/C++运行环境

    1.安装MinGW和EditPlus 2.打开EditPlus ctrl+1 编译 ctrl+2 运行

  10. PHP的那些魔术方法(二)

    上文中介绍了非常常用并且也是面试时的热门魔术方法,而这篇文章中的所介绍的或许并不是那么常用,但绝对是加分项.当你能准确地说出这些方法及作用的时候,相信对方更能对你刮目相看. __sleep()与__w ...