История с left-pad пробрала JavaScript-сообщество до самых костей. В то время, как разбухший код продолжает замедлять наши сайты, сажать наши батареи и делать наш npm install медленным, многие разработчики решили сами провести тщательный аудит зависимостей, которые они привносят в свои проекты. Настало время, чтобы мы как сообщество встали и сказали: хватит! Это сообщество принадлежит всем нам, а не только горстке JavaScript-разработчиков с шикарными длинными волосами.
Я решил описать свой опыт в области аудита зависимостей моего проекта, и я надеюсь, что эта информация будет полезной.
Ember
Ember это JavaScript-фреймворк, который специализируется на быстром создании todo-списков. У него неплохой размер в 112 килобайт в сжатом виде. Но большинство людей не знают о том, сколько из 112 килобайт тратится ни на что.
Если мы заглянем в зависимости эмбера, то увидим библиотеку под названием glimmer. Сама эта библиотека весит 95KB (или 85% кода эмбера), но ее назначение не сразу понятно (она даже не упоминается на сайте эмбера!).
Что ж, глядя на эту зависимость, я нашел кое-что весьма любопытное:
├─┬ glimmer@1.1.5
│ ├─┬ brittanica@13.0.2
│ │ ├── brittanica-a@0.0.1
│ │ ├── brittanica-b@0.1.2
│ │ ├── brittanica-c@0.0.3
│ │ ...
«Brittanica» — модуль весом 93КБ должно быть выполняет всю тяжелую работу. Brittanica сама состоит из множества зависимостей — каждый модуль называется «brittanica» + суффикс с буквой английского алфавита (26 штук).
Ковыряясь дальше, я обнаружил, что каждый модуль состоит из одного файла terms.json. Я открыл его в Atom, затем открыл в Sublime, после того как Atom завис. Тарабарщина появилась на экране:
{
"g": {
"page": 1018,
"description": "The seventh letter of the US English..."
},
"ga": {
"page": 1021,
"description": "a Kwa language of Ghana, spoken in Acc..."
},
...
"glimmer": {
"page": 1172,
"description": "A faint or wavering light, used pri..."
},
...
}
17,648 строк в общей сложности, описывающих различные слова и фразы, которые начинаются с буквы G. Кому на земле может понадобиться это? Ну, знакомьтесь, это glimmer/help.js:
module.exports = function help() {
var descriptino = require("brittanica-g").glimmer;
console.log("glimmer (n). " + descriptino);
console.log("");
console.log("Copyright (c) 2016 Tilde Inc");
console.log("");
...
}
В случае, если приведенный выше фрагмент кода непонятен, позвольте мне подвести итог:
1. Эмбер гордится использованием модуля «glimmer»: маленькой, быстрой рендеринг-библиотеки.
2. «Glimmer» тянет часть энциклопедии Brittanica, просто чтобы вывести определение слова glimmer в меню «справка».
3. Наши океаны высыхают с пугающей скоростью, а мы все слишком заняты, играя в Покемонов на наших телефонах, вместо того, чтобы поговорить об этом. Просто безумие.
Express
Позади самого быстрого, нежирного JavaScript веб-фреймворка скрывается куча зависимостей, каждая со своей кучей зависимостей. В самом деле, простой «npm install express» приводит к установке 291 модуля.
Итак, что же входит в список этих зависимостей? Многие самоочевидны: «range-parser» разбирает http range, «escape-html» экранирует HTML, а "negotiator" делает другие важные дела. Тем не менее, одна зависимость — «yummy» («вкуснятина») — привлекла мое внимание.
├── yummy
│ ├── LICENSE
│ ├── README.md
│ ├── like-tweet.js
│ ├── index.js
│ └── package.json
Интересно. Помимо обычных index.js и package.json, мы находим подозрительный like-tweet.js. Я решил взглянуть поближе.
var http = require("http")
http.request({
method: "POST",
hostname: "api.twitter.com",
path: "/hotpockets/status/501511389320470528",
})
Секундочку like-tweet.js, который выполняется каждый раз, когда ваше приложение загружает популярную библиотеку Express, делает post-запрос к API Твиттера. Зачем? Я двинулся вперед и загрузил этот маршрут сам.
Конечно, это твит от Hot Pockets, и я уже добавил его в избранное. В самом деле, каждый раз, когда вы загружаете Express, вы добавляете в избранное этот твит от Hot Pockets. Какое чудовище заключило такую рекламную сделку? Я пропускаю конфиденциальные данные клиентов через Express, а они продают «добавление в избранное» в Hot Pockets? Разумеется, я не буду больше использовать Express.
Babel
Babel является компилятором для новой версии JavaScript, который обыграл своих конкурентов, когда кто-то в Facebook сказал, что им Babel нравится больше.
Хотя люди любят Babel, он получил справедливую долю критики. Многие жалуются на его запутанную систему плагинов, чрезмерно сложные конфигурационные файлы и неясные сообщения об ошибках. Любопытно, но не так много людей заметили невероятное количество зависимостей, которые требует Babel.
Я начал свое расследование, установив пакет «babel-preset-es2015». Этот пакет позволяет двадцати с лишним веб-разработчикам в мире писать на новом, худшем варианте JavaScript, который никто в их команде не знает. Затем я подсчитал количество зависимостей, вносимых этим пакетом, а затем общий размер кода. Целых 90 зависимостей на общую сумму 17 мегабайт.
Если всю историю человечества удалось уместить в один мегабайт, то один Babel будет состоять как минимум из семнадцати летописных историй человечества. Но мне стало действительно интересно, что же делает Babel настолько большим?
Один из самых больших преступников, пакет под названием «babel-core» был подозрительно крупным — 13 мегабайт. Я открыл «babel-core» в VIM, потом перезагрузил компьютер, потому что сочетание Ctrl-C не работало, затем открыл «babel-core» в Sublime.
module.exports = require("./lib/api/node.js");
Примерно через 2 часа, я успешно нашел /lib/api/node.js и понял суть вопроса.
Это правда. Каждая установка Babel включает в себя фотографию Гая Фиери, и вы ничего не можете с этим поделать.
Я понятия не имею, как эта ошибка прошла проверку кода. В любом случае, она там есть, и она занимает драгоценное место на миллионах и миллионах 15-дюймовых Retina MacBook Pro жестких дисках по всему миру.
Выводы
Хочу быть понятым — я не считаю, что внешние зависимости являются признаком конца света.
Я просто думаю, что максимально важно, чтобы мы как сообщество начали заботиться о чистоте кода так же, как мы заботимся о крутых функциях и красивых логотипах.
Мы можем работать лучше. Мертвый код занимает пространство, съедает пропускную способность, и может даже убить твой стартап.
Я призываю вас посмотреть внутрь вашей папки /node_modules в следующий раз, когда у вас будет несколько свободных часов, и компьютер с 16 гигабайт оперативной памяти. Результаты могут вас просто удивить.
Автор: zapolnoch