Search
Write a publication
Pull to refresh

Comments 32

А потом этот минифицированный код вставят в spa, которое грузится по 5 секунд из-за картинок по 5 метров...

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

К тому же, картинки наверняка закэшируются при первой загрузке сайта, а вот бандл с JavaScript кодом будет обновляться регулярно.

Вы написали, что импорт полифиллов - ответственность потребителя 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, да и побыстрее будет

Вот только SWC будет всегда работать быстрее Terser'а в виду того, что написан он на Rust

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

Понял вас. Но судя по информации из Readme в репозитории, на который вы сами и сослались, прибегать к такому приему не стоит. Разработчики V8 подвергают критике применение практик, описываемых в OptimizeJS. И по мне так, если честно, разработчики V8 вызывают гораздо больше доверия, чем разработчик, прямым текстом говорящий в своем репозитории, что поддержка его библиотеки не планируется

Sign up to leave a comment.

Articles