- Браузерам бракує вбудованої підтримки функції require Node, тому npm-модулі в стилі CommonJS не можуть запускатися безпосередньо в JavaScript на стороні клієнта.
- Browserify аналізує файл запису, такий як main.js, виконує всі виклики require та об'єднує кожну залежність в один готовий для браузера JavaScript-файл.
- Встановлення модулів за допомогою таких команд, як npm install uniq, дозволяє Browserify витягувати пакети з node_modules та вбудовувати їх у згенерований bundle.js.
- Включення bundle.js через стандартний тег скрипта в HTML дозволяє модульному коду на основі npm безперебійно виконуватися в браузері як єдиний оптимізований ресурс.

Коли ви починаєте працювати з модулями JavaScript, однією з перших проблем, з якими ви стикаєтеся, є розрив між тим, як Node.js завантажує код, і тим, як це роблять браузери. У Node ви просто викликаєте require() і все магічним чином з'єднується. Але спробуйте те саме безпосередньо в браузері, і ви швидко виявите, що цієї функції там просто не існує. Саме тут інструменти, робочі процеси та концепції навколо браузера npm-пакетів та блендерів, таких як Browserify, вступають у справу, щоб врятувати становище.
У цій статті ви дізнаєтесь, як npm як екосистема пакетів поєднується з ідеєю перегляду, виявлення та, зрештою, об'єднання цих пакетів у пакети, щоб вони фактично працювали у веббраузері. Ми знову розглянемо класичний приклад на основі Browserify та пояснимо чому require працює в Node, але не в браузері, і крок за кроком покаже, як перейти від крихітного файлу скрипта до єдиного об'єднаного ресурсу, який можна вставити на веб-сторінку за допомогою простого тегу скрипта. По дорозі ми також надамо контекст, практичні поради та деякі сучасні альтернативи, щоб весь робочий процес мав сенс для реальних проектів.
Розуміння різниці між Node.js та браузером

Ключовою відправною точкою є те, що веббраузери та Node.js пропонують дуже різні системи модулів "з коробки". Node історично використовував формат модулів CommonJS, де залежності завантажуються за допомогою require('package-name') та розкрити функціональність за допомогою module.exportsЦей шаблон глибоко інтегрований у середовище виконання Node, але традиційні браузери нічого про нього не знають.
У звичайному середовищі браузера немає вбудованих require функція, а також немає підтримки модулів у стилі CommonJS, на які покладаються більшість npm-пакетів. Браузер розуміє класичні теги скриптів, які завантажують файли JavaScript глобально, а в сучасніших середовищах він підтримує модулі ES з... type="module" атрибут, але він все ще не розуміє самостійно семантику CommonJS Node.
Ця різниця стає проблемою, щойно ви намагаєтеся повторно використовувати код у стилі Node або npm-пакети безпосередньо всередині клієнтського JavaScript. У вас може бути простий фрагмент, наприклад var unique = require('uniq') це чудово працює в Node-скрипті, але якщо ви вставите той самий рядок у файл, завантажений у браузері, ви миттєво отримаєте помилку посилання, тому що require не визначено.
Тому розробникам потрібен певний «міст», який дозволить їм продовжувати писати звичний Node-подібний код, водночас надаючи ресурси, сумісні з браузером. Цей міст зазвичай є бундлером: інструментом, який переглядає ваш граф залежностей, починаючи з файлу запису, збирає все необхідне та виводить один JavaScript-пакет, який браузер може виконати, не знаючи нічого про Node чи npm.
Що робить Browserify в екосистемі npm
Browserify — один із перших і найвпливовіших інструментів, який вирішив саме цю проблему для розробників JavaScript. Його мета проста: дозволити вам писати код за допомогою Node. require шаблон, завантажте модулі з npm, а потім упакуйте все це в один файл, який працює в браузері так, ніби CommonJS підтримується нативно.
З точки зору перегляду npm-пакетів, Browserify ефективно перетворює гігантську екосистему пакетів Node на бібліотеку потенційних залежностей на стороні клієнта. Замість ручного копіювання скриптів, ви просто встановлюєте модуль з npm, використовуєте require() так само, як і в серверному коді, і покладатися на Browserify, щоб перевести його в щось, що браузери ваших користувачів можуть зрозуміти.
Внутрішньо Browserify обходить усі модулі, на які посилається через require, починаючи з заданого файлу записів, та будує граф залежностей. Для кожного модуля в цьому графі він переписує код у форму, яка емулює середовище CommonJS у браузері, включаючи локальне визначення області видимості та зручний для браузера вигляд. require реалізація. Кінцевим артефактом є окремий файл пакета, який зазвичай називають bundle.js, що інкапсулює всі ці модулі.
Кінцевим результатом є робочий процес, у якому фронтенд-розробники можуть покладатися на пакети з npm, не турбуючись про відсутність вбудованої підтримки модулів Node в браузері. Ви отримуєте доступ до величезного каталогу бібліотек для таких завдань, як маніпулювання даними, утиліти або допоміжні засоби інтерфейсу користувача, але все ще надаєте клієнту лише один файл скрипта, який плавно інтегрується в традиційні HTML-сторінки.
Переписування класичного прикладу навчального посібника з Browserify
Щоб усе було конкретніше, уявіть, що у вас є один JavaScript-файл з назвою main.js у вашому проєкті, і ви хочете використовувати npm-пакет під назвою uniq фільтрувати дублікати значень з масиву. У середовищі Node файл починається з такого рядка, як var unique = require('uniq')Цей рядок імпортує експортовану функцію з uniq модуль і зберігає його у змінній під назвою unique.
Усередині цього main.js файл, ви можете створити простий масив чисел, який містить повторювані записи. Наприклад, ви можете встановити var data = , де певні числа зустрічаються більше одного разу. Мета полягає в тому, щоб створити новий масив, який містить кожне число лише один раз, у відсортованому порядку.
Використовуючи імпортовану функцію, решта коду стає дуже простою. Ви можете викликати console.log(unique(data)) вивести на консоль масив, повернутий функцією uniq пакет, який усуває дублікати значень зі списку. Якщо ви запустите це в Node, ви побачите вихідний масив, у якому кожне число з'являється лише один раз.
Вся ця логіка передбачає, що uniq модуль доступний у вашому середовищі, і що require функція визначена та здатна її розв'язати. У Node це обробляється середовищем виконання та Алгоритм розв'язання вузлового модуля, який шукає каталог з назвою node_modules а потім для папки з назвою uniq всередині нього
Встановлення пакета uniq з npm
Перш ніж ваш код зможе викликати require('uniq'), вам потрібно фактично встановити пакет з реєстру npm. Це робиться з командного рядка за допомогою npm-клієнта, який постачається разом з Node.js. У папці вашого проекту ви можете виконати таку команду, як npm install uniq щоб npm завантажив модуль і зберіг його під node_modules каталог.
Команда npm install uniq інструкція отримує опубліковану версію uniq пакет і додає його до залежностей вашого локального проекту. Залежно від вашої конфігурації npm та від того, чи використовуєте ви package.json файл, він також може записати пакет у ваш список залежностей, забезпечуючи узгоджене встановлення в різних середовищах для інших розробників вашої команди.
Після встановлення пакета структура каталогів вашого проекту містить новий node_modules/uniq папка, що містить код цього пакета. Саме це дозволяє Node require система для визначення місця розташування модуля після його вирішення 'uniq'Цю ж папку Browserify перевірятиме, коли починатиме створювати граф залежностей для вашого пакета.
На даний момент ваш main.js Файл є цілком коректним кодом Node, який можна виконати на сервері або з терміналу за допомогою стандартного інтерпретатора Node. Однак, якщо ви просто відкинете це main.js файл на веб-сторінку за допомогою тегу скрипта, ваш браузер все одно не зрозуміє цей імпорт у стилі CommonJS, тому вам потрібен додатковий крок, щоб зробити його готовим для браузера.
Об'єднання main.js та його залежностей у bundle.js
Найважливішим кроком, який дозволяє цьому коду в стилі Node працювати в браузері, є дозвіл Browserify обробляти main.js та всі необхідні модулі, а потім генерують один JavaScript-файл, який зазвичай називається bundle.js. Ви можете зробити це з командного рядка після встановлення Browserify глобально або локально у вашому проекті.
Типова команда для запуску цього процесу може виглядати так browserify main.js -o bundle.js. Тут, browserify це виконуваний файл, який запускає процес пакетизації, main.js це файл входу, який Browserify розглядає як корінь графа залежностей, та -o bundle.js наказує інструменту записати результуючий пакет у файл з назвою bundle.js у поточному каталозі.
За лаштунками, Browserify аналізує main.js, йде за кожним require виклик знаходить та рекурсивно досліджує кожен імпортований модуль. Це включає ваші власні локальні файли, якщо вони вам потрібні з відносними шляхами, а також сторонні модулі, що знаходяться під node_modules, такі як uniq пакет, який ви щойно встановили з npm.
Кожна залежність, з якою стикається Browserify, трансформується, щоб вона могла працювати всередині браузера без потреби в рідному середовищі Node. Він огортає кожен модуль у власну область видимості, імітує інтерфейс CommonJS та об'єднує всі ці перетворені модулі в один скрипт. Отриманий результат bundle.js файл містить код, який імітує require функцію та дозволяє створювати ваші оригінальні var unique = require('uniq') рядок поводиться належним чином під час виконання на стороні клієнта.
Після завершення Browserify у вас залишається лише один JavaScript-файл, який фіксує логіку вашої оригінальної програми, а також усе дерево транзитивних залежностей, необхідне для її роботи. Тепер цей файл готовий для посилання на HTML-сторінці, як і будь-який інший скрипт, без додаткового налаштування з боку браузера.
Завантаження пакета Browserify на HTML-сторінку
З bundle.js згенеровано, інтеграція всього у звичайний веб-сайт така ж проста, як додавання одного тегу скрипта до вашого HTML-коду. Замість того, щоб намагатися завантажити main.js безпосередньо, ви посилаєтеся на скомпільований пакет, створений Browserify, який вже містить uniq та будь-які інші npm-модулі, які вам можуть знадобитися.
Базовий фрагмент HTML може містити щось на кшталт <script src="bundle.js"></script> десь перед закриттям </body> бирка. Цей тег скрипта повідомляє браузеру про завантаження та виконання bundle.js файл. Оскільки пакет емулює середовище CommonJS у собі, ваші виклики до require працювати внутрішньо, навіть якщо глобальне середовище браузера досі не має уявлення про те, що це за функція.
З точки зору сторінки, немає видимої різниці між цим пакетом та будь-яким іншим окремим JavaScript-файлом, який ви могли б включити. Складність модулів, внутрішні залежності та моделюваний require вся логіка інкапсульована всередині bundle.jsБраузеру потрібно завантажити лише один ресурс і запустити його, що також має переваги в продуктивності порівняно із завантаженням багатьох окремих невеликих файлів.
Завдяки цьому робочий процес добре вписується навіть у старі інтерфейси фронтенду, де ви можете працювати зі статичними HTML-файлами або шаблонами, що відображаються на сервері. Вам не потрібно радикально змінювати структуру сторінок; ви просто змінюєте спосіб підготовки JavaScript, який ви надаєте, замінюючи численні розрізнені ресурси та модулі Node-only оптимізованим пакетом, створеним Browserify.
Чому об'єднання з Browserify важливе для перегляду npm-пакетів
Коли люди говорять про «браузер npm-пакетів» або перегляд npm-пакетів для фронтенд-використання, основне питання зазвичай полягає в наступному: як я можу насправді використовувати цей модуль у браузерному проекті? Існування таких інструментів, як Browserify, перетворює теоретичний каталог серверних бібліотек на практичний набір інструментів, який можна застосовувати безпосередньо у ваших вебзастосунках.
На практиці це означає, що пошук корисних модулів у npm більше не обмежується роботою на Node або в бекенді. Якщо ви знайдете невелику утилітну бібліотеку, яка працює виключно на структурах даних JavaScript і не залежить від специфічних для Node API, є висока ймовірність, що ви зможете використовувати її в браузері, об'єднавши її з Browserify або подібним інструментом. Це значно розширює ваші можливості під час вирішення таких проблем, як дедуплікація масивів, перетворення даних або реалізація невеликих алгоритмів.
Крім того, групування зменшує кількість мережевих запитів, які ваша веб-сторінка має виконувати під час завантаження. Замість того, щоб додавати окремі теги скриптів для кожного локального файлу або віддаленої бібліотеки, все об'єднується в один bundle.js актив. Це чудово поєднується з HTTP-кешуванням і може спростити конвеєри розгортання, особливо коли ви маєте справу зі складними додатками, які залежать від багатьох npm-модулів.
З точки зору технічного обслуговування, можливість постійно покладатися на require а управління залежностями npm робить вашу кодову базу фронтенду більш передбачуваною та модульною. Ви встановлюєте, оновлюєте та видаляєте модулі за допомогою команд npm, централізовано перевіряєте залежності та дозволяєте Browserify обробляти трансформацію, необхідну для сумісності з браузером, замість ручного копіювання файлів або вбудовування стороннього коду за допомогою ad-hoc методів.
Зв'язок із сучасними інструментами JavaScript
Хоча класичний приклад, який ми розглянули, зосереджений саме на Browserify, фундаментальний шаблон, який він ілюструє, все ще лежить в основі багатьох сучасних інструментів для фронтенд-збірки. Новіші пакетери, такі як Webpack, Rollup, Parcel або Vite, також вирішують проблему перетворення модулів, написаних в одному стилі, в пакети, які браузери можуть ефективно виконувати.
Сучасні браузери тепер підтримують ES-модулі вбудовано через <script type="module">, що частково змінює картину, але не усуває потреби в кроках збірки з урахуванням npm. Багато пакетів в екосистемі npm все ще надають точки входу CommonJS або покладаються на роздільну здатність у стилі Node, і навіть коли доступні збірки модулів ES, пакетування залишається цінним для оптимізації, струшування дерев та послідовної поведінки завантаження.
У цьому ширшому контексті, невеликий приклад з використанням require('uniq'), npm install uniq і browserify main.js -o bundle.js команда — це більше, ніж просто тривіальний посібник. Він демонструє основний конвеєр «написати модульний код, встановити залежності з npm, а потім створити зручний для браузера пакет» – шаблон, який сьогодні поділяють майже всі серйозні фронтенд-проекти, навіть якщо конкретні інструменти відрізняються.
Розуміння того, як працює Browserify, таким чином полегшує міркування і про новіші стеки. Замість того, щоб ставитися до сучасних пакетів керування як до чорних скриньок, можна побачити схожість: всі вони читають файли записів, виконують імпорт або вимоги, збирають залежності, трансформують код і виводять пакети, які браузер завантажує за допомогою простих тегів скриптів. Екосистема пакетів npm, система модулів і пакетер разом створюють безперебійний досвід у щоденній розробці.
Об'єднання всього цього в практичному робочому процесі
Щоб підсумувати практичний робочий процес, що мається на увазі в оригінальному прикладі, ви починаєте з написання коду вашої програми у файлі, такому як main.js використання require імпортувати будь-які модулі npm, які ви хочете використовувати. У цьому файлі ви можете викликати var unique = require('uniq'), визначте масиви типу , та виводити результати в консоль. Концептуально, ви працюєте так, ніби все це працюватиме під керуванням Node.
Наступний крок — переконатися, що ці модулі дійсно існують у вашому проєкті, встановивши їх за допомогою npm, наприклад, через npm install uniq. Ця дія заповнює node_modules каталог, що надає Node та Browserify доступ до коду модуля, щоб його можна було вирішити та включити там, де це необхідно.
Після того, як ваш код та залежності налаштовані, ви даєте команду Browserify рекурсивно зібрати все, починаючи з вашого файлу запису, виконавши таку команду, як browserify main.js -o bundle.js. Цей процес проходить по дереву залежностей, обгортає кожен модуль, щоб імітувати середовище CommonJS у браузері, і нарешті записує bundle.js як єдиний об'єднаний файл, що містить весь необхідний код.
Зрештою, ви переходите до свого HTML-коду та посилаєтеся лише на цей єдиний вихідний файл за допомогою звичайного тегу скрипта, такого як <script src="bundle.js"></script>. На сторінці не потрібен спеціальний синтаксис; вся складність повністю знаходиться всередині пакета. Браузер завантажує та виконує bundle.js, а код усередині нього працює так, ніби require механізми були вбудовані в сам браузер.
Дотримуючись цього шаблону, ви ефективно скорочуєте розрив між системою модулів Node та середовищем браузера, продовжуючи користуватися перевагами величезної екосистеми пакетів npm. Ви переглядаєте пакети, встановлюєте їх, вимагаєте їх, а потім надсилаєте один оптимізований файл своїм користувачам, забезпечуючи керованість та ефективність як процесу розробки, так і середовища виконання.
З точки зору вищого рівня, поєднання npm, модулів у стилі Node та такого пакетера, як Browserify, перетворює розрізнену колекцію JavaScript-файлів на цілісний, готовий до роботи з браузером конвеєр ресурсів. Розробники можуть писати модульний код, покладатися на пакети, що підтримуються спільнотою, і все одно доставляти один скрипт на свої веб-сторінки, що робить сучасну розробку на JavaScript масштабованою та доступною для різних інструментів та середовищ.