Множественные точки входа

В Webpack конфигурация entry может принимать не только строку, но и объект, позволяющий задать несколько независимых точек входа для одного проекта. Такой подход используется в приложениях с несколькими страницами, административных панелях, микрофронтендах и любых системах, где логика разбивается на изолированные части.

Объектная форма entry

При использовании нескольких точек входа конфигурация превращается из линейной в структурированную:

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js',
    admin: './src/admin.js'
  }
};

Каждое свойство объекта становится отдельным графом зависимостей. Webpack строит для каждого entry свой набор модулей, начиная с указанного файла и рекурсивно добавляя все зависимости.

Ключи объекта (home, about, admin) определяют имена будущих бандлов.

Формирование выходных файлов

При множественных entry важно корректно задать шаблон именования:

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js'
  },
  output: {
    filename: '[name].bundle.js',
    path: __dirname + '/dist'
  }
};

Плейсхолдер [name] подставляет ключ из объекта entry. В результате формируются:

  • home.bundle.js
  • about.bundle.js

Без использования шаблона Webpack перезапишет файл, и останется только последний сборочный результат.

Независимые графы зависимостей

Каждая точка входа строит собственный dependency graph. Это означает:

  • модули могут не пересекаться вовсе;
  • одни и те же библиотеки могут быть включены в разные бандлы;
  • возможны дублирования кода без дополнительной оптимизации.

Например, если и home.js, и about.js используют lodash, то без специальных настроек библиотека попадёт в оба бандла отдельно.

Проблема дублирования кода

При масштабировании проекта множественные entry быстро приводят к повторному включению одинаковых зависимостей. Это увеличивает размер сборки и ухудшает загрузку.

Типичный сценарий:

// home.js
import _ from 'lodash';

// about.js
import _ from 'lodash';

В результате:

  • home.bundle.js содержит lodash
  • about.bundle.js содержит lodash

Выделение общих модулей

Для устранения дублирования используется оптимизация splitChunks:

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js'
  },
  optimization: {
    splitChunks: {
      chunks: 'all'
    }
  }
};

Webpack автоматически анализирует пересечения модулей и выносит общие зависимости в отдельный файл.

Общий vendor-бандл

Часто используется более контролируемый вариант:

optimization: {
  splitChunks: {
    cacheGroups: {
      vendors: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all'
      }
    }
  }
}

Такой подход формирует отдельный vendors.js, содержащий библиотеки из node_modules, что позволяет:

  • кэшировать сторонние зависимости отдельно от приложения;
  • уменьшить размер страниц;
  • избежать повторной загрузки одинаковых библиотек.

Runtime chunk и стабильность кэша

При множественных entry возникает проблема изменения хешей даже при небольших правках. Для стабилизации используется runtimeChunk:

module.exports = {
  optimization: {
    runtimeChunk: 'single'
  }
};

Webpack выносит runtime-логику в отдельный файл, который управляет загрузкой модулей. Это позволяет:

  • уменьшить количество изменений в основных бандлах;
  • улучшить долгосрочное кэширование;
  • снизить количество повторных загрузок.

Множественные страницы (MPA подход)

Наиболее распространённый сценарий множественных entry — мультистраничные приложения.

Структура проекта:

src/
  home.js
  about.js
  admin.js
  shared/
    utils.js

Конфигурация:

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js',
    admin: './src/admin.js'
  },
  output: {
    filename: '[name].[contenthash].js',
    path: __dirname + '/dist',
    clean: true
  }
};

Каждая страница получает собственный JS-бандл, что соответствует классической серверной модели рендеринга.

Интеграция с HTMLWebpackPlugin

При множественных entry важно связать каждый бандл с соответствующей HTML-страницей:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    home: './src/home.js',
    about: './src/about.js'
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'home.html',
      chunks: ['home']
    }),
    new HtmlWebpackPlugin({
      filename: 'about.html',
      chunks: ['about']
    })
  ]
};

Каждый HTML-файл подключает только свой набор скриптов.

Изоляция логики между entry

Множественные entry по своей природе изолируют код, но важно учитывать:

  • глобальные состояния могут пересекаться через window;
  • общие модули должны быть явно вынесены;
  • события и подписки между страницами не существуют.

Такой подход хорошо подходит для:

  • административных панелей;
  • лендингов;
  • многостраничных сайтов;
  • разделённых доменов функциональности.

Динамическое использование entry

Хотя Webpack чаще конфигурируется статически, entry можно формировать программно:

const pages = ['home', 'about', 'admin'];

module.exports = {
  entry: pages.reduce((config, page) => {
    config[page] = `./src/${page}.js`;
    return config;
  }, {})
};

Это удобно при генерации конфигурации на основе файловой структуры.

Разделение по функциональным зонам

Множественные entry часто отражают архитектуру приложения:

  • пользовательская зона (home, profile)
  • административная зона (admin, dashboard)
  • публичные страницы (about, contact)

Каждая зона может иметь собственный набор зависимостей и стратегию загрузки.

Влияние на производительность

Использование нескольких entry влияет на поведение загрузки:

Положительные эффекты:

  • параллельная загрузка скриптов;
  • кэширование по страницам;
  • уменьшение размера отдельных бандлов.

Отрицательные эффекты при неправильной настройке:

  • дублирование библиотек;
  • увеличение общего объёма загрузки;
  • сложность управления зависимостями.

Связь с ленивой загрузкой

Множественные entry не заменяют dynamic import, но могут сочетаться с ним:

  • entry отвечает за стартовые точки;
  • lazy loading отвечает за вторичные модули.

Пример разделения:

  • home.js — базовая логика страницы
  • home динамически загружает модули при необходимости

Типичные ошибки при работе с entry

Одной из распространённых проблем является попытка использовать один и тот же entry для разных страниц без разделения чанков. Это приводит к:

  • неконтролируемому росту бандла;
  • невозможности кэшировать отдельные части;
  • смешиванию логики разных страниц.

Другой частый случай — отсутствие chunks в HTMLWebpackPlugin, из-за чего все скрипты подключаются ко всем страницам.

Стратегия организации проекта

При проектировании структуры с множественными entry обычно применяют следующие принципы:

  • один entry — одна логическая область;
  • минимизация пересечений между entry;
  • обязательное выделение shared-логики;
  • использование splitChunks для автоматической оптимизации;
  • явное сопоставление entry и HTML.

Такой подход обеспечивает предсказуемость сборки и упрощает масштабирование приложения.