前言

  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. ArrayPool 源码解读之 byte[] 也能池化?

    一:背景 1. 讲故事 最近在分析一个 dump 的过程中发现其在 gen2 和 LOH 上有不少size较大的free,仔细看了下,这些free生前大多都是模板引擎生成的html片段的byte[]数 ...

  2. 基于Linux的系统排错

    1.系统引导过程概述 2.系统异常及恢复 [1]grub系统引导 1)mbr上446字节丢失 模拟问题: dd if=/dev/zero? of=/dev/vda? bs=446? count=1? ...

  3. 如何实现LRU缓存

    大家好,我是程序员学长,今天我们来聊一聊LRU缓存问题. Tips: LRU在计算机软件中无处不在,希望大家一定要了解透彻. 问题描述 设计LRU(最近最少使用)缓存结构,该结构在构造时确定大小,假设 ...

  4. Android Parsing between JSON and Kotlin Object with Google Gson Library

    Parsing between JSON and Kotlin Object with Google Gson Library dependencies { ... implementation 'c ...

  5. vue 接入 vod-js-sdk-v6.js 完成视频上传

    东西有点多,耐心看完.按照操作一步一步来,绝对能成功 首先:npm 引入 npm install vod-js-sdk-v6 mian.js  全局引入  //腾讯云点播 import TcVod f ...

  6. 理解ASP.NET Core - [03] Dependency Injection

    注:本文隶属于<理解ASP.NET Core>系列文章,请查看置顶博客或点击此处查看全文目录 依赖注入 什么是依赖注入 简单说,就是将对象的创建和销毁工作交给DI容器来进行,调用方只需要接 ...

  7. 使用Keepalived实现Nginx的自动重启及双主热备高可用

    1.概述 之前我们使用Keepalived实现了Nginx服务的双机主备高可用,但是有几个问题没有解决,今天一起探讨一下. 1)在双机主备机制中,Keepalived服务如果宕了,会自动启用备机进行服 ...

  8. 洛谷P3130 haybalesCounting Haybale P 题解

    题目 [USACO15DEC]haybalesCounting Haybale P 题解 最近刚刚自学了线段树这个数据结构,恰巧做到了这道线段树的模板题.其实也没有什么好多说的,接触过线段树的大犇肯定 ...

  9. 被面试官问懵:TCP 四次挥手收到乱序的 FIN 包会如何处理?

    摘要:收到个读者的问题,他在面试的时候,被搞懵了,因为面试官问了他这么一个网络问题. 本文分享自华为云社区<TCP 四次挥手收到乱序的 FIN 包会如何处理?>,作者:小林coding . ...

  10. Typora + PicGo做个人知识库

    最近在做个人知识库,考察了一圈各种平台和工具,发现还是直接用文件系统管理Markdown文件更符合我当前的需求.以Markdown文件作为文字载体,以文件目录作为分类结构,承载以计算机知识为主的学习笔 ...