Я собирался написать пост в блоге на эту тему, но, к сожалению, в этом я не так продуктивен, как в написании кода.
tl;dr Небольшие специализированные модули нужны для повторного использования и для того, чтобы делать большие и сложные штуки, которые легко понять.
Люди слишком озабочены количеством строк кода. LOC вообще не имеет никакого значения. Не важно, состоит модуль из одной строчки, или из сотен. Все дело в сокрытии сложности. Думайте о модулях node как о кубиках лего. Вас не интересует, из чего и как они сделаны. Все, что вам требуется знать — как использовать эти кубики для постройки своего лего-замка. Делая маленькие и специализированные модули, вы можете легко строить большие и комплексные системы без контроля за тем, как каждая отдельная деталь работает. Наша кратковременная память конечна. Эти модули могут повторно использовать другие люди и каждое улучшение и исправленный баг получат все из них.
Представьте себе, если бы производители ПК производили процессоры сами. Большинство делали бы это плохо. Компьютеры были бы дороже, а инновации происходили бы медленнее. Вместо этого большинство использует Intel, ARM и прочие.
И это было бы невозможно, если бы npm не работал именно так. Красота многоуровневых зависимостей заключается в том, что я не должен контролировать, какие зависимости зависимостей я использую. В этом его сила.
Несколько лет назад, до Node.js и npm у меня была большая база сниппетов, которые я копипастил в проекты, когда в этом была нужда. Это были небольшие полезности, которые иногда пригождались. Теперь npm — моя база сниппетов. Зачем копипастить, если можно зареквайрить модуль и получить именно то, что нужно. Исправление бага в «сниппете» — всего лишь обновление одного модуля, а не исправление «руками» всех мест, где сниппет вставлялся бы.
К примеру, у меня есть модуль negative-zero. Его работа — сказать мне, что число равно
-0
. Обычно это не требуется, но случается. И как нам определить, что число — -0
. Вполне легко, x === 0 && 1 / x === -Infinity
. Так? Вам действительно надо знать, как и почему это работает так? Я бы предпочел подключить negative-zero
и сконгцентрироваться на других вещах.Другой пример. Один из самых популярных модулей на npm — Chalk. Возможно, вы не знаете этого, но, на самом деле, это набор модулей. Он использует модули для определения поддержки цветов в терминале, для получения ansi-кодов и т.д. Все это можно было бы включить в основной модуль, и так и есть, скорее всего, в большинстве случаев. Но это означало бы, что кто-то создаст еще один модуль для работы со строками в терминале и переизобретет колесо. С этим же набором модулей, люди легко получают выгоду от использования в своих проектах Chalk'а и, может быть, даже помогают косвенно улучшить сам Chalk, улучшая одну из его зависимостей.
И еще пример. Мой модуль user-home нужен только для того, чтобы получить домашнюю директорию пользователя. Вы можете подумать, что может быть проще, чем написать
process.platform === 'win32' ? process.env.USERPROFILE : process.env.HOME
. И большинство так и сделает. Но, правда, зачем каждому из нас знать, как получить домашнюю директорию? Почему бы не использовать готовый «кубик лего»? Ну и, конечно же, вы можете и не знать, что эта проверка — неполная. В Windows вам надо также посмотреть process.env.HOMEDRIVE + process.env.HOMEPATH
, а еще вы могли бы также захотеть сделать дополнительные проверки. Лего.Вы же не шьете себе собственные ботинки? Нет, вы покупаете их в магазине. Большинство не заботит, как изготавливаются их ботинки. Только то, как они хорошо сидят на ноге.
Я хочу, чтобы программировать было проще. Делать программирование более простым — это строить надежные системы. И практический путь в моем видении — это перестать переизобретать все подряд и делать одни и те же глупые ошибки снова и снова.
Комментарии (11)
Meredian
15.07.2015 15:46+4Есть одна сложность с кучей модулей — найти в них можно только если знаешь, что искать. У нас в компании-то приватный npm уже разрастается достаточно, что некоторые решения «теряются», и их находят много позже, да и то — только потому, что кто-то знал про него и увидел, что в коде вместо него используется велосипед.
Я гуглю много мелочей прежде, чем костылить самому, но идея, что можно, например, использовать модуль homedir, мне просто в голову не приходила.marapper Автор
15.07.2015 16:07Ага. Это основной недостаток, возникающий при такой концепции. Как и мобильным сторам, так и нпм, рано или поздно придется задуматься о нормальной классификации. Пока помогают профильные издания, списки, пробы на тестовом проекте, но все же иметь дело с сотнями модулей тяжко.
Зато в таком подходе хорошо работают фреймворки (появляется 4-5 микро- и нормальных, о которых все знают), скаффолдеры и инструменты аля gulp (с которым сначала гуглишь gulp-плагин, который оборачивает сколько-то бибилотек, а если нет, — пишешь пару строк кода).
crmMaster
15.07.2015 16:36+2Вы только товарищам, пишущим на PHP это не показывайте — а то напихают композером овер 9000 модулей, а ты дождаться загрузки сайта не можешь.
Подход «собираем приложение из кубиков» работает ТОЛЬКО на системах, загружающихся в память при старте и далее ничего глобального не инициализирующих.
ystr
16.07.2015 13:02+2Мне вот интересно: этот автор 666-ти модулей когда-нибудь сам писал что-то очень сложное? Или его хлеб это модули типа «negative-zero»?
kriptomen
Простите за оффтоп, habrahabr, запили AMA!
marapper Автор
Яростно плюсую. Это куда лучше и интереснее конференций, халявных планшетов на неделю, странных сервисов по вопросам/фрилансу. Тем более, что ресурс и воля сделать это, есть.
Mithgol
Мягко скажу, что я бы таким AMA не пользовался, потому что habrahabr уж конечно запретил бы на нём вопросы и ответы политического направления; а ведь это не anything тогда был бы.