在Node.js上运行Flutter Web应用和API
大量的跨平台应用开发框架,使你可以编写一次代码,然后在 Android,iOS 等多个平台上甚至在台式机上运行。你可能听说过一些流行的框架,例如 Ionic,Xamarin 和 React Native。另一个相对较新的框架是 Flutter。
在本文中,你将学到一些有关 Flutter 的知识,特别是对 Web 的支持,该支持最近在 v1.9 版中可作为技术预览版本使用(https://flutter.dev/web)。你将可以向现有的 Flutter 程序中添加 Web 支持,并将其与简单的 API 一起在 Node.js 服务器上运行。
Flutter 简述
Flutter 是 Google 跨平台开发解决方案之一。虽然它出现的时间不是很长,但其功能集使其成为该领域的强大的竞争对手。
它将你的程序编译为可在 iOS 或 Android 上运行的原生代码,从而获得令人难以置信的性能和帧率。它支持在开发期间进行有状态的热重启,这意味着你可以随时对代码进行更改,并观看它们在模拟器或物理设备上的应用,而无需重新启动程序或丢失程序状态。
Flutter 主要关注 iOS 和 Android。在 1.9 版中已将 Web 支持添加为技术预览。它仍处于起步阶段,可能尚未准备就绪,但肯定令人兴奋且充满希望。正如你将很快看到的那样,只需进行一点的修改即可使用现有的 Flutter 应用并将其编译为 HTML、CSS 和 JS 包。
为什么在 Node.js 上运行 Flutter Web 程序?
Flutter Web 应用可以在任何 Web 服务器上运行。那么为什么要在 Node.js 服务器上托管 Flutter Web 程序呢?好吧,老实说,出于与其他 Web 应用和 API 选择 Node.js 的相同原因:它非常擅于服务大量的简单请求,你可以用 JavaScript 在其中编写前端和后端代码等。
你可能已经有了一个 Node.js API,可将数据提供给 Flutter iOS 或 Android 程序。将 Flutter 程序编译为 Web 应用并将其托管在现有的 Node.js 服务器上可能是当前解决方案的逻辑扩展,而无需增加额外的托管成本。
示范
现在该深入研究代码,看看 Flutter web 的实际应用了。你需要以下工具:
- Android Studio(Android SDK 管理器和模拟器)
- Visual Studio Code Flutter 扩展(或 Android Studio)
- Node.js 12
Flutter 有出色的开发人员文档。如果这是你第一次开发 Flutter 程序,请按照“入门”指南进行设置。
本文中的示例和说明基于 Visual Studio Code,但如果你选择使用 Android Studio,则仍然可以继续学习。
需要 Node.js 12 才能运行 Flutter Weather 程序的 Web 版本以及后端 Weather API。
步骤1:探索示例代码
为了演示如何向现有的 Flutter 应用添加 Web 支持,我们将从一个简单的气象应用开始,该应用已在 Android 10(API level 29)上进行了测试。
手机上的Flutter Weather App
weather app 允许用户查看预定义城市的当前天气。天气数据是从运行在 Node.js 上的后端服务器中检索的。
从 GitHub 复制 weather app 和服务器的源代码:
- briandesousa/weather_app_flutter(https://github.com/briandesousa/weather_app_flutter)
- briandesousa/weather-app-nodejs-server(https://github.com/briandesousa/weather-app-nodejs-server)
提示:
weather-app-nodejs-server
项目库有一个Flutter-web-support
分支,其中包含已启用 Flutter Web 支持的可在服务器运行的完整版本。
最好将两个项目的存储库克隆到同一个父文件夹中。将创建 weather_app_flutter
存储库的内容并将其复制到 weather-app-nodejs-server
存储库内的文件夹中。
探索 Flutter 天气应用
在编辑器中打开 weather_app_flutter
。让我们仔细看看 main.dart
文件。它包含构成程序用户界面的脚手架和小部件。 Home
窗口小部件类具有 fetchWeatherData
函数,该函数调用后端天气 API 来检索数据并更新窗口小部件的状态:
1fetchWeatherData({String location}) async {
2 var url = WEATHER_API_URL location;
3 final response = await http.get(url);
4 if (response.statusCode == 200) {
5 var jsonResponse = convert.jsonDecode(response.body);
6 setState(() {
7 this._weatherData = WeatherData(
8 jsonResponse['weather']['location'],
9 jsonResponse['weather']['temperature'],
10 jsonResponse['weather']['weatherDescription'],
11 );
12 this._apiError = null;
13 });
14 } else {
15 setState(() {
16 this._apiError =
17 'Unable to retrieve weather data from API (HTTP ${response.statusCode})';
18 });
19 }
20}
fetchWeatherData
函数使用 Dart 的 http
包通过 HTTP 连接到服务器。你还可以使用其他 Dart 包,但是如果你打算向 Flutter 程序添加 Web 支持,则这是官方推荐的包。
同时记下 WEATHER_API_URL
常量。在运行程序之前,请先更新此常量的值,以便它可以连接到本地 Node.js 服务器上运行的 API。该网址必须包含你计算机的主机名。Android 模拟器或物理设备无法访问 localhost
URL。
探索 Node.js 服务器和天气 API
在编辑器中打开 weather-app-nodejs-server
项目代码。
编辑器中的Node.js服务器代码
其中有一些重要的文件和目录:
public/api-test.html
文件可用于快速测试启动后服务器是否按预期工作(例如,`http://localhost:3000/api-test.html
)routes/weather.js
文件包含一个简单的 GET API,该 API 接受 path 参数并返回天气数据(例如,http://localhost:3000/api/weather/londonon
)- 你可以在
public-flutter
文件夹中复制气象程序的已编译 web 版本。设置 Node.js 服务器以将文件从该目录提供到根上下文(例如,http://localhost:3000
)
步骤2:向 Flutter 应用添加 web 支持
由于目前 web 支持仍是技术预览,因此需要最新的 Flutter 开发中版本,也称为master channel。在 weather_app_flutter
存储库的根文件夹中,运行以下命令:
1flutter channel master
2flutter upgrade
提示:在Windows上的 Visual Studio Code 的 bash shell 中运行 Flutter 命令时,你可能会遇到 “Unknown operating system. Cannot install Dart SDK.”错误。请尝试在普通的 Windows command shell中运行命令。
升级过程可能需要几分钟。接下来你将需要在 Flutter 安装中启用 Web 支持:
代码语言:javascript复制1flutter config --enable-web
2flutter devices
启用 web 支持后,你将在设备列表中看到一个新的 Chrome 设备。如果没有看到 Chrome,请在运行以下命令刷新设备列表菜单后重新启动 Visual Studio Code。
要将网络支持添加到 weather app,你需要在 weather_flutter_app
项目的顶级文件夹中运行以下命令:
1flutter create .
create 命令将对该程序进行一些修改,你可以在这个提交中看到。最值得注意的变化是添加了一个包含 index.html
的子文件夹 web
:
代码编辑器中的Index.html文件
通过在 weather-app-nodejs-server
的根目录中运行以下命令来启动 Node.js 服务器:
1npm start
从 Visual Studio Code 的设备列表中选择 Chrome,然后开始调试。或者,你可以运行以下 flutter命令:
代码语言:javascript复制1flutter run -d chrome
由于 Flutter 需要即时下载其他依赖项时,你第一次在 Chrome 中启动该应用可能会花费一些时间。最终你将在浏览器中看到天气应用正在运行。可能会有某些样式与你在仿真器或物理设备上看到的样式略有不同。
Chrome中的应用预览
你会注意到该应用没有显示来自天气 API 的任何数据。如果你打开 Chrome DevTools,则会看到跨域资源共享错误。
浏览器不允许 Flutter Web 服务器向 Node.js 服务器发出请求,因为它们运行在不同的端口上。你可以通过在服务器上启用跨域资源共享或安装 Chrome 插件来禁用 CORS 来解决此问题。
我们现在将忽略这个错误,因为在下一步中,我们将直接在 Node.js 服务器上运行预编译的 Flutter Web 代码,从而完全消除跨域请求。
尝试修改 main.dart
文件中的某些代码,然后让 Flutter 重新编译你的程序。你会发现所做的修改不会立即显示在浏览器中。这是因为 Flutter Web 尚不支持热重启。希望不久后能够提供这种支持。
提示:本节中每个 Flutter 命令的详细说明都可以在 flutter.dev 上找到【https://flutter.dev/docs/get-started/web】。
步骤3:在 Node.js 上运行 Flutter Web 应用
现在你可以用 Flutter 在浏览器中运行 weather app,下一步是构建并将其复制到 Node.js 服务器,以与 API 一起运行。
要构建 Flutter Web 应用捆绑包,请运行以下命令:
代码语言:javascript复制1flutter build web
build 命令将生成 build/web
文件夹,其中包含构成天气应用的所有静态文件。
编辑器中 build/web 文件夹中的内容
把 weather_app_flutter/build/web
的内容复制到 weather-app-nodejs-server/public-flutter
。如果你的 Node.js 服务器仍在运行,请重新启动。
通过在的浏览器中访问 http://localhost:3000
,查看在Node.js上运行的程序。这次你的应用程序将会显示从天气 API 检索到的天气数据,而不会出现跨域资源共享错误。
最终运行在浏览器中的程序
最后的想法
取得现有 Flutter 应用并将其编译为可部署到 Web 服务器的 Web 应用如此简单,真是令人难以置信。浏览器中呈现的用户界面看起来几乎与 Android 中的界面相同。
但是不能仅仅由于 Flutter 的 Web 支持而将 Flutter 视为跨平台应用程序框架。Flutter 团队非常清楚, Web 支持缺少功能,存在已知的性能问题并且尚未完全支持生产环境。
可以肯定的是:Flutter for Web 的未来看起来很有希望。你可以在这里(https://medium.com/flutter/hummingbird-building-flutter-for-the-web-e687c2a023a8)了解有关 Flutter Web 支持和 Hummingbird 项目更多的信息。