Unable to build Flutter Web and Flutter Mobile apps seperately
Asked Answered
G

3

7

I am building a flutter project and am having an issue integrating the web and mobile code in a single project. I want to use Moor and Moor_FFI in my mobile code, but even though the entry point to my web (main.dart) and mobile code (main.dev.dart) are configured to be different to debug, it still tries to compile the mobile code for the web. This causes an issue, because FFI and other Dart plugins are not supported on Flutter Web as of now, resulting in a massive error message.

Error compiling dartdevc module:ffi|lib/ffi.ddc.js

packages/ffi/src/utf8.dart:6:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
       ^
packages/ffi/src/utf16.dart:6:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
       ^
packages/ffi/src/allocation.dart:5:8: Error: Not found: 'dart:ffi'
import 'dart:ffi';
       ^
packages/ffi/src/utf8.dart:23:20: Error: Type 'Struct' not found.
class Utf8 extends Struct {
                   ^^^^^^
packages/ffi/src/utf8.dart:26:21: Error: Type 'Pointer' not found.
  static int strlen(Pointer<Utf8> string) {
                    ^^^^^^^
packages/ffi/src/utf8.dart:26:21: Error: Expected 0 type arguments.
  static int strlen(Pointer<Utf8> string) {
                    ^
packages/ffi/src/utf8.dart:41:26: Error: Type 'Pointer' not found.
  static String fromUtf8(Pointer<Utf8> string) {
                         ^^^^^^^
packages/ffi/src/utf8.dart:41:26: Error: Expected 0 type arguments.
  static String fromUtf8(Pointer<Utf8> string) {
                         ^
packages/ffi/src/utf8.dart:54:10: Error: Type 'Pointer' not found.
  static Pointer<Utf8> toUtf8(String string) {
         ^^^^^^^
packages/ffi/src/utf8.dart:54:10: Error: Expected 0 type arguments.
  static Pointer<Utf8> toUtf8(String string) {
         ^
packages/ffi/src/utf16.dart:16:21: Error: Type 'Struct' not found.
class Utf16 extends Struct {
                    ^^^^^^
packages/ffi/src/utf16.dart:24:10: Error: Type 'Pointer' not found.
  static Pointer<Utf16> toUtf16(String s) {
         ^^^^^^^
packages/ffi/src/utf16.dart:24:10: Error: Expected 0 type arguments.
  static Pointer<Utf16> toUtf16(String s) {
         ^
packages/ffi/src/allocation.dart:9:7: Error: Type 'DynamicLibrary' not found.
final DynamicLibrary stdlib = Platform.isWindows
      ^^^^^^^^^^^^^^
packages/ffi/src/allocation.dart:13:29: Error: Type 'Pointer' not found.
typedef PosixMallocNative = Pointer Function(IntPtr);
                            ^^^^^^^
packages/ffi/src/allocation.dart:13:46: Error: Type 'IntPtr' not found.
typedef PosixMallocNative = Pointer Function(IntPtr);
                                             ^^^^^^
packages/ffi/src/allocation.dart:14:23: Error: Type 'Pointer' not found.
typedef PosixMalloc = Pointer Function(int);
                      ^^^^^^^
packages/ffi/src/allocation.dart:18:27: Error: Type 'Void' not found.
typedef PosixFreeNative = Void Function(Pointer);
                          ^^^^
packages/ffi/src/allocation.dart:18:41: Error: Type 'Pointer' not found.
typedef PosixFreeNative = Void Function(Pointer);
                                        ^^^^^^^
packages/ffi/src/allocation.dart:19:35: Error: Type 'Pointer' not found.
typedef PosixFree = void Function(Pointer);
                                  ^^^^^^^
packages/ffi/src/allocation.dart:23:31: Error: Type 'Pointer' not found.
typedef WinGetProcessHeapFn = Pointer Function();
                              ^^^^^^^
packages/ffi/src/allocation.dart:26:7: Error: Type 'Pointer' not found.
final Pointer processHeap = winGetProcessHeap();
      ^^^^^^^

And so on.....

Is there any way to configure the compiler to only build the files related to Web or Mobile for the respective runs?

For Reference: Github repo with the error recreated: https://github.com/JoshMarkF/MoorFFIIntegrationDemo

Genome answered 25/2, 2020 at 3:22 Comment(0)
C
2

Edit
flutter build web and flutter run -d chrome all works fine.
because web ui code (webui.dart) and mobile ui code (mobileui.dart) are in different dart file,
so these two files can have different import

You can copy paste run 3 three files below, main.dart, webui.dart and mobileui.dart
You can use conditional import to separate different implement for web and mobile
so web and mobile can have totally different logic

code snippet call with prefix multiPlatform

import 'mobileui.dart' if (dart.library.html) 'webui.dart' as multiPlatform;
...
home:  multiPlatform.TestPlugin(),

working demo when use Android Studio run with Android Emulator and Chrome

enter image description here

main.dart

import 'package:flutter/material.dart';
import 'mobileui.dart' if (dart.library.html) 'webui.dart' as multiPlatform;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget { 
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(        
        primarySwatch: Colors.blue,
      ),
      home:  multiPlatform.TestPlugin(),
    );
  }
}

mobileui.dart

import 'package:flutter/material.dart';

class TestPlugin extends StatefulWidget {
  @override
  _TestPluginState createState() => _TestPluginState();
}

class _TestPluginState extends State<TestPlugin> {
  @override
  Widget build(BuildContext context) {
    return Text("Mobile");
  }
}

webui.dart

import 'package:flutter/material.dart';
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:ui' as ui;


class TestPlugin extends StatefulWidget {
  TestPlugin();

  _TestPluginState createState() => _TestPluginState();
}

class _TestPluginState extends State<TestPlugin> {
  String createdViewId = 'map_element';

  @override
  void initState() {
    // ignore: undefined_prefixed_name
    ui.platformViewRegistry.registerViewFactory(
        createdViewId,
            (int viewId) => html.IFrameElement()
          ..width = MediaQuery.of(context).size.width.toString() //'800'
          ..height = MediaQuery.of(context).size.height.toString() //'400'
          ..srcdoc = """<!DOCTYPE html><html>
          <head><title>Page Title</title></head><body><h1>This is a Heading</h1><p>This is a paragraph.</p></body></html>"""
        /*..src = "http://f12apidev32.umc.com/Tableau/jsapi_practice.aspx"*/
          ..style.border = 'none');

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Container(
        padding: EdgeInsets.symmetric(horizontal: 10),
        decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(color: Colors.grey[300], width: 1),
            borderRadius: BorderRadius.all(Radius.circular(5))),
        width: 200,
        height: 200,
        child: Directionality(
            textDirection: TextDirection.ltr,
            child: HtmlElementView(
              viewType: createdViewId,
            )));
  }
}
Caty answered 25/2, 2020 at 3:41 Comment(6)
In my code, the error is caused by the moor_ffi package in the mobile code, that is not needed for the web, only the mobile and needs dart:ffi. Is there any way to control these imports as per mobile or web?Genome
because webui.dart and mobileui.dart are two different dart file. you won't encounter compile error. you can have totally different implement and of course different import. all you need is separate to different dart file.Caty
you can see my example webui.dart and mobileui.dart have totally different importCaty
The issue is that flutter build web and flutter run -d chrome don't use the same compiler as described here. In short, flutter build web uses dart2js which will look at the entry file and only compile the web code. However, flutter run -d chrome uses dartdevc which looks at all the files in the lib folder. Because of that, it's trying to compile mobile files and moor_ffi, hence the error.Demasculinize
I have tested my demo. flutter build web works and when I put it in IIS also works. You can copy paste and test my case. use conditional import works fine.Caty
use flutter run -d chrome also works fine. webui code and mobileui code are in different dart file.Caty
W
0

web_ffi: ^0.7.2 in dependencies in pubspec.yaml and import this file. import 'package:web_ffi/web_ffi.dart';

it will separately open web and mobile device..

Willamina answered 31/1, 2022 at 4:11 Comment(0)
B
0

You also need to repair .pub-cache for any of dependencies, plugin related issue. Run following command for cleaning your fluter and repairing your pub-cache

1. flutter clean

2. flutter pub cache repair 

These two commands will solve most of plugin, dependencies related issue.

Beamon answered 14/5, 2023 at 2:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.