Обратите внимание на обновление подписки "Dependency Injection" публичного аккаунта WeChat
Ниже приводится аранжировка и дополнение, которым я поделился внутри команды год назад. Уровень ограничен. Если есть какие-либо ошибки, пожалуйста, дайте мне знать.
Привет всем, меня зовут Ван Лигуо. В настоящее время я возглавляю группу разработки RPA. В прошлом году мы создали платформу обработки RPA с нуля. В настоящее время количество строк кода, поддерживаемых в внешний интерфейс составляет около 130 000 строк, из которых более 92% составляют код TypeScript.Существуют следующие три активные итерации репозитория кода:
- Фон администратора, созданный с помощью TS3.5 + Angular8 + Rxjs (в настоящее время обновлен до Angular9)
- Платформа разработки с низким кодом, построенная на TS3.7 + Electron5 + React16.8 + Redux + Mobx + Nodejs
- Настольное приложение, созданное с помощью TS3.7 + Electron8 + React16.8 + Mobx + Nodejs
После всех усилий в течение этого периода времени следует сказать, что код трех вышеперечисленных складов относительно элегантен, а стоимость обслуживания относительно невелика (вы должны были не работать сверхурочно в течение полугода, ха-ха). Основная работа, которую я проделал за этот период, это проектирование архитектуры и проверка кода. В процессе я накопил некоторый опыт. Я очень рад возможности пообщаться с вами сегодня. Сегодняшний обмен состоит из 10 частей, а именно:
Перед официальным стартом я хотел бы сделать вам заявление.Вышеуказанные 10 частей - это только вопросы, которые я лично считаю первоочередными.Они разбираются отдельно и обсуждаются с вами.Если вы хотите вникнуть в то, как конкретная линия написанного кода Чтобы быть более элегантным, вы можете прочитать больше книг по методологиям кодирования на рынке, кроме того,Сегодня это содержимое применимо только к проектам, разработанным бизнесом верхнего уровня, то есть оно не применимо к проектам с открытым исходным кодом/проектам базовой библиотеки.
Кроме того, поскольку мы используем Angular и React одновременно, код двух фреймворков может быть перемешан в сегодняшнем примере, но это не будет включать слишком много концепций, связанных с фреймворком, и не повлияет на ваше понимание.
1/10 Основные соглашения:
1. Структура каталогов
В большинстве случаев ваша структура каталогов хорошо организована, а ремонтопригодность приемлема, а хорошая структура каталогов должна говорить сама за себя.
Вот специальное объяснение, почему в проектах Angular вам лучше иметьmodules
каталог, потому что по прошествии длительного времени вы обнаружите, что простой общий каталог трудно удовлетворить ваши потребности. Иногда вы полагаетесь только на компонент в общем, но вам нужно импортировать весь общий ресурс. Это потому, что иногда модуль маршрутизации соответствует не только Это домен, В этом случае я настоятельно рекомендую вам разделить общий каталог на более мелкие детали в соответствии с моделью домена или даже удалить общий каталог и изменить его на каталог модулей, чтобы модуль маршрутизации может импортировать несколько модулей домена по мере необходимости.
2. Стиль именования
Несколько замечаний:
-
Определения типов лучше всего снабжать префиксом, чтобы различать типы и значения (это может быть ограничено TSlint).
// tslint.json { "rules": { "interface-name": [true, "always-prefix"], } }
-
Именование классов CSS также может быть ограничено с помощью stylelint.
// .stylelintrc.json { "rules": { // example:aa-bb-cc,aa-bb-width120 "selector-class-pattern": "^[a-z][a-z0-9]*((-[a-z0-9]+)*|[a-z0-9]*)$" } }
2/10 Тип Безопасность
В первые дни, когда я был единственным в команде, я выбрал es6 для быстрой разработки, позже продукт был повышен до стратегического продукта компании, команда также стремительно расширялась, уровень инженеров был градиентом, а потребность в ограничениях типов росла, поэтому Мы очень решительно решили перевести весь проект на 100% TS.В то время, чтобы снизить стоимость миграции, в коде было еще много всякого,Разочаровывает то, что если вы не можете хорошо использовать систему типов TS, использование TS увеличит умственную нагрузку и снизит эффективность кодирования.Позже мы запустили повальное увлечение TS.Все продолжали читать документы, расширенные руководства, изучать элегантно оформленные коды TS на рынке и пытаться построить относительно стандартную систему TS.
Скоро any в проекте станет менее заметным для невооруженного глаза, и теперь мы включили два важных ограничения в проверке полной ссылки:
- уровень ошибки -> запретить любые
- Уровень ошибки -> Неявное любое не разрешено
Кроме того, здесь следует упомянуть, что человеческому сознанию не всегда можно полностью доверять, даже если вы используете хук pre-commit для запуска lint, его можно легко обойти.Я настоятельно рекомендую вам добавить проверки lint в ваш облачный поток ci и применить ограничения, согласно которым ветки, не прошедшие проверку lint, не могут быть объединены.
После включения и полного отключения любого в первые дни наша эффективность кодирования была очень неэффективной, и много раз нам приходилось писать множество определений типов.
К счастью, в большинстве случаев инструменты или библиотеки, которые мы используем, экспортировали некоторые типы инструментов, и существует очень мало типов инструментов, которые нам нужно написать самим.Я рекомендую несколько ресурсов, которые помогут вам быстрее писать более безопасный код TS:
- Tearmscript встроенные типы инструментов
- Библиотека типов инструментов сообщества
- Лучшие практики React + TypeScript
3/10.Аннотация Виновен
Такой комментарий выглядит забавно, не так ли? Но я считаю, что ваш проект должен иметь и до сих пор генерирует такие аннотации. Как писать комментарии — это настоящее искусство, и вас будут ругать за то, что вы пишите слишком много и слишком мало. Мое предложение очень простое:Никогда не комментируйте, если у вас нет веской причины.
Подумайте, при каких обстоятельствах вы бы стали жаловаться, что код не закомментирован?
- Трудно понять или совершенно непонятно
- Я думал, что понял, но неправильно понял(удален фрагмент кода, который я считал бесполезным, вызывающим серьезные проблемы)
Тогда легко понять, когда нам нужны аннотации:
- сложный код:Сложный бизнес/использование непонятных технологий, хитрые методы внедрения
- Скомпрометированный код:Дизайн не очень, но для реализации бизнеса другого лучшего выбора пока нет.
- Код совместимости:Лучше всего аннотировать нисходящий/совместимый с платформой код, чтобы избежать случайного удаления.
4/10 Разделение конфигурации
Для различий на уровне компонентов, много разProps
Этого достаточно, если модуль, состоящий из нескольких компонентов, необходимо дифференцировать, вы можете использовать многоуровневую передачу параметров или статические переменные, но я хочу сказать вам, что в большинстве случаев это возможно.Provider
Более уместно, особенно если вы хотите использовать несколько конфигурационных схем одновременно в жизненном цикле приложения.
На самом деле, каждыйProvider
Неудивительно, что Angular или React можно легко использовать.Provider
,следующим образом
Я хочу сказать здесь, в частности, каждыйAngular
При написании повторно используемых модулей в проекте лучше всего развивать экспозицию.InjectToken
привычка, даже если кажется, что она пока не нуждается в настройке.
5/10 Управление состоянием
О программах управления состоянием глобального рынка относительно зрелых, таких как Rxjs, Mobx, Redux ... сегодня мы не будем слишком много изучать глобальное управление состоянием, больше хотим изучить с вами местное государственное управление.
Сначала задайте вам вопрос:Можно ли повторно использовать локальное государственное управление? Или мне следует повторно использовать локальный код управления состоянием? 🤔
Еще один вопрос:Если его можно использовать повторно, должны ли мы использовать композицию или наследование? 🤔
мое предложение:Можно использовать повторно, но лучше не использовать наследование, можно рассмотреть композицию.
На самом деле, в Angular вы можете повторно использовать локальный код управления состоянием, просто внедряя сервисы с уровня компонентов. Это так просто? На самом деле этоMVP
Реализация архитектуры, в которой поставщики на уровне компонентов действуют как уровень презентатора.
Начиная с версии 16.8 React, вы можете использовать хуки для объединения локального управления состоянием. Я думаю, все слышали об этом. Наш реальный опыт:Простота в использовании действительно проста в использовании, и есть действительно много ям.
Мы также использовали нашу собственную библиотеку хуков в прошлом (@bixi/hooks), можете взять и поиграть, если вам интересно.
6/10 оптимизация производительности
Мой последовательный взгляд на оптимизацию производительности таков:Лучшее время — когда проект создан, а затем — сейчас.
Лучше всего для всех выработать привычку писать высокопроизводительный код.Ниже приведены некоторые методы оптимизации производительности, которые мы часто используем в процессе разработки.Не вдаваясь в подробности, вы можете изучить их один за другим.
7/10 Управление версиями
Здесь есть две части управления версиями:
-
Управление версиями зависимых библиотек:
- Обязательно заблокируйте сторонние зависимости (yarn.lock)
-
Управление версией бизнес-кода
- Обратная совместимость по крайней мере с одной основной версией
- Отметьте совместимый код и запишите
- Регулярно очищайте совместимый код
8/10 Умеренный пакет
Говоря об инкапсуляции, давайте сначала посмотрим на процесс изменения следующего сегмента кода.
- Вам нужно написать фрагмент кода для отслеживания изменений значений четырех компонентов и синхронизации их с локальным состоянием.Вы написали код слева, и вы чувствуете, что код очень прост, поэтому отправьте код, чтобы выйти работай.
- Когда меняются требования, когда меняются значения компонентов a и b, будут какие-то побочные эффекты, поэтому вы корректируете код вправо, и код как бы медленно развивается в неконтролируемом направлении
- Вы начинаете жаловаться, что код плохой, потому что требования перепутаны....
В прошлом процессе проверки кода я обнаружил, что многие студенты хотели бы написать приведенный выше код, и они могут назвать мне вескую причину:Функции разделены и используются повторно..
Однако действительно ли ваш код используется повторно?
Фактически, в процессе разработки бизнес-кода чрезмерная инкапсуляция многократно увеличивает сложность и снижает удобство сопровождения, поэтому я часто говорю вам:ты усложняешь это".
Мы можем попытаться преобразовать приведенный выше код самым тупым и простым способом следующим образом.
Вы обнаружите, что количество строк в этом коде увеличивается, но его очень просто поддерживать Когда я имею дело с логикой, меня не волнует, повлияет ли это на b/c/d...
9/10 Дизайн компонентов
Давайте взглянем на следующие требования к дизайну компонента.Это реальный компонент в нашем приложении.Он имеет следующие четыре основные характеристики:
Некоторые принципы разборки компонентов студентами:Что бы это ни было, удаляйте его до тех пор, пока его больше нельзя будет удалить.
Затем, когда он столкнется с требованиями к дизайну вышеуказанного компонента, он будет разобран на левую часть ниже или даже более мелко, так в чем проблема с этой разборкой?
-
Стили 1/2/3/4 связаны, и разборка затруднит написание стилей
-
5/6/7 Компоненты не имеют большого значения для повторного использования, а демонтаж только увеличит сложность
Очевидно, что чем меньше компонентов, тем лучше, поэтому мы рекомендуем вам разобрать их на два компонента, как показано справа (конечно, если ваш код сложный, вы можете разобрать их соответствующим образом).
Давайте посмотрим на этот простойInput
компонент, чтобы увидеть, как он имеет несколько грехов:
-
Подозревается наличие зависимостей со стилями других компонентов.
input{ border-right: none; }
-
Компоненты не подлежат повторному использованию, что приводит к
searchTasks
мероприятие -
Компоненты раскрывают детали реализации и должны полагаться на внешние
validate
метод -
Компонент копируется во время инициализации
value
Копировать и не продолжать после внешнего монитораvalue
Изменить обновление копий, что приводит к тому, что приводят к данным, а не мощности и т. Д.
10/10 Защитное программирование
Написание более надежного кода, конечно, должно быть нашей долгосрочной задачей, но некоторые вредные привычки программирования могут затруднить отслеживание ваших проблем с кодом, а ваш инструмент мониторинга ошибок (мы используем sentry для отслеживания ошибок кода) может стать бесполезным. код на рисунке выше:
// bad
if (this.editor) {
this.editor.destory();
}
// bad,等价于上面代码
this.editor?.destory();
Причина, по которой это плохо, заключается в том, что мы знаем, что после монтирования этого компонентаthis.editor
Он неизбежно должен существовать, тогда, если мы его удалим, если он не существует, мы должны вовремя выдать ошибку, а не проглатывать ее молча, Лучший способ справиться с этим должен быть следующим:
// good,我们断定它一定存在
(this.ediotor as Editor).destory();
В общем, вам лучше соблюдать осторожностьlodash
илиoptional chaining
, неправильное место должно быть брошено вовремя.
Конечно, чтобы не сделать ваше приложение слишком безобразным сбоем, вам все равно нужно хорошо поработать над сбором ошибок и ухудшением пользовательского интерфейса.
Спасибо вам всем.
Обратите внимание на обновление подписки "Dependency Injection" публичного аккаунта WeChat