Comments 32
А потом этот минифицированный код вставят в spa, которое грузится по 5 секунд из-за картинок по 5 метров...
И с этим ничего не поделать. Но ваша задача как разработчика NPM пакета - качественно сделать NPM пакет. И если разработчику конечного пакета в итоге объем своего бандла не важен, то окажется, что ваши усилия были за зря. Но в таком случае проблема долгой загрузки сайта будет на совести разработчика конечного продукта, т.к. вы сделали все возможное.
К тому же, картинки наверняка закэшируются при первой загрузке сайта, а вот бандл с JavaScript кодом будет обновляться регулярно.
Для этого просто делают lib.min.js доступной по cdn
Вы написали, что импорт полифиллов - ответственность потребителя NPM пакета. Имхо это на 100% относится и к минификации - незачем NPM пакет минимизировать. Минимизируют сам бандл конечного продукта
А ещё я написал, что минификатор не волшебный инструмент, и что если писать код определенным образом, минификатор сможет гораздо качественнее уменьшать размер выходного файла.
Кстати, так, к слову, мнение о том, что пакет должен минимизироваться разработчиком пакета подкрепляется и более авторитеными разработчиками. Например, разработчики React тоже таким занимаются
я уверен, что минификация неминифицированных пакетов намного эффективнее (в т.ч. благодаря дедупликации повторяющихся кусков кода - вы сами предлагаете копировать к себе функции из lodash, так вот если все разработчики будут это делать, а потом разными способами минимизировать, то бандлер не сможет это правильно дедуплицировать)
Почему в реакте выбрали другой путь - я полагаю, чтобы пользователь мог сделать 2 импорта в своём html
редко изменяющийся статичный реакт с cdn
часто меняющийся собранный бандл приложения без реакта
Такой подход может быть оправдан в ряде случаев. Но вашу маленькую либу никто не будет импортировать отдельным <script>
Отвечая на комментарий выше - вам бы следовало просто написать, что не нужно минифицировать свою либу, вот и всё. Если бы мне кто-то поставил либу, в которую невозможно быстро залезть и посмотреть исходники - я бы вероятно от неё отказался
По поводу исходников, я вашу мысль не понял. Вам же не кто не мешает их смотреть. Просто не нужно смотреть исходники в собранном файле. Он на то и собранный, что уже перестал быть исходником.
По поводу дедупликации тут можно порассуждать. Есть несколько проблем.
Самая важная - "если все разработчики начнут" - это очень серьезное условие. Все разработчики не начнут никогда. Например, ES6 вышел 7 лет назад, а некоторые разработчики все ещё под ES5 пишут.
С точки зрения минимизации кода, было бы благоприятнее всего, если все зависимости были внешними. Тогда бы дубликатов быть не могло. Но тут появляется проблема неудобства использования NPM пакетов - два NPM пакета могут использовать разные версии другого пакета. И разработчик конечного продукта совсем не должен решать подобные конфликты.
Проблема разных версий рождает ещё одну проблему. Если зависимость будет все-таки не внешней, и код будет встраиваться, но в разных пакетах будет встраиваться код разных версий пакетов, то как в таком случае быть? Здесь никак код сокращать нельзя.
К тому же даже если 2 функции будут целиком друг друга копировать "буковка-в-буковку", то не так уж просто будет избавиться от одной из них. Каждая функция в JavaScript - объект. А некоторые из них ещё и с собственным контекстом.
Поэтому вы предлагаете решение, которое потребует значительных доработок в инструментах по минификации кода, а также в головах если не всех то хотя бы большинства разработчиков. И это предложение по мне звучит слишком идеалистически.
По поводу исходников, я вашу мысль не понял
Допустим, я использую сторонний DatePicker. В любой современной IDE я могу быстро открыть его детали имплементации (node_modules/custompicker/DatePicker.js). Для небольших npm пакетов - исходный код является лучшей документацией.
Возможно, вы в своем пакете поставляете одновременно и исходники, и бандл - тогда вы молодец. Но если вы поставляете только minified.js + typings.d.ts, то это плохо. Когда мне потребуется взглянуть на имплементацию, придется идти на гитхаб и ещё там искать срез именно той версии, которая используется у меня
Понял вас. Вообще я считаю, что в выкладывании исходников всё-таки смысла нет. Достаточно прикладывать файл с типизацией, production версию пакета и development. Причем минифицированию должна подлежать только prod версия.
Ох как часто я негодую, когда вместо того, чтобы увидеть исходник мне открывается d.ts файл, а рядом нет исходника. И да, я угрюмый открываю github и ищу исходный код нужной мне функции. И ещё хочу дополнить, что тоже писал либу react native, использовал готовый starter template. Автор шаблона считает что папку с исходниками отправлять в npm нужно.
Вы можете негодовать, но у этого есть и обратная сторона. Мне приходилось разворачивать сайты на VDS с объем HDD в 500 Мбайт, и из-за того, что некоторые разработчики хранят в своем пакете нефункциональный код, мне приходилось прибегать к различным ухищрениям, чтоб сделать базовый `npm install`.
А ещё мне кажется, что исходники в принципе использоваться не должны. Какой смысл от отдельного пакета, если приходится лезть в его исходники, чтоб разобраться в том, как он работает?
Если в случае Reactа и можно довериться ребятам, что production-версия это та же development, без специально добавленных уязвимостей. То с noname библиотекой всё равно придётся делать аудит неминифицированного кода и использовать его, а не подготовленный автором библиотеки.
Я правильно понимаю, что вы делаете аудит всех NPM пакетов, что используются в проекте? В том числе и тех пакетов, что используются вашими пакетами? Т.е. буквально все пакеты в node_modules
Согласен, вставлю свои 5 копеек.
Как разработчик на Node.JS, иногда во время дебага приходится лазить в исходники других npm пакетов, чтобы понять что условно результат устраивает меня(да, гипотечески это решается тестированием, но от багов никто не застрахован). В таком случае достаточно будет перейти в github и там создать issue на функционал либы. Плюс если пользуетесь yarn,pnpm пакетными менеджерами у них есть функционал по патчингу пакетов что позволяет не ждать фикса вашего любимого\критически важного пакета. Минификация в этом случае будет наоборот мешать вам инспектировать проблему другой либы.
Скажу честно, как фронтенд разработчик даже не задумывался над такой проблемой. Но в целом я согласен с вами, минификация Node.JS файлов может быть неоправданна.
Хотя с другой стороны я говорил об использовании сразу 2 версий пакета - dev и prod. И дебаг было бы логично делать как раз в dev версии, которую минифицировать вовсе не обязательно.
Тогда вопрос на засыпку. Вы написали библиотеку, сделали 2 сборки. dev и prod.
Я как разработчик нашел вашу либу, по функционалу все круто, то что я искал. Пишу `<пакертный менеджер установи либу>`. А затем импортирую в свой проект.
получится как-то так:
// src/index.ts
import something from 'yourlib';
/// rest code
Вопрос. Какая тут сборка будет: dev или prod?
По хорошему библиотеку делать нужно так, чтобы разработчику задумываться о таком не пришлось. В моем примере, как я и сказал, у тех разработчиков, что используют Webpack, нужная версия подставится сама. Если они не пользуются Webpack, они наверняка знают о переменной NODE_ENV, которая нужна много для каких инструментов фронтенд разработчика. А если они и про нее не будут знать и загрузят таки код dev версии, они все ещё могут положиться на собственный минификатор.
Ваш ответ отличается от того, что будет в реальности. Если внимательно посмотреть на документацию к node.js в раздел про то как резолвятся зависимости из node_modules можно понять, что будет взят фаил исполняемый из "main" или "exports" package.json файла. Это значит, что если проект фронтедовский - там уже наверняка есть сборщик, который сминифицирует код как надо(например вебпак). Если проект на ноде, то с вероятностью 90% код не надо минифицировать, а если и надо, то скорее всего что-то не так и проблема в другом.
Получается Ваша статья лишена смысла, поскольку заниматься минифицированием это:
1) себе дороже, неблагодарный труд, особенно если библиотека и для node.js и для браузера
2) сборщик и так сминифицирует код (зачем дважды делать одно и тоже)
Не совсем понял, почему мой ответ отличается от реальности. Я в статье указал, что главный файл должен быть указан в package.json, и ответ я написал, опираясь на то, что вы уже осведомлены об этом правиле.
И все же я считаю, что в статье есть смысл. Не все люди знают как работают импорты, и таким людям я помог в этом разобраться. Механизм разделения сборок будет полезен даже в случае, если минификация будет проводиться исключительно в конечном продукте.
К тому же минификация пакета при разработке пакета и при разработке конечного продукта отличаются. Я описал, как сделать минификацию более качественно в рамках одной единицы кода - вашего пакета. Без помощи разработчика пакета, минификация будет менее качественной.
А если дело именно в Node.JS, то по поводу минификации пакета, используемого для него, я уже согласился, так что не понимаю, зачем вы в очередной раз пытаетесь доказать свою правоту.
уменьшить размер своей библиотеки с 1772 байт до 1594
а с включенным gzip какая разница? и если включен gzip (а он включен почти всегда и везде), то может и он function нет смысла отказываться?
оказалось, что Terser зачем-то генерирует лишние скобки для некоторых выражений
Может это оптимизация скорости парсинга наподобие такой? https://github.com/nolanlawson/optimize-js
Я бы предпочёл ускорение работы, чем экономию сотни байт)
Видимо, флаг wrap_func_args
у Terser автор не снял -)

Вот только SWC будет всегда работать быстрее Terser'а в виду того, что написан он на Rust
"ускорение работы" (за счёт дополнительных скобок) - это не про скорость минификации, а про скорость парсинга кода в браузере у конечного пользователя.
Понял вас. Но судя по информации из Readme в репозитории, на который вы сами и сослались, прибегать к такому приему не стоит. Разработчики V8 подвергают критике применение практик, описываемых в OptimizeJS. И по мне так, если честно, разработчики V8 вызывают гораздо больше доверия, чем разработчик, прямым текстом говорящий в своем репозитории, что поддержка его библиотеки не планируется
Экстремально уменьшаем размер NPM пакета