最近测验将平板程序编译成web运用发布,发布后程序能够运转,可是存在一些问题。现将问题和处理进程记录如下

  1. web运用加载耗时问题

  1. 加载时会去www.gstaic.com下载/chromium/canvaskit.js文件和canvaskit.wasm文件,
  2. 加载时会去www.gstaic.com下载notosanssc字体文件和roboto字体

Flutter 手机端项目转web运行部分问题记录

Flutter 手机端项目转web运行部分问题记录

Flutter 手机端项目转web运行部分问题记录

Flutter 手机端项目转web运行部分问题记录

打包指令

我的打包指令为:

flutter build web -t lib/main.dart --no-tree-shake-icons  --release

处理下载字体的问题

  1. 将需求下载的资源文件预下载放入项目中

  • 从对应的字体网址下载好roboto.ttf和notosanssc.otf
  • 将字体文件放在项目中的资源文件中

Flutter 手机端项目转web运行部分问题记录

  • 在项目的ymal文件中加入Font声明

Flutter 手机端项目转web运行部分问题记录

  • 打包项目,打包后build文件如下

Flutter 手机端项目转web运行部分问题记录

运转测验发现roboto.ttf文件现已能够从资源中下载,可是notosanssc.otf任然会从gstaic.com下载

Flutter 手机端项目转web运行部分问题记录

Flutter 手机端项目转web运行部分问题记录

  1. 处理notosanssc.otf依然需求下载的问题

  • 修该ymal中Roboto字体的资源文件为notosanssc.otf

Flutter 手机端项目转web运行部分问题记录

  • 打包测验

Flutter 手机端项目转web运行部分问题记录

  • 不会再从gstaic中下载文件。这个办法不清楚原因,有知道原因的欢迎谈论指正
  1. 处理canvaskit.js文件和canvaskit.wasm问题

  • buil目录中发现存在canvaskit.js和canvaskit文件

Flutter 手机端项目转web运行部分问题记录

  • 修改–dart-define=FLUTTER_WEB_CANVASKIT_URL为:canvaskit/,即

    • –dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/
  • 此刻编译指令为:

    • flutter build web -t lib/main.dart --no-tree-shake-icons  --release --dart-define=FLUTTER_WEB_CANVASKIT_URL=canvaskit/
      
  • 测验

Flutter 手机端项目转web运行部分问题记录

Flutter 手机端项目转web运行部分问题记录

  • chrome和safari加载时间不一致的问题

    • canvaskit.wasm这个文件在chrome中需求耗时16s,在safari只是需求60ms

    • chrome

    • Flutter 手机端项目转web运行部分问题记录

    • safari

      • Flutter 手机端项目转web运行部分问题记录
    • 这个问题也不清楚原因,暂时未处理

参考:我把FlutterWeb烘托模式改成Canvaskit后… – 掘金

  1. web浏览器刷新,url会重置的问题

我的项目是一个插件项目,需求主程序经过url传入一个资源地址,然后插件项目读取地址栏的地址,去下载并加载对应文件。首要代码如下:

void main() async {
  String? assetsApi = Uri.base.queryParameters['assetsApi'];
  printDebug("wbeApp start assetsApi:$assetsApi");
  runApp(MyApp(interface: MyControl(assetsApi: assetsApi ?? "")));
}
Widget build(BuildContext context) {
  return GetMaterialApp(
    home: AppUI(
      interface: interface,
    ) ,
  );
}
  • 此刻debug直接运转:http://localhost:51335/#/

Flutter 手机端项目转web运行部分问题记录

  • 修改地址运转:http://localhost:51335/?assetsApi=http://172.16.132.147:5000/api/roomConfig/downloadAppUIAssets?roomId=tAnHi86sRdsFbTzF4

此刻程序能够读取地址栏的url,并正确加载

Flutter 手机端项目转web运行部分问题记录

  • 可是加载完成后,无法记录我们输入的url地址栏url再次变为:http://localhost:51335/#/

  • 处理办法

    • 运用setUrlStrategy办法
    • import 'package:flutter_web_plugins/flutter_web_plugins.dart';
      void main() async {
        String? assetsApi = Uri.base.queryParameters['assetsApi'];
        printDebug("wbeApp start assetsApi:$assetsApi");
        setUrlStrategy(PathUrlStrategy());
        runApp(MyApp(interface: MyControl(assetsApi: assetsApi ?? "")));
      }
      
    • 对app增加router
    •   Widget build(BuildContext context) {
          String basePath = Uri.base.path;
          debugPrint("basePath:$basePath");
          String router = "/?assetsApi=${interface.url}";
          debugPrint("router:$router");
          return GetMaterialApp(
            initialRoute: router,
            routes: {
              router: (_) {
                return AppUI(
                  interface: interface,
                );
              }
            },
            onGenerateRoute: (settings) {
              debugPrint('onGenerateRoute name: ${settings.name}');
            },
            onUnknownRoute: (settings){
              debugPrint('onUnknownRoute name: ${settings.name}');
            },
            // home: AppUI(
            //   interface: interface,
            // ) ,
          );
        }
      }
      
    • 此刻从url加载完成程序后,地址栏不会重置,会记住上次的目录
    • initialRoute的值不知道怎么填写的时分,能够从onUnknownRoute或许onGenerateRoute中寻找
  1. dart.io和dart:js

web项目中运用dart.io库中的API时会反常报错

非web项目无法运用dart:js的API时也会反常

那怎么在一个功能中经过渠道判别来运用不同的API呢

  1. 怎么在同一个项目中同时运用dart.io和dart.js两个库的

操作如下:

  • 界说接口类abstract class,运用import if 来做头文件导入判别
import 'desktop_mobile.dart'
  if (dart.library.html) 'web.dart';
abstract class App{
  Future<Map> init();
  factory App() => getApp();
}
  • 完成非web接口类

    • import 'dart:convert';
      import 'package:flutter/services.dart';
      import 'app.dart';
      class MobileApp implements App {
        @override
        Future<Map> init() async {
          String data = await rootBundle.loadString("assets/project_json.json");
          Map jsonData = jsonDecode(data);
          return jsonData;
        }
      }
      App getApp() => MobileApp();
      
  • 完成web接口类

    • 从js传过来的json格式数据可能导致dart无法辨认,所以改为传jsonString
import 'dart:convert';
import 'package:flutter/services.dart';
import 'app.dart';
import 'dart:js' as js;
class WebApp implements App {
  @override
  Future<Map> init() async {
    String? jsonString = js.context["appConfig"];
    jsonString ??= await rootBundle.loadString("assets/project_json.json");
    return jsonDecode(jsonString);
  }
}
App getApp() => WebApp();
  • 运用
import 'app/app.dart';
Map jsonData = await App().init();
  1. runtimeType在web和手机端不同

web渠道下数据的runtimeType和非原生不一样,判别数据类型时最好用is关键字来判别

如:

dynamic values = json[key];
  if (values != null && values is Map) {
}

而不运用

      dynamic values = json[key];
      if (values != null && values.runtimeType.toString().contains("Map")) {
      }

以下是部分整理

  1. macos渠道

// int
dynamic int1 = 1; // int
int int2 = 1; // int
// double
dynamic double1 = 1.0;  // double
double double2 = 1.0; // double
// number
dynamic num1 = 2; // int
dynamic num2 = 2.0; // double
num num3 = 2; // int
num num4 = 2.0; // double
// string
dynamic string1 = "1.0"; // String
String string2 = "1.0"; // String
// map
dynamic map1 = {"1":2};// _Map<String, int>
dynamic map2 = {"1":2,"2":"2"};// _Map<String, Object>
dynamic map3 = {"1":2,"2":"2",1:'2'};// _Map<Object, Object>
Map map4 = {"1":2}; // _Map<dynamic, dynamic>
Map<dynamic,dynamic> map5 = {"1":2}; // _Map<dynamic, dynamic>
Map<String,dynamic> map6 = {"1":2}; // _Map<String, dynamic>
Map<dynamic,String> map7 = {"1":"2"};// _Map<dynamic, String>
// list
dynamic list1 = [1,2];// List<int>
dynamic list2 = ["1",2];// List<Object>
dynamic list3 = [1,2,{}];// List<Object>
List list4 = [{"1":2},{"1":2,"2":"2"}];// List<dynamic>
  1. web渠道

// int
dynamic int1 = 1; // int
int int2 = 1; // int
// double
dynamic double1 = 1.0;  // int
double double2 = 1.0; // int
// number
dynamic num1 = 2; // int
dynamic num2 = 2.0; // int
num num3 = 2; // int
num num4 = 2.0; // int
// string
dynamic string1 = "1.0"; // String
String string2 = "1.0"; // String
// map
dynamic map1 = {"1":2};// IdentityMap<String, int>
dynamic map2 = {"1":2,"2":"2"};// IdentityMap<String, Object>
dynamic map3 = {"1":2,"2":"2",1:'2'};// LinkedMap<Object, Object>
Map map4 = {"1":2}; // LinkedMap<dynamic, dynamic>
Map<dynamic,dynamic> map5 = {"1":2}; // LinkedMap<dynamic, dynamic>
Map<String,dynamic> map6 = {"1":2}; // IdentityMap<String, dynamic>
Map<dynamic,String> map7 = {"1":"2"};// LinkedMap<dynamic, String>
// list
dynamic list1 = [1,2];// List<int>
dynamic list2 = ["1",2];// List<Object>
dynamic list3 = [1,2,{}];// List<Object>
List list4 = [{"1":2},{"1":2,"2":"2"}];// List<dynamic>
  1. Flutter web嵌入web项目

Flutter build的产品作为一个静态资源放在web项目中,web项目想调到flutter页面中,运用window.open函数

window.open(URL,name,specs,replace)