Как Flutter отображает код в интерфейсе

предисловие

Как красиво отобразить код в проекте или свой демо-код на интерфейсе? В этой статье сравниваются и исследуются решения, которые просты в использовании, просты в обслуживании и универсальны.

Чтобы сэкономить время каждого, напишите соответствующий доступ и использование окончательного решения впереди.

код предварительного просмотра

быстрый старт

dependencies:
  code_preview: ^0.1.5
  • Использование: CodePreview, укажите имя класса, которое необходимо просмотреть, и может автоматически сопоставляться с соответствующим файлом кода класса.
    • Я изначально хотел упростить метод записи в входящий объект, но по некоторым причинам у меня не было другого выбора, кроме как сдаться и изменить его наclassName
    • Подробную информацию см. в Flutter Web中的问题описании следующих модулей.
import 'package:code_preview/code_preview.dart';
import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(className: 'Test');
  }
}

изображение-20230429215042820

файл кода конфигурации

Поскольку принцип заключается в обходе файлов ресурсов, файлы кода или их пути к папкам, которые необходимо отобразить, должны быть определены в ресурсах.Этот шаг обеспечивает автоматическое подключаемое решение для всех.

Настоятельно рекомендуется, чтобы код, который необходимо отображать в интерфейсе, управлялся в единой папке.

  • Код для отображения интерфейса должен быть определен в активах в pugspec.yaml.

изображение-20230422224011359

Если папка предварительного просмотра кода сложна в классификации, трудно каждый раз определять путь

Предоставьте плагин: Flutter Code Helper

  • Установка: Поиск в плагинахFlutter Code Helper

изображение-20230422225244651

  • Определите путь к папке, которая должна быть автоматически сгенерирована в pugspec.yaml, и папка будет автоматически сгенерирована под активами рекурсивно для вас.
    • Его не нужно генерировать автоматически, можно: не писать эту конфигурацию, либо настроить пустой массив (auto_folder:[])
code_helper:
  auto_folder: [ "assets/", "lib/widgets/" ]

09.04.2023 22-33-42

Объяснение. Приведенный выше подключаемый модуль основан на проекте подключаемого модуля FlutterAssetsGenerator компании RayC .

  • Посмотрев на код плагина RayC и связанные с ним функции, есть определенное несоответствие с реализацией вышеперечисленных функций, которые я ожидал, и изменения многое изменят.
  • Хотите попробовать различные новые конфигурации проекта плагина, просто тяните до последней
  • Если вы думаете о каких-либо функциях, которые вам понадобятся позже, вы можете добавить их в любое время.

Поэтому я не упомянул pr его плагину, поэтому открыл новый проект плагина отдельно

расширенное использование

тема

Предоставляет две темы стиля кода

  • дневной режим
CodePreview.config = CodePreviewConfig(codeTheme: CodeTheme.light);

изображение-20230429215716043

  • ночной режим
CodePreview.config = CodePreviewConfig(codeTheme: CodeTheme.dark);

изображение-20230429215545723

Разбор аннотаций

  • Вы можете использовать следующий формат для добавления комментариев к классу
    • Должен быть добавлен перед ключом @, например ( @title , @xxx)
    • Между ключом и значением необходимо использовать 分号сегментацию, например ( @xxx : xxx)
    • Если значение необходимо изменить, оно должно быть добавлено перед копией новой строки.中划线
/// @title:
///  - test title one
///  - test title two
/// @content: test content
/// @description: test description
class OneWidget extends StatelessWidget {
  const OneWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}
  • Затем вы можете customBuilderполучить параметр param из обратного вызова, а параметр имеет параметр parseParam
    • Получите данные вышеуказанного комментария: param.parseParam['title'] или param.parseParam['***']
    • Тип полученного значения — List<String>, который совместим с типом многострочного значения.
  • customBuilderиспользование
    • codeWidgetВстроенный макет предварительного просмотра кода, если вы хотите определить свой собственный макет кода предварительного просмотра, вам не нужно его использовать.codeWidget
    • codeWidgetВообще говоря, вы можете настроить макет, соответствующий требованиям, на основе данных, полученных из аннотации, в сочетании с вложением
    • paramВ нем много полезного контента, можете проверить сами
import 'package:code_preview/code_preview.dart';
import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return CodePreview(
      className: 'OneWidget',
      customBuilder: (Widget codeWidget, CustomParam? param) {
        debugPrint(param?.parseParam['title'].toString());
        debugPrint(param?.parseParam['content'].toString());
        debugPrint(param?.parseParam['description'].toString());
        return codeWidget;
      },
    );
  }
}
  • Текущий макет внутреннего предварительного просмотра автоматически удалит аннотации в классе. Если вы хотите сохранить аннотации, вы можете сопоставить их самостоятельно.
 CodePreview.config = CodePreviewConfig(removeParseComment: false);

Несколько схем предварительного просмотра кода

Схема FlutterUnit

Проект FlutterUnit также поставляется с решением для предварительного просмотра кода, которое является специальным решением.

  • Приблизительно взглянув на него, все данные FlutterUnit основаны на flutter.dbтекстовой информации соответствующей демонстрации в этом файле.
  • Все демо также существуют отдельно widgetsв проекте под названием
  • Так что наверное можно догадаться
    • Должен быть вспомогательный инструмент db, который будет сканировать widgetsдемо-код в проекте.
    • Отсканируйте их текстовую информацию, затем проанализируйте приведенные выше комментарии и другую соответствующую информацию, сохраните их в базе данных по категориям и, наконец, сгенерируйте файл базы данных.

изображение-20230429172832212

  • Таблица сопоставления, хост может получить экземпляр демонстрационного эффекта отсюда через имя класса компонента в db

изображение-20230429175714400

Подведем итог

Глядя на весь процесс, рабочая нагрузка для его реализации все еще немного велика.

  • Написание вспомогательных инструментов БД
  • Правила разбора текстовых аннотаций
  • Как удобно поддерживать файл базы данных (поддерживает ли его вспомогательный инструмент и автоматически перезаписывать файл базы данных хоста после создания)
  • Чтение и соответствующая адаптация файлов db на разных платформах

преимущество

  • Поскольку инструмент сканирования не зависит от библиотек, связанных с Flutter, решение для предварительного просмотра можно быстро портировать на другие языки программирования (compose, SwiftUI и т. д.).
  • Широкие возможности настройки, поскольку это полностью независимый сторонний инструмент сканирования, который можно настроить по своему усмотрению.

недостаток

  • Наиболее очевидным недостатком должно быть то, что после небольшого изменения демо-кода требуется сторонний инструмент для повторной генерации файла db (если сторонний инструмент реализует инструмент cli, вы можете интегрировать команду генерации сканирования с push и другими командами , что должно быть лучше, чтобы избежать этой проблемы. вопрос)

схема build_runner

build_runner — это мощный инструмент автоматической генерации кода.Согласно синтаксическому дереву ast + пользовательской аннотационной информации, он может генерировать много мощной вспомогательной информации о коде, такой как json_serializableожидание библиотеки

Таким образом, вы также можете использовать эту пользовательскую аннотацию класса, чтобы получить информацию о коде соответствующего всего класса, преобразовать полученное xx.g.dartсодержимое кода в строку в соответствующем прикрепленном файле, а затем напрямую отобразить xx.g.dartинформацию о строке кода файла. Просто перейдите к интерфейс

преимущество

  • Он может генерировать команды, полностью автоматически генерировать код и даже автоматически настраивать таблицу сопоставления всей демонстрации предварительного просмотра.
  • Несколько параметров могут быть настроены с помощью аннотаций стандартным образом.

недостаток

  • Поскольку build_runnerвсе синтаксическое дерево ast необходимо анализировать, как только проект станет очень большим, время анализа и генерации будет очень и очень долгим!
  • Поскольку многие из этих библиотек теперь зависимы build_runner, выполнение команды автоматической генерации приведет к изменению огромного количества xx.g.dartфайлов, что значительно увеличит нагрузку на cr.

схема файлов ресурсов

Это должно быть наиболее распространенным решением

  • Определите наш pubspec.yamlпуть к файлу кода вassets
flutter:
  assets:
    - lib/widgets/show/
  • Затем используйте loadString, чтобы получить содержимое файла.
final code = await rootBundle.loadString('lib/widgets/show/custome_dialog_animation.dart');

изображение-20230429205530817

преимущество

  • Очень низкий уровень вмешательства, не build_runnnerповлияет на другие модули, такие как решение
  • Простота обслуживания, если код предварительного просмотра демо-версии изменен, при упаковке файл ресурсов также будет генерировать соответствующий измененный файл кода.

недостаток

  • Это проблематично в использовании.При его использовании вам нужно указать определенный путь к файлу, чтобы найти нужный файл ресурсов кода.
  • Необходимо повторно указать путь к файлу pubspec.yamlвassets

Оптимизация схемы файлов ресурсов

Вышеуказанные три схемы имеют свои преимущества и недостатки.当前的诉求

  • В настоящее время я хочу написать простое решение для предварительного просмотра кода общего назначения только во Flutter.

  • Простой в использовании и эффективный

  • Простое обслуживание, небольшие затраты при разработке несколькими людьми

Решение FlutterUnit : его реализация требует больших затрат, а обслуживание одного файла базы данных несколькими разработчиками может быть немного проблематичным, например: при обновлении кода файл базы данных забывают обновить.

Схема build_runner : время генерации является проблемой, а xx.g.dartтакже проблематично воздействовать на другие типы файлов

Схема файла ресурсов : в целом она соответствует ожиданиям, но при ее использовании вам необходимо pubspec.yamlповторно указать путь и указать путь к файлу, что является двумя большими проблемами.

В сочетании со стоимостью внедрения и привлекательностью выберите 资源文件方案и оптимизируйте его болевые точки ниже.

использовать оптимизацию

Среди скомпилированных продуктов Flutter есть очень полезный файл: AssetManifest.json.

В файле AssetManifest.json есть пути всех файлов ресурсов, а дальше все просто, нам нужно только прочитать содержимое файла

final manifestContent = await rootBundle.loadString('AssetManifest.json');

После получения всех путей в сочетании с переданным именем класса прочитайте содержимое файла всех путей, а затем выполните обычное сопоставление с переданным именем класса.

слегка оптимизирован

  • Преобразуйте входящее имя класса в имя подчеркивания и сопоставьте его со всеми путями. Если оно может быть сопоставлено, выполните сопоставление содержимого. После успешного совпадения верните содержимое кода файла
  • Если указанное выше сопоставление не удается, будет выполнено полное сопоставление.

до оптимизации

import 'package:code_preview/code_preview.dart';
import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(path: 'lib/widgets/show/custome_dialog_animation.dart');
  }
}

Оптимизировано

import 'package:code_preview/code_preview.dart';
import 'package:flutter/material.dart';

class Test extends StatelessWidget {
  const Test({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return const CodePreview(className: 'CustomDialogAnimation');
  }
}
  • Вообще говоря, я единообразно настраиваю превью-демо и className, что лучше для сравнения

изображение-20230429170007279

Оптимизация определения пути

Первоначально я хотел pubspec.yamlнаписать assetsподстановочные знаки, чтобы напрямую определить полный путь, но, к сожалению, он не поддерживает такой способ записи.

flutter:
  assets:
    - lib/widgets/**/*.dart

ГГ, я могу думать только о других способах.Я не могу думать о многих способах.Я могу только начать извне и использовать плагин идеи, чтобы реализовать путь автоматической генерации сканирования.

  • Установка: Поиск в плагинахFlutter Code Helper

изображение-20230422225244651

  • В pugspec.yaml определите каталог, который должен автоматически сгенерировать папку.Папка может быть вложена по желанию, и она будет автоматически рекурсивно сгенерирована под активами для вас.
    • Его не нужно генерировать автоматически, можно: не писать эту конфигурацию, либо настроить пустой массив (auto_folder:[])
code_helper:
  auto_folder: [ "assets/", "lib/widgets/" ]

09.04.2023 22-33-42

Проблемы во Flutter Web

Magic runtimeType

В режиме выпуска флаттера паутины

  • dart2js будет сжимать JS, что приведет к изменению имени типа
  • Например: runtimeType класса в dart TestWidgetFunctionможет стать minified:Ah, а не TestWidgetFunction!

Зачем нужна компрессия? Сжатие имени позволяет компилятору уменьшить размер JavaScript в 3 раза +; компромисс между точной эквивалентной семантикой и производительностью/размером кода, Dart, очевидно, выбирает последнее

Эта ситуация будет происходить только в режиме выпуска Flutter Web, на других платформах и в режиме Debug | Profile этой проблемы не будет, поэтому ожидаемые Xxx.runtimeType.toStringданные могут быть не получены. . .

Для конкретного обсуждения см.

Решения

  • minified:AhИзмените тип сжатия наTest
  • TestИспользуйте тот же алгоритм, чтобы сжать полученную строку вminified:Ah

Если вы знаете, как этого добиться, обязательно подскажите

Давайте посмотрим, можно ли решить эту проблему с точки зрения регулировки уровня сжатия.

инструкции по сжатию dart2js

Примечание. По умолчанию для веб-сайта flutter build используется уровень оптимизации O4.

  • O0: Отключить многие оптимизации.
  • O1: Включить оптимизацию по умолчанию (только уровень команды dart2js по умолчанию)
  • O2: на основе оптимизации O1 другие оптимизации, учитывающие семантику языка и безопасные для всех программ (например, минимизация).
    • Примечание. При использовании -O2 при компиляции с помощью компилятора JavaScript для разработки строковое представление типа больше не такое, как в Dart VM.
  • O3: На основе оптимизации O2 и исключения неявной проверки типов.
    • Примечание. Отсутствие проверки типов может привести к сбою приложения с ошибками типов.
  • O4: на основе оптимизации O3 включить более агрессивную оптимизацию
    • Примечание. Оптимизация O4 чувствительна к изменениям во входных данных, проверяйте пограничные случаи в пользовательском вводе, прежде чем полагаться на O4.

Ниже представлен новый проект флаттера, без каких-либо изменений, объем js-продукта разной степени сжатия.

# main.dart.js: 7.379MB
flutter build web --dart2js-optimization O0 
# main.dart.js: 5.073MB
flutter build web --dart2js-optimization O1
# main.dart.js: 1.776MB
flutter build web --dart2js-optimization O2
# main.dart.js: 1.716MB
flutter build web --dart2js-optimization O3
# main.dart.js: 1.687MB
flutter build web --dart2js-optimization O4

Подведем итог

  • предполагаемое использование
    • Почему вы хотите использовать объекты? Потому что при изменении имени объекта легко заметить, что его нужно изменить в соответствии с местом, где оно используется.
    • Вы можете использовать входящий экземпляр объекта, внутренне использовать runtimeType, чтобы получить имя типа, а затем выполнить соответствующее сопоставление.
CodePreview(code: Test());

но

Таким образом, использование flutter build web --dart2js-optimization O1скомпилированного продукта веб-релиза флаттера может привести семантику runtimeType в соответствие со строками в Dart VM.

Однако при таком уровне сжатия объем js слишком преувеличен, что определенно окажет большое влияние на скорость загрузки.Вполне возможно, что увеличение объема в сложных проектах должно быть еще более возмутительным.

Для более простого использования от идеи использования команд низкоуровневого сжатия для упаковки нужно отказаться

  • использование должно идти на компромисс
CodePreview(className: "Test");

Это процесс мышления, который меня очень смущает.

наконец

Это здесь, я чувствую, что это должно помочь всем

Вообще говоря, у большинства команд будет собственная внутренняя библиотека компонентов. Благодаря мощным кроссплатформенным функциям Flutter ее можно легко опубликовать на веб-платформе, и вы можете легко испытать эффекты различных компонентов. С помощью решения для предварительного просмотра кода вы можно быстрее приступить к работе с различными компонентами~

Что ж, до новых встреч, красавчики!

{{о.имя}}
{{м.имя}}

Supongo que te gusta

Origin my.oschina.net/xdd666/blog/8704604
Recomendado
Clasificación