Сучасна диджитал-освіта для дітей — безоплатне заняття в GoITeens ×
Mazda CX 5
×

Повышаем продуктивность Flutter-разработчика. 5 методов

Усі статті, обговорення, новини про Mobile — в одному місці. Підписуйтеся на телеграм-канал!

Всем привет! Меня зовут Юра и я Flutter-разработчик. Изучая эту технологию, работая с ней, я начал все чаще задаваться вопросом: как я могу успевать больше за меньший промежуток времени? Собственно, формула простая: мне нужно меньше тратить времени на рутинные процессы и уделять больше времени написанию нового кода. За два года, я собрал своеобразный список методов, которые помогли лично мне привести эту формулу в действие и повысить эффективность работы. Надеюсь, они будут полезны и вам.

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

1. Используйте плагины

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

Вот мой топ таковых для IntelliJ IDEA:

  • Dart Data Class
  • Key Promoter X
  • String Manipulation
  • Git Tool Box

2. Используйте хоткеи

Один из данных плагинов — это Key Promoter X, данный плагин говорит после каждого действия, сделанного руками, какой был хоткей для него. Хоткей — это сочетание клавиш для быстрого выполнения действий. Данный плагин поможет вам больше использовать хоткеи, что в перспективе очень сильно может сказаться на вашей производительности. Привыкайте использовать все команды с помощью хоткеев!

3. Используйте генерацию кода

Не отходя далеко, продолжим настройку IDE. IDE — это программа для написания кода. Практически в каждой IDE есть такая функция как «Live Templates». Она позволяет сохранить часто используемые участки кода и использовать их, написав указанную команду прямо в редакторе кода. На самом деле, хорошо настроенные «Live Templates» позволяют сэкономить очень много времени и, наверное, являются одним из самых эффективных методов писать код быстрее.

4. Билды и нюансы работы с ними

Далее поговорим про билды. Многие команды необоснованно собирают постоянно только «release» билды для тестирования, но «debug» билд в среднем собирается раза в 3-4 быстрее «release» билда, и об этом не стоит забывать. Оптимизируйте и выберите в каких ситуациях какого типа билды вам необходимы и экономьте время на этом.

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

CI (Continuous Integration) — в дословном переводе «непрерывная интеграция». Имеется в виду интеграция отдельных кусочков кода приложения между собой.

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

В своей команде мы решили это таким методом: при создании комита разработчик указывает также типы билдов, которые ему нужны и CI проверяет текст коммита и создает билд с необходимыми параметрами.

Пример: git commit -m «Commit text -d -r -i»

Команда -d создает дебаг билд, -r — релиз билд, -i — IOS билд.

Наша команда для билдов использует Jenkins CI, но вы можете выбрать любую другую и использовать ее.

5. Перейдем к самому интересному: как проверить код и потратить на это как можно меньше времени?

Самым действенным и простым методом будет создать и настроить линтер файл и проверять код, используя Dart Analyzer. Это может сильно сократить время при проверке пул реквестов а также его можно переносить из проекта в проект.

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

👍ПодобаєтьсяСподобалось0
До обраногоВ обраному1
LinkedIn
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Дозволені теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Юрий, вопрос не по теме. Насколько легко с помощью Flutter, если доводилось, делаются виджеты, — работа приложения на заблокированном экране. Я видел, что делают простейший функционал, например, аудио-плеера: pause/play & <> . Но можно ли сделать что-то кастомное?

На сколько мне известно, на данный момент флаттер на прямую не умеет работать с ними, есть только варианты через использование нативных языков. (На сколько помню Google обещали добавить эту фичу до середины 21 года.)

Есть повод для оптимизма )) Спасибо.

Вот расширения для vscode до кучи
medium.com/...​-development-fdd569c6abd4

В своей команде мы решили это таким методом: при создании комита разработчик указывает также типы билдов, которые ему нужны и CI проверяет текст коммита и создает билд с необходимыми параметрами.

я сломался, я не понимаю этого, ну от слова совсем..

При создании коммита, в тексте коммита указываются дополнительные параметры. (-i, -d, -r)
В Jenkins pipeline идет проверка на их наличие и если они есть выполняются определенные шаги.

ANDROID_DEBUG_BUILD_TOKEN = " -d";
ANDROID_RELEASE_BUILD_TOKEN = " -r";
IOS_BUILD_TOKEN = " -i";

IS_ANDROID_DEBUG_BUILD = stringContains(env.GIT_COMMIT_MSG, ANDROID_DEBUG_BUILD_TOKEN)

IS_ANDROID_RELEASE_BUILD = stringContains(env.GIT_COMMIT_MSG, ANDROID_RELEASE_BUILD_TOKEN)

IS_IOS_BUILD = stringContains(env.GIT_COMMIT_MSG, IOS_BUILD_TOKEN)

if (IS_IOS_BUILD) {
// do something
}

Вопрос не в реализации, спасибо конечно, непонятна целесообразность вашего флоу оно безумно странное

Не могли бы вы указать конкретнее в чем странность данного флоу? Наша логика заключается в том, что далеко не каждый комит требует билд и мы его собираем по необходимости. Мы для трэкинга задач используем Jira + BitBucket, в связи с чем в Тексте каждого важного комита уже указывается код задачи, и я не вижу проблемы в использовании других ключей для того чтобы указать в какой момент требуется собирать билд, а в какой — нет. Если вы считаете что данный флоу странный — укажите пожалуйста причины)

Я конечно очень давно не использую Дженкинс, но все же.
Совмещение коммита суть которого хранить историю и команд для ci, это очень плохая идея.
Не понятно, почему не использовать юайку/триггеры для прямой сборки?
Ну и флоу странный, это просто в первую очередь по тому, что я не очень понимаю, где тут реквесты, ревью и прочее, если это дебажный билд, то тем более делать его с коммитов, немного странно.

upd: попытался немного вчитаться, я так понимаю, это бранча по типу мастера, на нее у вас дженкинс смотрит и после мерджа ревью, вы хотите не всегда билды собирать, но я все равно не понимаю, почему инфа о билде находится в коммите, а не в общем конфиге хотя бы

По поводу флоу не совсем так.
В коменте комита прописывается «T-1(Код таски в Jira) -r Текст коммита».
После комита в ветку feature/*, hotfix/*, dev, master. Стартует через вебкук билд в jenkins.
Данный билд проводит написанные тесты в любом случае и отправляет статус билда в BitBucket и Jira.

Что это дает? Деву банально после комита не нужно делать побочные действия кроме как затрекать время и отправить ПР на проверку(Уверен что и это можно сделать автоматически).

В тоже время тим лид и тестировщик могут прямо с таски взять соответсвующий таске билд.

PS: Точно есть варианты и умнее но на данный момент данный нас устраивает полностью.

Наша команда для билдов использует Jenkins CI, но вы можете выбрать любую другую и использовать ее.

а поделитесь примерчиком?

Уточните пожалуйста примерчиком чего именно?

скриптиков, которые по по команде собирают нужный конфиг

Команда -d создает дебаг билд, -r — релиз билд, -i — IOS билд.

В пайпе есть 3 шага для каждого типа билда(IOS, Android debug, Android release).
Так же одним из первых шагов идет шаг анализа комита.
В данном шаге используется функция написанная на груви которая проверяет наличие в тексте комита строк (" -i", " -d«, «-r»).
Результат функции записывается в переменные и проверяется в начале этапов для каждого типа.
Если пайп заходит в соотвествующий этап он просто выполняет стандартные команды для сборки: [sh «flutter build apk —release»], [sh «flutter build apk —debug»].
С билдом под IOS мы приняли решение вынести сборку за пределы нашего сервера дабы ускорить процесс сборки. И на данный момент мы просто использование курл запроса стартуем билд на CodeMagic. (До этого был создан отдельный job в jenkins для IOS билдов но в связи с тем что IOS билд на нашем сервере занимает ±15 минут было принято решение в пользу CodeMagic с длительностью билда ±3-5 минут).

В данный момент пайп выглядит ± так:

/* import shared library */
@Library('jenkins-shared-library')_

pipeline {
    agent any

    environment {
        PROJECT_FLUTTER_VERSION = "1.20.4";

        // Tokens
        DEBUG_BUILD_TOKEN = " -d";
        RELEASE_BUILD_TOKEN = " -r";
        IOS_BUILD_TOKEN = " -i";
        ALL_BUILD_TOKEN = " -a";

        // Routes to .apk files.
        RELEASE_APK_ROUTE = "build/app/outputs/apk/release"
        DEBUG_APK_ROUTE = "build/app/outputs/apk/debug"
    }

    stages {
        stage ('Checkout') {
            steps {
                checkout scm
            }
        }
        stage ('Steps Analysis') {
            steps {
               script {
                   env.FLUTTER_VERSION = sh (script: 'flutter --version', returnStdout: true).trim()
                   env.GIT_COMMIT_MSG = sh (script: 'git log -1 --pretty=%B ${GIT_COMMIT}', returnStdout: true).trim()

                   env.IS_ANDROID_DEBUG_BUILD = stringContains(env.GIT_COMMIT_MSG, DEBUG_BUILD_TOKEN)
                   env.IS_ANDROID_RELEASE_BUILD = stringContains(env.GIT_COMMIT_MSG, RELEASE_BUILD_TOKEN)
                   env.IS_IOS_BUILD = stringContains(env.GIT_COMMIT_MSG, IOS_BUILD_TOKEN)
                   env.IS_ALL_BUILDS = stringContains(env.GIT_COMMIT_MSG, ALL_BUILD_TOKEN)
                   env.IS_FLUTTER_VERSION_CORRECT = stringContains(env.FLUTTER_VERSION, PROJECT_FLUTTER_VERSION)

                   def data = readYaml file: "pubspec.yaml"
                   env.PROJECT_VERSION = data.version
                   env.PROJECT_NAME = data.name
                   env.PROJECT_DESCRIPTION = data.description

                   currentBuild.displayName = "${env.PROJECT_NAME}-v${env.PROJECT_VERSION} - Build number: ${env.BUILD_NUMBER}"
                   currentBuild.description = "${env.PROJECT_DESCRIPTION}\n${env.GIT_COMMIT_MSG}"

                   env.Build_text =
                   "\nProject Name: ${env.PROJECT_NAME}\nProject Version: ${env.PROJECT_VERSION}\nProject Description: ${env.PROJECT_DESCRIPTION}\n\nFlutter Version: $PROJECT_FLUTTER_VERSION\n\nCommit message: ${env.GIT_COMMIT_MSG}$BUILD_PAGE_TEXT$BUILD_LOGS_TEXT";
               }
            }
        }
        stage ('Flutter version') {
            when {
                expression {(env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_IOS_BUILD == "true"  || env.IS_ALL_BUILDS == "true") && IS_FLUTTER_VERSION_CORRECT == "false"}
            }
            steps {
                sh 'flutter version $PROJECT_FLUTTER_VERSION'
            }
        }
       stage ('Flutter pub get') {
            when {
                expression { env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_IOS_BUILD == "true" || env.IS_ALL_BUILDS == "true"}
            }

            steps {
                sh 'flutter clean && flutter pub get'
            }
        }
        stage ('Flutter Doctor') {
            when {
                expression { env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_IOS_BUILD == "true" || env.IS_ALL_BUILDS == "true"}
            }

            steps {
                sh 'flutter doctor'
            }
        }
        stage ('Build IOS Release') {
            when {
                expression {env.IS_IOS_BUILD == "true" || env.IS_ALL_BUILDS == "true"}
            }

            steps {
                sh "curl --location --request POST 'https://api.codemagic.io/builds' \
                    (ТУТ ПАРАМЕТРЫ CODE MAGIC)"}'"
            }
        }
        stage ('Build Android Debug') {
            when {
                expression {env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ALL_BUILDS == "true"}
            }

            steps {
                sh "flutter build apk --debug"
                script {
                    sh "mv $DEBUG_APK_ROUTE/app-debug.apk $DEBUG_APK_ROUTE/${env.PROJECT_NAME}-v${env.PROJECT_VERSION}-debug.apk"

                    archiveArtifacts artifacts: "$DEBUG_APK_ROUTE/${env.PROJECT_NAME}-v${env.PROJECT_VERSION}-debug.apk"
                }
            }
        }
        stage ('Build Android Release') {
            when {
                expression {env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_ALL_BUILDS == "true"}
            }

            steps {
                sh "flutter build apk --release"
                script {
                    sh "mv $RELEASE_APK_ROUTE/app-release.apk $RELEASE_APK_ROUTE/${env.PROJECT_NAME}-v${env.PROJECT_VERSION}-release.apk"

                    archiveArtifacts artifacts: "$RELEASE_APK_ROUTE/${env.PROJECT_NAME}-v${env.PROJECT_VERSION}-release.apk"
                }
            }
        }
    }
    post {
        success {
             echo "Success"
             script {
                  if (env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_IOS_BUILD == "true" || env.IS_ALL_BUILDS == "true") {
                      // Telegram send notification
                      // Slack send notification
                  }
             }
        }
        aborted {
            echo "Aborted"
            script {
                if (env.IS_ANDROID_DEBUG_BUILD == "true" || env.IS_ANDROID_RELEASE_BUILD == "true" || env.IS_IOS_BUILD == "true" || env.IS_ALL_BUILDS == "true") {
                    // Telegram logs post
                    // Slack send notification
                }
            }
        }
        failure {
            echo "Failure"
            script {
                    // Telegram logs post
                    // Slack send notification
                }
            }
        }
    }
}

PS
Так же добавлена новая команда " -a" для всех билдов.

PS x2
Прошу экспертов не судить строго тк это первая настройка Jenkins и я уверен что есть варианты сделать что-то подобное проще)

Підписатись на коментарі