This is the 9th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Flutter Web development practices shared

Directory:

1. Develop and debug process

2. Plug-in adding process

3. Packaging process

4. Frequently Asked Questions

Development and debugging process

Support Web

Enabling Web Support

Use the following command to enable Web support:

flutter config --enable-web

Existing projects support web

Run the following command in the existing project directory:

flutter create .

The new project supports web

Since Web support is already enabled, create the Flutter project directly to support the Web

flutter create myapp

After enabling the project to support Web, Flutter can be developed in the same way as before. If there is a special treatment for Web, kIsWeb can be used in the project to determine

debugging

The process of debugging a FLUTTER Web project is the same as that of any FLUTTER project. There are two ways

IDE way

Select Chrome (Web) from the IDE device selection and click the Debug button

Command-line mode

Run the following command in the project directory on the terminal

flutter run -d chrome

Enable local service debugging

You can also start the Web service locally and access it from a browser for debugging

  1. flutter packages pub global activate webdev
  2. flutter packages pub global run webdev serve
  3. Open any browser and type ‘http://127.0.0.1:8080/’

Plug-in Adding Process

Add plug-in Project

If there is no plug-in project and you need to create a new plug-in project, run the following command:

flutter create --template=plugin --platforms=web /path/to/yourProject

After adding the Web plug-in dependency, you can see that a file with the same name for the plug-in with the web suffix is generated: xxx_web.dart

Our plug-in implementation for the Web platform needs to be implemented in xxx_web.dart

Add a plug-in file

If you already have a plug-in project, you just need to add the Web configuration to pubspec.yaml of the plug-in project

flutter:
  plugin:
    platforms:
      android:
        package: com.aa.bb.tt_flutter_business_plugin
        pluginClass: TTFlutterBusinessPlugin
      ios:
        pluginClass: TTFlutterBusinessPlugin
      web:
        pluginClass: TTFlutterBusinessPluginWeb
        fileName: plugin_web/tt_flutter_business_plugin_web.dart
Copy the code

First import import ‘dart: HTML ‘as HTML; , and then register the plug-in and implement it.

class TTFlutterBusinessPluginWeb {
  static void registerWith(Registrar registrar) {
    final MethodChannel channel = MethodChannel(
      'com.aa.bb/tt_flutter_business_plugin'.const StandardMethodCodec(),
      registrar,
    );

    final pluginInstance = TTFlutterBusinessPluginWeb();
    channel.setMethodCallHandler(pluginInstance.handleMethodCall);
  }
  
  Future<dynamic> handler(MethodCall call) {
    if (call.method == 'getPlatformVersion') {
      return Future.value(html.window.navigator.appVersion);
    }
    return null; }}Copy the code

The direct call HTML. Window. The navigator. AppVersion,

You can also call js.context.callmethod (); The call.

callMethod

 callMethod(Object method, [List? args]);
Copy the code

Method, which supports String or num, is used to determine which JS method to call, and args is the array of arguments passed to the method.

Synchronous method call

If the JS method is synchronous, the return value of callMethod is the return value of the JS method.

Asynchronous method call

If the JS method is asynchronous, you can pass a block in the args of the callMethod to return the asynchronous result from the block in the JS

Function responseCall = (dynamic dataStr){
      print('= web plugin = shareCollaboration Web Call back:$dataStr');
      Map responseMap = json.decode(dataStr);
      bool success = responseMap['success'] as bool;
      Map content = responseMap['content'] as Map;
      if (success) {
        callBack('$success');
      } else {
        callBack(content['errorMsg']); }}; js.context.callMethod("callWindowFunction",[json.encode(params),responseCall]);
Copy the code

Global registration method calls

In the actual development process, some plug-in implementations need to call the global registration method, if directly using js.context.callMethod cannot be called.

You need to make a bridge in JS

1. Create the JS folder in the web folder of the project

2. Create a JS file in the js folder

3. Implement a method in the js file to call the global registration method

function callWindowFunction(param, callback)
{
      window.TTCefWebFunction(param,callback);
}
Copy the code

The global registration method I’ll call here is window.ttCefWebFunction

Packaging process

Normal Web packaging only needs to execute flutter build Web.

But this means that the renderer uses the Audo parameter, which is HTML on the mobile browser and convaskit on the desktop

Renderer selection

Flutter web running and packaging involves a choice of renderers, including HTML and Canvaskit. The differences are as follows:

Render using HTML, CSS, Canvas and SVG elements, the application size is relatively small.

Compile Skia into WebAssembly format using CanvasKit rendering and use WebGL rendering. Application consistency on mobile and desktop provides better performance and reduces the risk of inconsistent rendering across browsers. But the size of the application will increase by about 2MB.

By default, HTML is used on the mobile browser and convasKit is used on the desktop

You can do that manually if you want,

The cli is as follows:

Add –web-renderer HTML after command

// Use HTML to render a flutter run -d chrome --web-renderer CanvasKitCopy the code

In the project, the configuration is:

1. Use the auto parameter to build or do not use the Settings parameter

2. Insert the

  <script type="text/javascript">
    let useHtml = // ...
    if(useHtml) {
      window.flutterWebRenderer = "html";
    } else {
      window.flutterWebRenderer = "canvaskit";
    }
  </script>
  <script src="main.dart.js" type="application/javascript"></script>
Copy the code

PS: There are two points to note when using Canvaskit

1. Due to the wall in China, the source of Canvaskit needs to be replaced

Can pass – the dart – define = FLUTTER_WEB_CANVASKIT_URL = “https://unpkg.zhimg.com/[email protected]/bin/” to change the source address

2. At present, when using CanvasKit, the text on the page will be displayed as [X] when it first appears, and will be automatically refreshed later. Places with ellipsis in the text will also be displayed as [X] and cannot be automatically refreshed.

The current record management platform packaging command is

flutter build web –web-renderer html — release

Problems encountered

Intermodulation cross-domain problem

OS: macOS Catalina

  1. Add to ~/.bash_profile (~/.zshrc if you are using ZSH) :

    export CHROME_EXECUTABLE="/Applications/Google Chrome.app/Contents/MacOS/google-chrome-unsafe"
    Copy the code
  2. Unsafe: Create a google-Chrome-unsafe shell script and place it in the same directory as the original Chrome executable:

    google-chrome-unsafe

    #! /bin/bash“/Applications/Google“\ Chrome.app“/Contents/MacOS/Google“\ Chrome –disable-web-security –user-data-“dir“=“”your-tmp-dir” $*

    Ps:

    • To highlight the file path is: / Applications/Google Chrome app/Contents/MacOS/Google Chrome — the unsafe

    • Don’t forget the executable permissions: chmod +x

  3. After the environment variables are in effect, ide Debug starts Chrome with the above commands by default, that is, safe mode (allowing cross-domain) is turned off

Note: remember to restart the IDE for environment variables to take effect!

Unsafe mode occasionally fails

Need to be turned on again

Plug-ins cannot invoke global registration methods

Add a JS bridge

Display [X] when text first appears

Use an HTML renderer for now

After deployment, an error message is displayed indicating that main.dart.js cannot be found

The reason is that the path is not correct because it was deployed to xx.sit.tt.com/static-meet…

The runtime directly find is xx.sit.tt.com/main.dart.j…

Fixes:

Change to in index.html