Unable to build Flutter Web and Flutter Mobile apps seperately

5,108

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,
            )));
  }
}
Share:
5,108
Joshua Mark Furtado
Author by

Joshua Mark Furtado

Updated on December 18, 2022

Comments

  • Joshua Mark Furtado
    Joshua Mark Furtado over 1 year

    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

  • Joshua Mark Furtado
    Joshua Mark Furtado about 4 years
    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?
  • chunhunghan
    chunhunghan about 4 years
    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.
  • chunhunghan
    chunhunghan about 4 years
    you can see my example webui.dart and mobileui.dart have totally different import
  • Gpack
    Gpack about 4 years
    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.
  • chunhunghan
    chunhunghan about 4 years
    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.
  • chunhunghan
    chunhunghan about 4 years
    use flutter run -d chrome also works fine. webui code and mobileui code are in different dart file.