Опция absWorkingDir

В контексте работы с esbuild одна из ключевых деталей конфигурации, влияющих на разрешение путей и поведение входных/выходных файлов, — это параметр absWorkingDir. Несмотря на свою лаконичность, он определяет фундаментальный контекст выполнения сборки и напрямую влияет на интерпретацию всех относительных путей внутри конфигурации.


Назначение absWorkingDir

absWorkingDir задаёт абсолютную рабочую директорию, относительно которой esbuild интерпретирует все пути, указанные в конфигурации сборки:

  • входные файлы (entryPoints)
  • пути в outdir и outfile
  • относительные импорты модулей
  • плагины, работающие с файловой системой

Ключевая идея: esbuild перестаёт полагаться на текущую рабочую директорию процесса (process.cwd()), заменяя её явно заданной базой.


Поведение по умолчанию

Если absWorkingDir не указан, esbuild использует:

  • process.cwd() в Node.js-окружении
  • текущую директорию запуска CLI в случае командной строки

Это поведение кажется простым, но в реальных проектах приводит к неоднозначностям:

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

Сигнатура и тип

interface BuildOptions {
  absWorkingDir?: string;
}

Значение должно быть:

  • абсолютным путём
  • строкой в формате файловой системы ОС
  • существующей директорией (логически, но не обязательно проверяемо esbuild)

Основной эффект: фиксация контекста путей

При установке absWorkingDir все относительные пути начинают интерпретироваться так, как будто процесс всегда запущен из этой директории.

Пример:

import { build } from 'esbuild';

build({
  absWorkingDir: '/project',
  entryPoints: ['src/index.js'],
  outdir: 'dist'
});

Здесь:

  • src/index.js трактуется как /project/src/index.js
  • dist трактуется как /project/dist

Даже если команда запускается из /home/user или /tmp, поведение останется одинаковым.


Влияние на entryPoints

entryPoints — один из наиболее чувствительных параметров к рабочей директории.

Без absWorkingDir:

entryPoints: ['src/index.js']

может означать разные файлы в зависимости от:

  • каталога запуска Node.js
  • CI-системы
  • скриптов npm

С absWorkingDir:

absWorkingDir: '/project',
entryPoints: ['src/index.js']

всегда приводит к:

/project/src/index.js

Влияние на outdir и outfile

Для выходных параметров правило аналогичное:

outdir: 'dist'

интерпретируется как:

/project/dist

при установленном:

absWorkingDir: '/project'

Это особенно важно в следующих сценариях:

  • генерация артефактов в CI/CD
  • сборка внутри Docker-контейнеров
  • использование esbuild как библиотеки в монорепозиториях

Взаимодействие с модулями и импортами

Хотя absWorkingDir напрямую не участвует в резолвинге import, он задаёт базу, от которой строится разрешение относительных путей файловой системы.

Пример:

// /project/src/index.js
import './utils/math.js';

При:

absWorkingDir: '/project'

esbuild интерпретирует:

/project/src/utils/math.js

Это особенно важно для:

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

Монорепозитории и предсказуемость сборки

В монорепозиториях структура часто выглядит так:

repo/
  packages/
    app/
    lib/

Без фиксации absWorkingDir сборка может зависеть от:

  • текущего cwd пакета
  • запуска npm script
  • поведения CI runner

С absWorkingDir:

absWorkingDir: '/repo/packages/app'

вся сборка становится изолированной и повторяемой.


Взаимодействие с CLI

В CLI-режиме esbuild:

esbuild src/index.js --outdir=dist

по умолчанию использует текущую директорию терминала.

А эквивалент с фиксацией:

esbuild src/index.js --outdir=dist --abs-working-dir=/project

Позволяет запускать команду из любого места без изменения результата.


Использование в Docker

В контейнерных окружениях absWorkingDir часто становится критически важным.

Типичная проблема:

  • контейнер запускается с WORKDIR /app
  • скрипт запускается из другого слоя или entrypoint

Без фиксации:

  • пути начинают «плавать»
  • артефакты создаются вне ожидаемой директории

С установкой:

absWorkingDir: '/app'

сборка становится независимой от Docker-слоя запуска.


Плагины и файловая система

Многие плагины esbuild работают с путями напрямую:

onResolve({ filter: /.*/ }, args => {
  return {
    path: path.resolve(args.resolveDir, args.path)
  };
});

Здесь resolveDir вычисляется на основе текущего контекста сборки, который опирается на absWorkingDir.

Таким образом:

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

Частые ошибки при использовании

Использование относительного пути

absWorkingDir: './project'

Это некорректно в общем случае, потому что esbuild ожидает абсолютный путь. Такое значение может привести к:

  • разным результатам в разных средах
  • неожиданному резолвингу

Несоответствие с process.cwd()

Если одновременно используются:

  • process.cwd()
  • absWorkingDir

и логика проекта зависит от обеих величин, возникает рассинхронизация:

  • плагины используют одну базу
  • пользовательский код — другую

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

esbuild активно оптимизирован под повторяемые сборки. absWorkingDir усиливает эту характеристику:

  • одинаковые входные данные → одинаковый результат
  • отсутствие зависимости от среды запуска
  • стабильные пути в sourcemap и артефактах

Особенно важно для:

  • CI pipeline
  • кеширования сборок
  • распределённых билд-систем

Связь с sourcemap

При генерации sourcemap:

sourcemap: true

пути источников могут включать:

  • абсолютные пути
  • относительные пути

absWorkingDir влияет на базовую точку отсчёта, от которой формируются относительные пути в source map.

Результат:

  • более чистые и предсказуемые map-файлы
  • корректная привязка к исходникам в IDE

Резюме поведения

absWorkingDir определяет:

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

Его использование превращает сборку из «зависящей от запуска» в «детерминированную относительно проекта».