Loader text

Механизм loaders в esbuild определяет способ интерпретации импортируемых файлов в процессе сборки. Loader text предназначен для преобразования содержимого файлов в строковые значения, которые становятся частью итогового JavaScript-бандла без дополнительной обработки синтаксиса или компиляции.

Семантика text-loader

Loader text рассматривает любой подключаемый файл как обычный текстовый ресурс. При сборке содержимое файла:

  • считывается как UTF-8 строка
  • экспортируется как строковое значение
  • не подвергается парсингу как JavaScript, JSON или иной структурированный формат

Фактически каждый импорт превращается в константу-строку внутри модуля.

Пример поведения:

import template from './template.html'

console.log(template)

При использовании text loader файл template.html не интерпретируется как HTML-структура. Его содержимое вставляется в JavaScript как строка.


Настройка loader text

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

import * as esbuild from 'esbuild'

esbuild.build({
  entryPoints: ['src/index.js'],
  bundle: true,
  loader: {
    '.txt': 'text',
    '.html': 'text',
    '.md': 'text'
  },
  outfile: 'dist/bundle.js'
})

CLI-аналог:

esbuild src/index.js --bundle --loader:.txt=text --loader:.html=text --outfile=dist/bundle.js

Каждое расширение явно привязывается к loader text, что позволяет контролировать типы ресурсов на уровне конфигурации сборки.


Поведение в итоговом бандле

При использовании text-loader содержимое файла инлайнится прямо в код. Например:

Файл greeting.txt:

Hello world
This is a sample text

Код:

import greeting from './greeting.txt'

export function show() {
  return greeting.toUpperCase()
}

Результат после сборки:

var greeting = "Hello world\nThis is a sample text\n";

export function show() {
  return greeting.toUpperCase();
}

Строка становится обычной переменной, доступной для дальнейших операций.


Отличие от других loaders

text vs file

Loader file:

  • копирует файл в output директорию
  • возвращает URL/путь к ресурсу

Loader text:

  • не создаёт отдельный файл
  • встраивает содержимое в бандл

Разница принципиальна для архитектуры приложения: file сохраняет внешний ресурс, text делает его частью кода.


text vs dataurl

Loader dataurl:

  • кодирует файл в base64
  • формирует Data URI

Loader text:

  • оставляет исходный текст без кодирования
  • сохраняет читаемость и минимизирует накладные расходы

text vs json

JSON loader:

  • парсит структуру
  • возвращает объект

text loader:

  • не интерпретирует содержимое
  • возвращает сырую строку

Пример различия:

import data from './config.json'   // объект
import raw from './config.json'    // строка (при text loader)

Области применения

Шаблоны разметки

HTML-фрагменты часто используются как шаблоны UI:

import modalTemplate from './modal.html'

export function createModal() {
  const container = document.createElement('div')
  container.innerHTML = modalTemplate
  return container
}

Такой подход позволяет хранить разметку отдельно, не вводя HTML-парсинг на этапе выполнения.


Markdown и документация

Markdown-файлы удобно загружать как текстовые ресурсы:

import readme from './README.md'

document.body.innerText = readme

Использование text-loader исключает необходимость дополнительного парсера и упрощает пайплайн сборки.


Шейдеры и графика

GLSL и другие shader-языки часто подключаются как строки:

import vertexShader from './shader.vert'
import fragmentShader from './shader.frag'

gl.shaderSource(program, vertexShader)

Text loader позволяет хранить графические программы без преобразования структуры.


Особенности обработки символов

Loader text сохраняет:

  • переносы строк
  • пробелы
  • специальные символы
  • UTF-8 символику

Однако важно учитывать экранирование при встраивании:

  • символ " преобразуется в \"
  • обратные слеши \ дублируются
  • строки нормализуются для безопасного JavaScript-формата

Инлайнинг и оптимизация

Esbuild автоматически оптимизирует текстовые ресурсы:

  • удаляет избыточные escape-последовательности
  • объединяет строки при tree-shaking
  • минимизирует размер итогового бандла при включённой minify

Пример минификации:

var t = "line1\nline2\nline3";

Ограничения использования

Loader text не предназначен для:

  • структурированных данных с частым доступом (лучше JSON)
  • бинарных ресурсов (лучше base64 или file loader)
  • больших файлов, критичных к размеру бандла

Особенно важно учитывать влияние на bundle size: каждый текстовый ресурс увеличивает размер итогового JS.


Поведение в ESM и CJS окружениях

В ESM:

import text from './file.txt'

В CommonJS:

const text = require('./file.txt')

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


Интеграция с другими настройками esbuild

Loader text часто комбинируется с:

  • bundle: true для инлайнинга зависимостей
  • minify: true для сокращения строк
  • charset: utf8 для корректной обработки символов
  • platform: node|browser в зависимости от окружения

Паттерны использования в архитектуре

Embedded assets pattern

Текстовые ресурсы становятся частью модуля:

module
 ├── code.js
 ├── template.html → text loader
 └── styles.css → text loader

Все ресурсы собираются в единый граф зависимостей.


Static injection pattern

import sql from './query.sql'

export function run(db) {
  return db.exec(sql)
}

SQL-запросы хранятся как текст, исключая необходимость runtime-загрузки файлов.


Поведение при watch-режиме

В режиме watch изменение текстового файла:

  • вызывает пересборку модуля
  • обновляет строковый экспорт
  • не требует перезапуска процесса

Это делает loader удобным для разработки шаблонов и статических ресурсов.


Влияние на tree-shaking

Text loader сам по себе не участвует в tree-shaking содержимого файла, поскольку файл уже становится атомарной строкой. Однако:

  • импорт неиспользуемых текстовых ресурсов удаляется
  • строка включается только при реальном использовании экспорта

Совместимость с плагинами

Plugins esbuild могут перехватывать обработку файлов до применения loader. В случае text-loader:

  • plugin может переопределить содержимое
  • может заменить файл динамически сгенерированной строкой
  • может применять трансформации (например, шаблонизацию)

Типичные ошибки использования

  • подключение больших логов или дампов данных → раздувание бандла
  • использование text-loader вместо JSON → потеря структуры данных
  • попытка интерпретации результата как объекта → логическая ошибка выполнения
  • смешивание с бинарными ресурсами → некорректная кодировка