Всегда ли NPM лучше простой ссылки для распространения вашей библиотеки JS третьим лицам?

Я поделюсь несколькими предложениями о том, как разработать вашу интерфейсную библиотеку, чтобы упростить ее распространение среди партнеров / клиентов, и почему мы решили распространять большинство наших библиотек с использованием CDN вместо NPM.

Производительность веб-сайта очень важна, и чем тяжелее библиотека JS, тем хуже она повлияет на производительность. Внимательный и добросовестный разработчик откажется от всех библиотек, которые сильно влияют на вес страницы.
Преобразовать очень тяжелый оператор в конкретное количество килобайт непросто, потому что это зависит от проекта и его бюджета производительности.

Архитектура библиотеки

Чтобы снизить затраты на производительность наших библиотек, мы реализовали их как серию небольших и независимых модулей. Каждый модуль выполняет определенную роль в библиотеке.
В наших библиотеках всегда есть модуль начальной загрузки, очень легкий модуль (мы говорим о нескольких КБ), который просто содержит минимальную бизнес-логику. : он реализует метод библиотеки инициализации.
URL-адрес нашей библиотеки javascript, которая будет добавлена ​​на вашу веб-страницу, всегда указывает на модуль начальной загрузки.

Хорошим примером является Thron.js, наш JS SDK: он предоставляет методы и модели javascript, которые упрощают использование функций THRON, таких как создание мультимедийного контента, загрузки и общие компоненты UX). Thron.js имеет следующие модули:

  • вышеупомянутый модуль начальной загрузки, размер которого в основном зависит от полифиллов, необходимых для поддержки IE11;
  • «модуль Api», который предоставляет методы и модели javascript (например, создание содержимого из файла, получение всего содержимого из папки…);
  • «Компонентный модуль», он предоставляет все компоненты пользовательского интерфейса;
  • «Модуль отслеживания», используемый обоими модулями, описанными выше: он записывает взаимодействия пользователя.

На диаграмме выше мы показываем поток загрузки Thron.js. Если, например, вы хотите вызвать метод, будут загружены только модули начальной загрузки, API и отслеживания.
Все модули загружаются асинхронно с остальной частью страницы (сценарий будет выполняться, пока страница продолжает синтаксический анализ) чтобы иметь небольшое влияние или не оказывать никакого влияния на производительность страницы.
При принятии решения о том, следует ли и как разбивать библиотеку, мы обращаем внимание только на два момента:

  • Сбалансируйте количество модулей и их вес; если модуль слишком тяжелый (в нашем случае более 500 КБ без сжатия), рассмотрите возможность разделения его на более мелкие модули;
  • Не переусердствуйте с количеством модулей. Многие модули размером всего несколько КБ могут быть скорее недостатком, чем преимуществом, потому что накладные расходы HTTP и сети будут больше, чем время загрузки небольших файлов.

Вторым моментом может быть довольно сложно управлять, рассмотрим следующий пример: предположим, нам нужно реализовать библиотеку компонентов пользовательского интерфейса, состоящую из кнопки, флажка, ввода выбора и ввода текста. Если мы решим, что каждый элемент является отдельным модулем, подумайте, что произойдет, когда ваши пользователи захотят создать простую веб-форму для веб-страницы, используя все элементы пользовательского интерфейса из списка, для загрузки всех модулей потребуется 5 различных HTTP-запросов (один для bootstrap и по одному для каждого элемента пользовательского интерфейса). Это много соединений, которые будут открываться с одним и тем же доменом (скорее всего), и они будут учитываться при учете ограничения браузера: все браузеры реализуют ограничение одновременных подключений к одному и тому же домену, чтобы повысить скорость загрузки страницы при сохранении системных ресурсов. Увеличенное количество подключений повлияет на производительность страницы, а не улучшит ее.

Распространение вашей библиотеки среди партнеров и клиентов

Как было сказано в начале статьи, мы решили распространять наши библиотеки через CDN, и, говоря очень простым языком, это средство предоставить нашим клиентам и партнерам URL-адрес для нашей библиотеки javascript:

Мы знаем, что наиболее распространенный метод публикации библиотек javascript - через диспетчер пакетов, такой как NPM, но это последнее решение имеет для нас огромные ограничения: оно не позволяет нам исправить его! < br /> В идеальном мире распространение библиотеки через NPM имеет только преимущества, потому что разработчики клиентов / партнеров будут готовы обновить свою версию, исправить неработающий код (если таковой имеется) и развернуть новую, лучшую версию. К сожалению, это случается нечасто: иногда у вас есть заказчик, который полагается на внешнее агентство для разработки, и вся цепочка развертывания оказывается слишком длинной. Конечно, мы не можем (и не будем) брать на себя ответственность за какие-либо исправления, но возможность исправлять наши ошибки, не дожидаясь запуска всей цепочки развертывания, иногда является долгожданным дополнением.

Веб-проект, если он не является чрезвычайно простым, обычно создается с использованием сборщика модулей (например, Webpack или Parcel).
Оптимизированный сборщик модулей объединяет в один большой файл ( или в других файлах, называемых чанками) все файлы javascript вашего проекта, внешние библиотеки, поступающие из NPM (папка node_modules для тех, кто жует интерфейс) включены.
Когда это происходит, библиотека больше не в ваших руках, но включен, инкапсулирован в приложениях, которые его используют.

Обращение к своим клиентам / партнерам с просьбой об обновлении до новой версии - нетривиальная задача: клиент / партнер должен понимать, какие проекты затронуты, понимать, кто реализовал проект (возможно, это было сделано внешний консультант), поймите, сможете ли вы обновить его ... короче говоря, это определенно неприятность для наших партнеров / клиентов, которой мы хотим избежать!

Этот наш выбор также поддерживают многие другие важные бренды (например, Google, Facebook). Вот несколько примеров библиотек, выпущенных через CDN

При исправлении библиотеки существует риск регрессии, особенно если она не включена в известный нам код. Мы уменьшаем этот риск, обеспечивая управление версиями файлов библиотеки: как вы, возможно, уже заметили, мы используем номер версии в пути включения библиотеки, это позволяет нам «поднять» версию библиотеки каждый раз, когда мы знаем, что МОЖЕТ произойти некоторая регрессия. , это помогает нашим клиентам / партнерам сохранять полный контроль над обновлениями библиотек, как если бы они использовали NPM.

Структура конечной точки

Конечная точка наших библиотек всегда указывает на модуль начальной загрузки (точка входа в библиотеку, описанная выше) и следует этой структуре:

https: // ‹companyId› -cdn.thron.com/shared/lib/common/ ‹libName› / ‹libVersion› / ‹assetName› .js, где

  • ‹libName› соответствует имени библиотеки.
  • ‹libVersion› соответствует конкретной версии библиотеки.

Добавление версии библиотеки в URL-адрес очень важно, чтобы избежать регресса; если бы мы не использовали этот URL с версией, мог бы произойти следующий сценарий:

  1. Мы выпускаем библиотеку «lib / amazingLib / boot.js».
  2. Партнер добавляет библиотеку в свой проект и использует библиотечный метод «embed»
  3. Наша команда решила улучшить метод «встроить», изменив его. Бессознательно изменения нарушают партнерскую реализацию
  4. Библиотека выпущена в производство, и «lib / amazingLib / boot.js» указывает на последнюю версию библиотеки.
  5. Изменения распространяются на проект партнера…

Всегда следует помнить о двух правилах:

  1. У каждой версии библиотеки всегда должен быть соответствующий URL.
  2. URL-адрес, опубликованный в рабочей среде, всегда должен указывать на один и тот же javascript (за исключением важных исправлений безопасности, о которых необходимо сообщить вашему клиенту / партнеру).

Всегда ли лучший выбор - модульная архитектура с CDN-публикацией?

Наше практическое правило решить, распространять ли библиотеку через CDN или NPM, очень просто:

  • будет ли библиотека с открытым исходным кодом? Если да, используйте NPM;
  • предназначена ли библиотека для внутренних разработчиков компании? Если да, используйте NPM;
  • Готов ли заказчик / партнер принять задачу управления обновлениями библиотеки во ВСЕХ случаях? Если да, используйте NPM;
  • В любом другом случае используйте CDN.

Библиотеку, поставляемую через NPM, легче установить в проекте, который использует сборщик модулей (такой как ash Webpack или Parcel): мы используем NPM для наших внутренних библиотек или тех библиотек, которые используются просто как зависимости.

Чтобы ответить на первоначальный вопрос, ответ - НЕТ; Как обычно, вы должны выбрать подходящий инструмент для работы: мы любим NPM и используем его там, где это возможно!

Как вы управляете распространением библиотеки JS? Сообщите нам, если вы не согласны с нашим подходом и почему: мы будем рады обсудить это.