Комментарии 18
Вот вам причины почему это не случится никогда.
Вредоносная версия пакета уроет не один а множество сайтов.
JS пакеты едят диск как не в себя, а браузеры и так много ресурсов потребляют.
Вебсайт сломался потому что пакетный менеджер сломался.
На этот вебсайт можно зайти только с эджа т.к. только у него "правильный пакетный менеджер (тм)".
Во времена JQuery куча сайтов тянули его с официального CDN, так что можно сказать что идея уже устарела т.к. почему-то так больше не делают.
Вредоносная версия пакета уроет не один а множество сайтов.
Пакеты с версией кэшируются локально (т.е., в браузере). Новая версия пакета уроет множество сайтов, которые используют именно эту, новую, версию. Есть вариант, что в центральном хранилище, типа npmjs подменят уже ранее версионированный пакет, но он маловероятен. Опять же в локальном кэше браузера лежат "правильные" старые версии. В общем, этот момент в браузерах кардинально не отличается от серверной версии пакетного менеджера.
JS пакеты едят диск как не в себя, а браузеры и так много ресурсов потребляют.
А типа, когда они кэшируют тот же jQuery по 10 раз в разных бандлах разных сайтов, это лучше?
Вебсайт сломался потому что пакетный менеджер сломался.
или браузер сломался, или интернет отвалился, или ОСь пала... Чаще сайты ломаются из-за кривого скрипта в них самих, чем из-за ошибок браузера.
На этот вебсайт можно зайти только с эджа т.к. только у него "правильный пакетный менеджер (тм)".
Чё-т как-то за уши притянуто. package.json
работает и с npm, и с yarn.
Во времена JQuery куча сайтов тянули его с официального CDN, так что можно сказать что идея уже устарела т.к. почему-то так больше не делают.
Для пет-проектов и небольших сайтов - сгодится. Но
почему-то так больше не делают
Потому что крупные проекты думают ещё и о безопасности, выставляя Content-Security-Policy как минимум.
npmjs подменят уже ранее версионированный пакет, но он маловероятен
Потому что крупные проекты думают ещё и о безопасности, выставляя Content-Security-Policy как минимум.
Это хорошо, но не отменяет того факта, что крупные проекты делаются из модулей, которые хранятся в пакетах, имеют свои зависимости и как-то должны менеджироваться. Либо каждым проектом в отдельности, либо всё-таки можно будет договориться и доверять какому-то источнику, типа npmjs.com. По факту, исходники с него-то и тянутся, потом билдятся, а потом уже выставляют полиси.
и тем не менее, пакетами пользоваться не перестали. Выводы сделали, ошибки исправили и продолжают.
Для сборки бандла небольшого фронтенда качается пакетов на несколько гигабайт, сборка занимает от минут до получаса, в зависимости от железа и размера кодовой базы и всех зависимостей - и всё это собирается в небольшой оптимизированный файл или несколько. И даже при этом браузерам временами не легко всё это выполнять без тормозов. А Вы хотите половину этого процесса ещё в браузерах запускать: десктопные варианты на мощных ПК ещё потянут, а мобильные чет мне кажется не очень, да ещё и гигабайты кэша пакетов надо где-то хранить.
Я думал о браузерных пакетах, как о результатах сборки, а не как об исходниках для сборки. Сборка делается на сервере разраба, а в центральный репо помещается уже собранный пакет. Примерно так сейчас и происходит, но только без браузера (загляните в каталог ./dist/
).
Это какие-то полумеры, в папке dist такие-же собранные бандлы. Тогда надо зависимости зависимостей так-же подключать пакетами.
Справедливо. Понятно, что пакетный менеджер для браузера не может быть один в один, как серверный пакетный менеджер. Но направление движения верное - делается пакет для работы в браузере и определяются зависимости на другие пакеты, собранные для работы в браузере. Можно начать с пакетов без зависимостей. С того же jQuery, хотя бы. Можно даже заморочится версиями ES6/CJS вдобавок.
А может не надо делать ещё одну операционку внутри другой? Может всё же делать клиентские приложения нативными? А сайты оставить сайтами?
Вообще такая технология есть и ей лет 15-20 - называется IFRAME. Вставляете IFRAME со всеми нужными политиками безопасности на свои страницы. Тот грузит скрипты внутри себя. Далее получаете ссылку на объект window этого iframe (через свойство iframe.contentWindow) И вперед.
А вообще, общий кеш в браузере вряд ли будет, в первую очередь по причине безопасности. Например, с такой технологией подключить к вредоносному сайту банковский скрипт с данными станет легко, даже куки не надо воровать.
Ресурсы, такие как unpkg.com и jsdelivr.com, в некоторой степени помогают уменьшить дублирование, поскольку если несколько сайтов ссылается на один и тот же ресурс на unpkg.com, то все они будут использовать один и тот же объект из кэша браузера.
Как они помогают? Я бы еще могу согласиться в том случае, если бы речь шла о загрузке таких скриптов через IFRAME. Вот в таком случае мы точно с вами могли бы говорить об экономии трафика. А если идет речь об идентичных прямых ссылках на внешний скрипт на различных сайтах, то кэширование будет распространяться на каждый отдельный ресурс. Посещая таких 2 сайта, идентичный файл библиотеки вы скачаете 2 раза.
почему бы не хранить npm‑пакеты (или хотя бы транспилированные значимые объекты кода) прямо в браузере, учитывая версионность и другие свойства, присущие пакету?
Да никто и сейчас Вам не мешает это делать даже без бандлеров и хранить в браузере. Есть прекрасный механизм import maps, который по сути является картой импортов. Эту карту импортов можно и в ручную писать, если есть надобность, а так видел на npm пакет, который конвертирует package.json в карту.
А если идет речь об идентичных прямых ссылках на внешний скрипт на различных сайтах, то кэширование будет распространяться на каждый отдельный ресурс. Посещая таких 2 сайта, идентичный файл библиотеки вы скачаете 2 раза.
Да, кэширование в разные origin'ы одного и того же ресурса идёт раздельно. Так тем более есть смысл какие-то вещи (такие, как код библиотек) хранить в браузере централизованно.
А вообще, общий кеш в браузере вряд ли будет, в первую очередь по причине безопасности.
Так ведь речь на за общий кэш, а за менеджер пакетов. Мы же и так тянем одни и те же пакеты через npm при сборке. А потом один и тот же код пихаем в свои собственные бандлы, которые кэшируются раздельно под каждый origin, типа это секьюрно. А то, что по итогу в раздельные кэши попадает одна и та же библиотека из npm'а, так то такое.
Есть прекрасный механизм import maps, который по сути является картой импортов.
Надо будет его пощупать поближе. С первого раза он мне как-то не показался.
Не совсем понял, чем это будет принципиально отличается от использования unpkg/jsdelivr. Если хочется именно в одном отдельном файле это хранить, можно сделать себе vendor.js, в котором импортировать их с cdn и ре-экспортировать.
Как тут уже указывали, браузер хранит кэш раздельно для каждого origin (схема://домен:порт). Если на одну и ту же картинку (например, аватар на gravatar.com) ссылаются различные сайты, то браузер будет кэшировать эту картинку для каждого сайта. Ну, вот так устроен мир (вернее, браузер).
В целом мотивы поведения вполне понятны - ресурс может для разных сайтов выдаваться по-разному. В зависимости от того, кто его запрашивал. Поэтому и кэшировать его нужно также с привязкой к origin. Вот и получается, что одни и те же ресурсы кэшируются множество раз на одном и том же браузере. Даже если в месте раздачи они постоянны и не изменяются в зависимости от запрашивающего.
С кодом вообще беда. Когда мы собираем бандлы, мы заталкиваем в них одни и те же библиотеки с npmjs.com (если нам нужна единая точка внедрения/отказа, то она у нас уже есть). А затем этот код в составе бандла закачивается на клиента и кэшируется браузером. Вот и получается, что тот же jQuery в кэш ложится не один раз, а несколько десятков, а то и сотен. В том числе и поэтому профиль Хрома и занимает гигабайты (у меня 3.5 Г в ~/.config/google-chrome
).
Раз уж мы всё равно тянем исходники из npm-пакетов (единого репозитория), то почему бы не вынести менеджер пакетов на уровень самого браузера и не замкнуть его на аналогичный репозиторий? Только не npm-пакетов, а браузерных. Сбилдили разрабы jQuery новую версию для браузера, выложили её в этот репо, а все остальные в своём коде ссылаются на нужную им версию. То же самое, что и сейчас, только без всяких посредников в виде webpack'а и npm.
Как тут уже указывали, браузер хранит кэш раздельно для каждого origin (схема://домен:порт).
Не учел, спасибо. Правда, утверждается, что это, в первую очередь, защита от трекинга - по тому, насколько быстро загрузился ресурс, можно понять, был ли он уже в кеше, и использовать это как маркер. Как эта проблема будет решаться в случае с единым репозиторием? По набору пакетов и их версий в кеше, подозреваю, можно неплохой такой fingerprint составить.
"Сложные задачи имеют более одного правильного решения, оптимальность которых зависит от применяемых критериев оценки." (с) и "Каждому решению присуще сожаление" (с) :) Кому-то важнее секьюрность, кому-то скорость, кому-то размер. Лично я не вижу проблем, если кто-то узнает, что у меня в кэше лежат программные файлы, относящиеся к gmail, shopify, mail.ru, habr, reddit и т.п. На край, можно сделать как в FF с разделением кэша - сделать использование менеджера пакетов настраиваемым.
Кстати, если вас волнует размер профиля, то разделение кешей можно полностью или частично отключить на уровне браузера. Как минимум в Firefox: https://developer.mozilla.org/en-US/docs/Web/Privacy/State_Partitioning#exempt_specific_origins_from_partitioning. Но, понятное дело, это влечет те самые потенциальные проблемы с трекингом.
Появится ли в браузере менеджер пакетов?