2ヶ月以上の設計とコードをして、私はFlutterの動態化の方案の対比と最良の実現を整理しました


背景
エンドではAppの柔軟性を向上させ、変化するビジネスニーズを迅速に解決するために、開発者たちはPhoneGap、React Native、Weexなど多くのソリューションを模索したが、Flutterエコではまだ良いソリューションはない.将来の閑魚はFlutterに基づいてエンドツーエンドで開発され、リリースサイクルを突破すれば、リリースしないでビジネスニーズを完了し、パフォーマンス体験を互換化することができ、ビジネスニーズに迅速に応えることができます.そのため、Flutter生態の下での動的化を探る必要があります.
シナリオの選択
AndroidとIosのダイナミックなシナリオを参考にして,我々も多様なFlutterダイナミックなシナリオを考えた.
1.代替Flutterコンパイル製品のダウンロード
新しいFlutterコンパイル製品をダウンロードし、Appインストールディレクトリの下のコンパイル製品に置き換えて動的化を実現することはAndroid側では可能ですが、Ios側では不可能です.デュアルエンド一体のソリューションが必要なので、これは最善の選択ではありません.
2.React Nativeのようなフレームワーク
まずReact Nativeのアーキテクチャを見てみましょう
React Nativeはandroid(ios)のオリジナルコンポーネントに変換してレンダリングします.React Nativeの設計構想でXML DSLをFlutterの原子widgetコンポーネントに変換し、Flutterにレンダリングさせる.技術的には可能ですが、このコストは大きく、これは膨大な工事になります.投入産出比から見ると、あまり良い選択ではありません.
3.ページ動的コンポーネントフレーム
太さのWidgetコンポーネントからダイナミックにページを組み立て、Native端にはすでに多くの成熟したフレームワークがあり、例えば天猫のTangram、タオバオのDinamicXは、性能、ダイナミック性、開発サイクルでバランスを取っている.重要なのは、ほとんどのダイナミックなニーズを満たし、問題を解決することができます.
3つのシナリオの比較グラフは、次のとおりです.
実際のダイナミックニーズに基づいて、両端の一貫性、パフォーマンス、コスト、ダイナミック性を考慮して、折衷案を選択し、ページダイナミックコンポーネントの設計構想は良い選択です.
ページダイナミックコンポーネントフレーム
Flutterで太いコンポーネントを動的にアセンブリしてページを構築するには、前後のサービスとツールが必要です.ここでは、フロントエンドインタフェースのレンダリングエンジンの手順に重点を置きます.
構文ツリーの選択
Native側のTangram,DinamicXなどのフレームワークには共通点があり,XmlやHtmlをDSLとしている.しかし、FlutterはReact Style構文です.彼自身の文法はもうページをうまく表現できるようになった.カスタムXml構文、カスタム論理式は必要ありません.FlutterソースコードをDSLとして使用すると、開発、テストプロセスを大幅に軽減でき、追加のツールサポートは必要ありません.したがって、DSLとしてFlutterソースコードが選択され、動的化が実現される.
DSLの解析方法
FlutterソースコードはDSLとして、ソースコードの解析と分析を行う必要があります.Flutter analyzerは私たちにいくつかの考え方を与えてくれました.Flutter analyzerはコードスタイル検出ツールです.パッケージ:analyzerを使用してdartソースコードを解析し、ASTnodeを取得します.
Flutter analyzeソース構造を見て、dart sdkの中のpackage:analyzerを使用しています.
dart-sdk:  
     analysis_server: 
         analysis_server.dart
         handleRequest(Request request) 

     analyzer:
         parseCompilationUnit()
         parseDartFile 
         parseDirectives 

Flutter analyzeはソースコードを解析してASTnodeプロセスを得る.
プラグインまたはコマンドはanalysis serverに対して要求を開始し、要求には分析が必要なファイルpathと分析のタイプ、analysis_serverはpackage:analyzerを使用してcommilationUnit(ASTnode)を取得し、astNodeをcomputer分析し、分析結果リストを返します.
同様にpackage:analyzerを使用してソースファイルをcommilationUnit(ASTnode)に変換することもでき、ASTnodeは抽象構文ツリーであり、抽象構文ツリー(abstract syntax treeまたはASTと略称する)はソースコードの抽象構文構造のツリー表現形式である.
抽象構文ツリーを利用してdartソースコードをよく解析することができます.
解析レンダリングエンジン
次に、レンダリングモジュールについて重点的に説明します.
スキーマ図:
1.ソース解析プロセス
1.ASTツリーの構造
次のFlutterコンポーネントのソースコードのように、
import 'package:flutter/material.dart';

class FollowedTopicCard extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new Container(
      padding: const EdgeInsets.fromLTRB(12.0, 8.0, 12.0, 0.0),
      child: new InkWell(
        child: new Center(
          child: const Text('Plugin example app'),
        ),
        onTap: () {},
      ),
    );
  }
}

そのAST構造:
ASTの構造から見ると、彼は規則的だ.
2.ASTからwidgetノードへ
ASTnodeを手に入れたが、ASTnodeとwidget node treeはまったく異なる概念であり、ASTnodeをwidget node treeに再帰的に変換する必要がある.
Widgetノードに必要な要素
Nameでどのようなタイプのwidgetかを記録します
Widgetのargumentsはmapの中に入っています
Widgetのliteralsはリストに入っています
widgetのchildrenはlsitの中に入っています
Widgetのトリガイベント関数mapの中
Widget nodeプラスfromjson,tojsonメソッド
astNode treeを再帰するときに、I n s t a n c e CreationExpressionを認識してwidget nodeを作成できます.
2.コンポーネントデータレンダリング
フレームワークsdkにサポートされているコンポーネントを登録します.コンポーネントは次のとおりです.
a.原子構成部品:Flutter sdk中のFlutterのwidget
b.ローカルコンポーネント:大きな粒子のコンポーネント、カードwidgetコンポーネントにローカルに書く
c.ロジックコンポーネント:ロジックをローカルにパッケージしたwidgetコンポーネント
d.ダイナミックコンポーネント:ソースdslでダイナミックにレンダリングされたwidget
具体的なコードは以下の通りです.
 const Map allWidget = {
  'Container': wrapContainer,
     ………….
}
 static Widget wrapContainer(Map pars) {
  return new Container(
    padding: pars['padding'],
    color: pars['color'],
    child: pars['child'],
    decoration: pars['decoration'],
    width: pars['width'],
    height: pars['height'],
    alignment: pars['alignment']
  );
}

一般的に私たちがネットワークを通じて要求したデータはmapです.例えばソースコードにこのような'${data.urls[1]}'AST解析が書かれている場合、このようなstring、またはAST式が得られ、解析することでmapから対応する値が得られるに違いない.
3.論理とイベント
a.サポートロジック
Flutterコンセプト万物はwidgetであり、式、論理をカスタムwidgetにカプセル化することができます.ソースコードにif else,変数などが書かれていると,sdk解析の過程が重くなる.だから論理をwidgetにカプセル化します.これらの論理widgetは、コンポーネントとしてフレームワークコンポーネントとして扱われます.
b.サポートイベント
ページをジャンプしたり、フレームを弾いたり、サービスをしたりして、sdkに登録します.利用者はsdkのみのサービスを約束する.
4.ルールと検出ツール
a.検査規則
ソースコードのフォーマットにルールを設定する必要があります.たとえばif elseを直接書くことはサポートされていません.if else文の代わりに論理wigetコンポーネントを使用する必要があります.規則を制定しなければastノードからwidget nodeへの解析過程は複雑になる.理論的には解析できますが、sdkが十分強い限り解析できます.ルールを制定し,sdkの解析論理を軽減できる.
b.工具検査
ツールを使用して、ソースコードが制定されたルールに合致しているかどうかを検出し、すべてのソースコードが解析されることを保証します.
パフォーマンスと効果
フレームレートが50 fpsより大きく、体験的にweexと同じ機能のページよりもスムーズに見ることができ、Samsung galaxy s 8では、コンポーネントがダイナミックにレンダリングされているとは感じられない.
データ構造
サービス側が要求したデータは、次のようなフォーマットを約束することができます.
class DataModel {

  Map  data;

  String type;

}

各pageはコンポーネントで構成され、各コンポーネントのデータはDataModelでレンダリングされます.typeに基づいて対応するテンプレートを見つけ、テンプレート+dataでインタフェースをレンダリングします.
ダイナミックテンプレート管理モジュール
Widget Node TreeをコンポーネントJsonテンプレートに変換しました.バージョン管理、動的ダウンロード、アップグレード、ロールバック、更新などをサポートする管理プラットフォームが必要です.
フレームの境界
このフレームワークは,コンポーネントの組み立て,コンポーネントレイアウトの動的変更,ページレイアウトの動的変更により動的化を実現する.だから、運営の変化が速いトップページ、詳細、注文、私のなどのページに適しています.いくつかの複雑な論理はコンポーネントにカプセル化され、コンポーネントをフレームワークに組み込み、ローカルコンポーネントとして使用する必要があります.フレームワークは動的コンポーネントの組み立てに重点を置き,エンジンはソースコードの複雑な論理式の解析に弱体化している.
後続の拡張
1.UI自動化との組み合わせ
UIの自動化については、前述の記事で説明した.UIオートメーションツールはコンポーネントを生成し、コンポーネントをテンプレートに変更し、動的に配布し、運用ニーズを迅速に解決します.
2.国際化のサポート
Appは国によって異なる機能を持っています.エリアに応じて、私たちのページを動的に組み立てることができます.
3.千人千面
異なる人々によって、異なるインタフェースを動的にレンダリングします.
まとめ
ここでは、ダイナミックスキームのレンダリング部分について説明します.この案はすべて初探段階で、まだ多くの改善が必要で、後続は拡張と修正を続け、オープンソース基準に達した後、オープンソースを考慮します.ダイナミックシナリオはバックエンドのフロントエンドを一体化したシナリオで、ツールの組み合わせが必要で、後で全体のダイナミックシナリオを紹介する文章があります.閑魚技術の公共アカウントに注目してください.閑魚に参加して面白い技術を探してください.
参考資料:
Static Analysis:
https://www.dartlang.org/guides/language/analysis-optionshttps://www.dartlang.org/tools/analyzer
dart analyzer :
https://pub.dartlang.org/packages/analyzerhttps://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli#dartanalyzer
dartdevc:
https://webdev.dartlang.org/tools/dartdevc
著者:閑魚技術-石
原文を読む
本文は雲栖コミュニティのオリジナル内容で、許可を得ずに転載してはならない.