Как стать автором
Обновить

Совет #1 по ознакомлению с новыми кодовыми базами JavaScript

Время на прочтение10 мин
Количество просмотров3.2K
Автор оригинала: Kevin Peters

За годы работы программистом я просмотрел, возможно, сотни кодовых баз. Слишком много, чтобы посчитать точно. Я много мучился с пониманием того, где в большинстве случаев находится значимый код. Обычно просьба подсказать, на что я должен обратить внимание, и указания в тикетах подталкивают меня вперед. Медленно, но уверенно, я буду понимать, что делает код. И вы тоже поймёте. У некоторых людей это получается лучше, а у некоторых — медленно. От этого не должно быть стыдно. В большинстве случаев код сложен. Но я нашёл простой инструмент, который облегчит вам задачу. Он называется code-complexity, и вы можете использовать его следующим
образом:


npx code-complexity . --limit 20 --sort ratio
# Вы можете также использовать --filter '**/*.js', чтобы применить паттерн для фильтрации файлов

Он выведет похожий на этот результат:


file complexity churn ratio
src/cli.ts 103 8 824
test/code-complexity.test.ts 107 7 749
.idea/workspace.xml 123 6 738

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


Сложность и текучесть


В этой главе я объясню концепты сложности (complexity) и текучести (churn), когда дело касается кода. Это основа для понимания методики, которую мы тут используем, чтобы улучшить понимание кодовой базы.


Что такое Сложность?


Сложность может быть определена разными способами. Как правило, для оценки сложности кода используется уровень вложенности функций. Код с небольшими функциями и скомпонованным поведением обычно более читабельный и лёгкий для понимания. Таким образом, можно сказать, что сложный код состоит из нескольких глубоко вложенных функций, и в основном это действительно так. Однако вложенность трудно отслеживать, поэтому надо найти другую метрику.


Длинные функции обычно находятся в больших файлах. Если люди помещают много всего в одну функцию, то они также часто складывают всё в один файл. Так что в теории мы могли бы взять за метрику и количество строк кода. Существует множество пакетов утилит, которые решают эту задачу. Один из них называется sloc. Он выводит количество строк кода в файле. Но не используйте его напрямую: инструмент, о котором я упомянул ранее, включает его по умолчанию.


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


Что такое Текучесть?


Текучесть немного сложнее для объяснения. Но давайте начнём с чего-нибудь. Текучий файл — это файл, в котором много изменений. Но что это значит?


В файле происходит много изменений, когда, очевидно, много людей изменяют его. Но как кто-то может это измерить? История git'а говорит нам, как часто файл фиксировался. Так что мы можем быть уверены, что файл, вероятно, будет изменён. Обычно это значит, что файлы такого типа являются основной точкой приложения. Проблема, однако, заключается в том, что часто сюда включаются конфигурационные файлы, но вы можете просто исключить их из анализа.


Чему может научить нас Сложность + Текучесть?


Сейчас, после изучения понятий сложности и текучести, мы можем сфокусироваться на их комбинации. Файлы, которые чаще всего изменяются и являются действительно сложными, должны подвергнуться рефакторингу. И в большинстве случаев естественно то, что такие файлы могут быть ядром приложения. Основная логика пишется в них напрямую или в связанных файлах. Так что давайте посмотрим, как мы можем анализировать их дальше.


Детальная проверка файлов


Моя методика детальной проверки файлов довольно проста. Сначала я просматриваю файл и проверяю, как называются экспортируемые функции. В идеале, я записываю их. Внутренние функции в начале не важны для понимания. Получив представление обо всех экспортируемых функциях, я в первую очередь проверяю, есть ли какие-нибудь unit-тесты. Если у функции есть параметры, то я также стараюсь их записать. С типами TypeScript и Flow становится гораздо проще получить общее представление о структуре.


Губка Боб ищет


Губка Боб детально проверяет код


Unit-тесты — хороший для старта подход, позволяющий увидеть, как работают функции. Чтобы понять функции, вам, наверное, достаточно посмотреть на вход, имя функции и на то, что она возвращает. В большинстве случаев вам помогают в этом типы, а unit-тесты показывают крайние случаи для функции, и как они могут быть использованы. Так что во многом этого достаточно, чтобы понять функцию. По крайней мере, если вы знаете язык программирования. Если вам хочется глубже погрузиться в функцию, то так и сделайте, но вам совсем не обязательно заниматься этим. Почему? Объяснение в следующей главе.


Почему не нужно понимать каждую деталь?


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


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


Хорошей идеей для первой задачи будет также организовать парное программирование с другими разработчиками из команды. Обязательно скажите им, что вы хотите больше печатать, а они будут больше в качестве наблюдателя, для того чтобы вы научились самостоятельно ориентироваться в кодовой базе. Благодаря такому онбордингу и простым тикетам, вам не придётся вдаваться в подробности. Детали кода будут обнаружены уже в ходе этапа реализации во время исправления багов или добавления нового функционала. Чем больше тикетов вы сделаете, тем больше подробностей вы узнаете о кодовой базе. Но оглядывайтесь назад на текучесть и сложность, потому что они могут меняться со временем.


Отладка деталей?


Теперь работа над кодовой базой будет связана ещё с одной большой вещью — отладкой. В ходе работы над первыми задачами вы, вероятно, уже научитесь, как запускать приложение локально, как запускать unit, интеграционные и e2e тесты, если они есть. Они становятся жизненно важными, когда вы реализовываете что-то, потому что добавление тестов позволит убедиться, что приложение работает так, как от него ожидается. Зачастую эти тесты охватывают много кода и являются в некотором роде абстрактными. В таких случаях вам нужно научиться отладке кода. Поскольку множество тестов выполняются в среде Node.js, мы быстро рассмотрим, как отлаживать приложения на базе Node.js. Множество инженеров используют console.log для отладки, и он полностью работоспособен в этом плане. Но если вам нужно следовать более крупным структурам кода, я могу порекомендовать использовать подходящий отладчик. JavaScript и TypeScript поддерживают ключевое слово debugger, тем не менее, запустить тесты и приятно работать в них с отладчиком довольно проблематично, потому что внутри Node.js немного сложно создать инструменты разработчика из окна браузера и подключить их к программе. Другим вариантом было бы использовать вашу IDE или редактор для подключения отладчика, который поддерживается в них. Например, Visual Studio Code поддерживает отладку Node.js приложений напрямую в IDE. Гайд об отладке Node.js в VS Code можно найти здесь.


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


Примеры


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


Blitz.js


Blitz.js — это фреймворк, построенный поверх Node.js. Он позиционирует себя как Ruby on Rails для JavaScript/TypeScript. Команда работает над этим фреймворком более года, и было бы интересно посмотреть, где находится их ядро логики.


Первым шагом, конечно, склонируем репозиторий в папку и затем выполним:


npx code-complexity . --limit 20 --sort ratio

file complexity churn ratio
nextjs/packages/next/compiled/webpack/bundle5.js 91501 1 91501
nextjs/packages/next/compiled/webpack/bundle5.js 91501 1 91501
nextjs/packages/next/compiled/webpack/bundle4.js 74436 1 74436
packages/cli/src/commands/generate.ts 228 28 6384
packages/cli/src/commands/new.ts 177 35 6195
packages/generator/src/generators/app-generator.ts 235 23 5405
packages/generator/src/generator.ts 283 19 5377
packages/server/src/stages/rpc/index.ts 184 28 5152
packages/server/test/dev.test.ts 190 27 5130
packages/core/src/types.ts 160 28 4480
packages/server/src/next-utils.ts 176 25 4400
packages/generator/templates/app/app/pages/index.tsx 240 18 4320
packages/server/src/config.ts 116 37 4292
packages/core/src/use-query-hooks.ts 184 22 4048
nextjs/test/integration/file-serving/test/index.test.js 3561 1 3561
examples/auth/app/pages/index.tsx 210 16 3360
packages/cli/src/commands/db.ts 75 44 3300
.github/workflows/main.yml 132 24 3168
packages/cli/test/commands/new.test.ts 141 19 2679
examples/store/app/pages/index.tsx 181 14 2534
packages/display/src/index.ts 158 16 2528

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


Мы видим, что здесь важны несколько каталогов:


  • packages/cli
  • packages/generator
  • packages/server
  • packages/core

Если мы получим задачу, то, по крайней мере, уже будем знать, где искать соответствующий код. Изначально, я бы попытался разобраться в файлах из packages/core, чтобы понять, что они делают. Затем понять тесты, если они есть, и тогда у вас должно появиться хорошее понимание того, что делает Blitz.


React.js


React.js — это фронтенд фреймворк, который почти каждый веб-разработчик сейчас знает. Чего большинство людей не знает, так это как структурирована кодовая база и какие её основные части. Так что давайте посмотрим на это.


npx code-complexity . --limit 20 --sort ratio

Выполнение команды приведёт к следующему результату:


file complexity churn ratio
packages/eslint-plugin-react-hooks/**tests**/ESLintRuleExhaustiveDeps-test.js 7742 51 394842
packages/react/src/**tests**/ReactProfiler-test.internal.js 4002 95 380190
packages/react-reconciler/src/ReactFiberWorkLoop.new.js 2373 139 329847
packages/react-reconciler/src/ReactFiberWorkLoop.old.js 2373 114 270522
packages/react-dom/src/server/ReactPartialRenderer.js 1379 122 168238
packages/react-reconciler/src/ReactFiberCommitWork.new.js 2262 71 160602
packages/react-devtools-shared/src/backend/renderer.js 2952 54 159408
packages/react-reconciler/src/ReactFiberBeginWork.new.js 2903 53 153859
scripts/rollup/bundles.js 760 199 151240
packages/react-reconciler/src/ReactFiberHooks.new.js 2622 56 146832
packages/react-dom/src/client/ReactDOMHostConfig.js 1018 140 142520
packages/react-reconciler/src/ReactFiberHooks.old.js 2622 50 131100
packages/react-reconciler/src/**tests**/ReactHooks-test.internal.js 1641 74 121434
packages/react-dom/src/**tests**/ReactDOMComponent-test.js 2346 51 119646
packages/react-dom/src/**tests**/ReactDOMServerPartialHydration-test.internal.js 2150 49 105350
packages/react-noop-renderer/src/createReactNoop.js 966 109 105294
packages/react-reconciler/src/ReactFiberCommitWork.old.js 2262 46 104052
packages/react-reconciler/src/ReactFiberBeginWork.old.js 2903 35 101605
packages/react-reconciler/src/**tests**/ReactIncrementalErrorHandling-test.internal.js 1532 62 94984
packages/react-refresh/src/**tests**/ReactFresh-test.js 3165 29 91785

Здесь мы видим, что два подпакета, наверное, наиболее интересны для понимания:


  • packages/react-dom
  • packages/react-reconciler

Понимание React Fiber и того, как работает частичный отрисовщик react-dom даст вам хорошее представление об архитектуре React. Приятным моментом в коде React является то, что он отлично документирован комментариями, хотя по началу он всё равно сложен.


Venom — TypeScript клиент для Whatsapp


Venom — это библиотека для взаимодействия с Whatsapp. Вы можете отправлять сообщения через эту библиотеку и делать множество других вещей. Она немного практичнее, потому что именно подобными приложениями вы будете заниматься в своей повседневной работе. Так что давайте выполним нашу обычную команду:


npx code-complexity . --limit 20 --sort ratio

file complexity churn ratio
src/lib/jsQR/jsQR.js 9760 5 48800
src/lib/wapi/wapi.js 474 44 20856
src/api/layers/sender.layer.ts 546 36 19656
src/lib/wapi/store/store-objects.js 362 24 8688
src/controllers/initializer.ts 178 48 8544
src/lib/wapi/jssha/index.js 1204 5 6020
src/api/layers/retriever.layer.ts 171 29 4959
src/types/WAPI.d.ts 203 24 4872
src/api/layers/host.layer.ts 258 17 4386
src/api/layers/listener.layer.ts 206 21 4326
src/controllers/browser.ts 141 29 4089
src/controllers/auth.ts 192 21 4032
src/api/model/enum/definitions.ts 589 6 3534
src/api/whatsapp.ts 95 30 2850
src/lib/wapi/functions/index.js 97 24 2328
src/api/layers/profile.layer.ts 82 22 1804
src/lib/wapi/business/send-message-with-buttons.js 323 5 1615
src/api/layers/group.layer.ts 115 14 1610
src/api/layers/controls.layer.ts 76 20 1520
src/api/model/message.ts 114 11 1254

Здесь мы можем увидеть, что есть каталоги, которые имеют важное значение:


  • src/lib
  • src/api
  • src/controllers

Как мы можем видеть, в каталоге src/lib лежат автоматически сгенерированные файлы. В идеале, мы могли бы отфильтровать их, но пока давайте посмотрим на другие файлы.


src/api/layers/sender.layer.ts и src/api/layers/retriever.layer.ts не сложные, но имеют много изменений. Поэтому каждый раз, когда функциональность добавляется или удаляется, затрагиваются эти файлы. Это основные файлы приложения и их понимание даст вам хорошее представление о том, как структурирована кодовая база и на чём вам следует сконцентрироваться.


Откуда взялась эта методика?


Эта методика анализа кодовой базы изначально возникла из книги, которая описывала рефакторинг больших кодовых баз: Software Design X-Rays Адама Торнхилла (Adam Tornhill). Это отличная книга, которая научит вас многому: как структурировать код и какие части стоят рефакторинга. Отличная книга. Я думаю, что каждый программист должен прочитать её в какой-то момент, потому что она поможет взглянуть на кодовую базу с другой стороны. Работая над проектом, люди будут знакомиться с различными частями программного обеспечения и, конечно же, у них будет своя особая "область" кода, где им будет супер комфортно. Является ли этот код хорошим и понятным — это еще один вопрос, на который пытается ответить эта книга.


Software Design X-Rays Адама Торнхилла


Software Design X-Rays Адама Торнхилла


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


Другие языки


Утилита code-complexity тесно связана с кодовыми базами на JavaScript и TypeScript. Для других языков, таких как Java, C#, Python и PHP существуют другие инструменты, но есть один общий инструмент, который работает для большинства кодовых баз, это code-maat. Это инструмент, созданный автором книги, упомянутой в прошлой главе.


С его помощью вы можете проанализировать проект и прийти к тем же выводам, которые упоминались в статье.


Заключение


Я надеюсь, вам понравилась эта статья, и ваша жизнь стала немного проще. Вход в новую кодовую базу сложен, и особенно в постоянно меняющимся мире JavaScript за ней трудно поспевать. С инструментами и процессами, представленными в этой статье, вам, возможно, будет проще вписаться в новую кодовую базу. Не стесняйтесь поделиться этой статьёй со своими коллегами, а также расскажите им о методиках, которые вы используете. Большинство моих знакомых разработчиков не знают об анализе текучести и сложности, а ведь это может быть очень полезно для всех. Так что поделитесь этим!

Теги:
Хабы:
+4
Комментарии0

Публикации

Истории

Работа

Ближайшие события

Weekend Offer в AliExpress
Дата20 – 21 апреля
Время10:00 – 20:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн