flet icon indicating copy to clipboard operation
flet copied to clipboard

Add flet build web --wasm (now available in flutter)

Open hololeo opened this issue 1 year ago • 5 comments

Please add Flutter build web --wasm support to flet

Very exciting changes to Flutter web. It supports compiling main.dart.js into wasm and the skia engine.

The download size is dramatically reduced from 30 megs to 6 megs, and much faster start up of less than 3 seconds vs 10+. see https://docs.flutter.dev/platform-integration/web/wasm

example you can try right now

https://flutterweb-wasm.web.app/

i have tested this on my old iphone6 and it works extremely well

Watch this recent video of the announcement. it is in beta and available as of writing. linked to relevant talk

youtube talk about flutter web wasm

Please include this in Flet so our Flet web pyiode deploys can get much smaller and faster!

Screenshot 2024-04-20 at 9 56 56 PM

hololeo avatar Apr 21 '24 04:04 hololeo

this may also be helpful

Requires JS-interop to access browser and JS APIs
#
To support compilation to Wasm, Dart has shifted how it enables interop with browser and JavaScript APIs. This shift prevents Dart code that uses dart:html or package:js from compiling to Wasm.

Instead, Dart now provides new, lightweight interop solutions built around static JS interop:

package:web, which replaces dart:html (and other web libraries)
dart:js_interop, which replaces package:js and dart:js

https://dart.dev/interop/js-interop

hololeo avatar Apr 21 '24 15:04 hololeo

errors encountered by @ndonkoHenri

https://github.com/ndonkoHenri/test-flet-github-actions/actions/runs/8772266592/job/24071006981#step:6:656


package:flet/src/controls/checkbox.dart => 
package:flet/src/controls/cupertino_checkbox.dart => 
package:flet/src/controls/list_tile.dart => package:flet/src/utils/text.dart => 
package:flet/src/utils/launch_url.dart => 
package:flet/src/utils/platform_utils_web.dart => dart:html
    ...

/home/runner/.pub-cache/hosted/pub.dev/package_info_plus-4.2.0/lib/src/package_i
nfo_plus_web.dart:2:8: Error: Dart library 'dart:html' is not available on this 
platform.
import 'dart:html';
       ^
/home/runner/.pub-cache/hosted/pub.dev/flet-0.22.0/lib/src/utils/platform_utils_
web.dart:2:8: Error: Dart library 'dart:html' is not available on this platform.
import 'dart:html' as html;

hololeo avatar Apr 21 '24 15:04 hololeo

Wow, that looks like a future!

Btw, it's possible to add --wasm option even today with https://flet.dev/docs/publish#extra-args-to-flutter-build-command (provided package_info_plus is fixed or mocked).

FeodorFitsner avatar Apr 21 '24 16:04 FeodorFitsner

Re package_info_plus - look at two last FEAT items, we need to upgrade to 6.0: https://github.com/fluttercommunity/plus_plugins/blob/main/packages/package_info_plus/package_info_plus/CHANGELOG.md#600

FeodorFitsner avatar Apr 21 '24 16:04 FeodorFitsner

Btw, it's possible to add --wasm option even today

Yeah, I tried that: https://github.com/ndonkoHenri/test-flet-github-actions/actions/runs/8772266592/job/24071006981#step:6:5 (Make sure to use either the beta or main channel, cause that's where that flag is available for now)

What's package_info_plus? Have we being using it?

I could perhaps be of help in the package migrations.

ndonkoHenri avatar Apr 21 '24 17:04 ndonkoHenri

Enabling WASM in Flet Project

This guide will walk you through the steps required to enable WebAssembly (WASM) in Flet .

Step 1: Create the Flutter Project for Web

Run the following command to create the Flutter project with web support:

flutter create . --platforms=web

Step 2: Modify flet_server_protocol_javascript_web.dart

Modify the file at:

packages/flet/lib/src/flet_server_protocol_javascript_web.dart

Replace the content with the following:

@JS()
library script.js;

import 'dart:js_interop';

import 'package:flutter/foundation.dart';
import 'flet_server_protocol.dart';

@JS('jsConnect')
external JSPromise<JSAny?> jsConnect(JSFunction onMessage);

@JS('jsSend')
external void jsSend(JSString data);

class FletJavaScriptServerProtocol implements FletServerProtocol {
  final String address;
  final FletServerProtocolOnMessageCallback onMessage;
  final FletServerProtocolOnDisconnectCallback onDisconnect;

  FletJavaScriptServerProtocol({
    required this.address,
    required this.onDisconnect,
    required this.onMessage,
  });

  @override
  connect() async {
    debugPrint("Connecting to JavaScript server $address...");
    await jsConnect(onMessage.toJS).toDart;
  }

  @override
  bool get isLocalConnection => true;

  @override
  int get defaultReconnectIntervalMs => 10;

  @override
  void send(String message) {
    jsSend(message.toJS);
  }

  @override
  void disconnect() {}
}

Step 3: Modify platform_utils_web.dart

Update the file at:

flet/lib/src/utils/platform_utils_web.dart

Replace the content with the following:

// ignore: avoid_web_libraries_in_flutter
import 'package:web/web.dart' as html;

import 'strings.dart';

bool isProgressiveWebApp() {
  return html.window.matchMedia('(display-mode: standalone)').matches ||
      html.window.matchMedia('(display-mode: fullscreen)').matches ||
      html.window.matchMedia('(display-mode: minimal-ui)').matches;
}

String getWebsocketEndpointPath(String uriPath) {
  var meta = html.document.head
      ?.querySelector("meta[name='flet-websocket-endpoint-path']");
  return trim(meta?.attributes.getNamedItem("content")?.value ?? "ws", "/");
}

String getFletRouteUrlStrategy() {
  var meta =
      html.document.head?.querySelector("meta[name='flet-route-url-strategy']");
  return meta?.attributes.getNamedItem("content")?.value ?? "";
}

bool isFletWebPyodideMode() {
  var meta = html.document.head?.querySelector("meta[name='flet-web-pyodide']");
  return meta?.attributes.getNamedItem("content")?.value?.toLowerCase() == "true";
}

void openPopupBrowserWindow(
    String url, String windowName, int width, int height) {
  int screenWidth = html.window.screen!.width;
  int screenHeight = html.window.screen!.height;
  final dualScreenLeft = html.window.screenLeft < 0 ? -screenWidth : 0;
  var toolbarHeight = html.window.outerHeight - html.window.innerHeight;
  var left = (screenWidth / 2) - (width / 2) + dualScreenLeft;
  var top = (screenHeight / 2) - (height / 2) - toolbarHeight;
  html.window.open(url, windowName,
      "top=$top,left=$left,width=$width,height=$height,scrollbars=yes");
}

Step 4: Update Sensor Plus Package Version

In the file located at:

packages/flet/pubspec.yaml

Update the sensors_plus dependency to:

sensors_plus: ^5.0.1

Step 5: Modify session_store_web.dart

Update the file at:

packages/flet/lib/src/utils/session_store_web.dart

Replace the content with the following:

import 'package:web/web.dart' as html;

Step 6: Update pubspec.yaml for Web Dependency

In the file located at:

packages/flet/pubspec.yaml

Add the following dependency:

dependencies:
  flutter:
    sdk: flutter

  web: ^0.5.0

Notes

  • WASM is not available for video and audio packages, as they depend on ffi, which is not supported for WebAssembly.

jaluscg avatar Aug 31 '24 22:08 jaluscg