Перейти к основному содержимому
Неофициальный Бета-перевод

Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →

Как работает кеширование

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

По умолчанию хеш для команды, например lerna run test --scope=remixapp, включает:

  • Все исходные файлы remixapp и его зависимостей

  • Соответствующую глобальную конфигурацию

  • Версии внешних зависимостей

  • Значения среды выполнения, заданные пользователем (например, версию Node.js)

  • Флаги CLI-команды

computation-hashing

Это поведение настраивается. Например, линтеры могут зависеть только от исходного кода проекта и глобальных конфигов, а сборки — от dts-файлов скомпилированных библиотек вместо исходного кода.

После вычисления хеша задачи Lerna проверяет, выполнялась ли ранее точно такая же задача. Сначала проверяется локальный кеш, затем — удалённый (если он настроен и локальной записи нет).

Если результат найден, Lerna воспроизводит его: размещает нужные файлы в правильных каталогах и выводит сохранённый лог терминала. Для пользователя команда выполняется так же, но значительно быстрее.

cache

Если соответствия не найдено, Lerna выполняет задачу, сохраняя выходные данные и логи терминала локально (и в удалённом кеше, если настроено). Весь процесс прозрачен и не требует вашего вмешательства.

Хотя концепция проста, Lerna оптимизирует процесс для удобства. Например:

  • Захватывает stdout и stderr для идентичного воспроизведения вывода (включая Windows)

  • Минимизирует операции ввода-вывода за счёт запоминания расположения файлов

  • Показывает только релевантный вывод при работе с большими графами задач

  • Предоставляет инструменты для диагностики промахов кеша и другие оптимизации

По мере роста рабочего пространства граф задач выглядит так:

cache

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

Исходный код как входные данные для хеширования

Результат сборки/тестирования приложения или библиотеки зависит от её исходного кода и всех связанных зависимостей (прямых и косвенных).

По умолчанию Lerna использует консервативный подход. Например, при выполнении lerna run test --scope=remixapp учитываются ВСЕ файлы в remixapp, header и footer (зависимости remixapp). Это может вызывать излишние промахи кеша — например, изменение spec-файла в footer не влияет на тесты.

Более точная конфигурация может выглядеть так:

ПРИМЕЧАНИЕ: "{projectRoot}" и "{workspaceRoot}" – специальные синтаксические конструкции, которые интерполируются раннером задач при выполнении команды. Не заменяйте их фиксированными путями – это снижает гибкость конфигурации.

nx.json
{
"namedInputs": {
"default": ["{projectRoot}/**/*"],
"prod": ["!{projectRoot}/**/*.spec.tsx"]
},
"targetDefaults": {
"build": {
"inputs": ["prod", "^prod"]
},
"test": {
"inputs": ["default", "^prod", "{workspaceRoot}/jest.config.ts"]
}
}
}

При такой конфигурации скрипт сборки будет учитывать только нетекстовые файлы remixapp, header и footer. Скрипт тестирования будет учитывать все исходные файлы тестируемого проекта и только нетекстовые файлы его зависимостей. Скрипт тестирования также учтёт конфигурационный файл jest в корне рабочего пространства.

Входные данные хеша среды выполнения

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

nx.json
{
"targetDefaults": {
"build": {
"inputs": [{ "env": "MY_ENV_NAME" }, { "runtime": "node -v" }]
}
}
}

Входные данные хеша аргументов

Наконец, помимо входных данных хеша исходного кода и среды выполнения, Lerna учитывает аргументы командной строки. Например, команды lerna run build --scope=remixapp и lerna run build --scope=remixapp -- --flag=true дают разные результаты.

Важно: только флаги, переданные непосредственно в npm-скрипты, влияют на результат вычислений. С точки зрения кэширования следующие команды идентичны.

npx lerna run build --scope=remixapp
npx lerna run build --ignore=header,footer

Другими словами, Lerna кэширует не то, что разработчик вводит в терминал, а результат выполнения команды.

При сборке/тестировании/линте… нескольких проектов каждый процесс имеет собственный хеш и будет либо извлечён из кэша, либо запущен. Это означает, что с точки зрения кэширования команда:

npx lerna run build --scope=header,footer

идентичны следующим двум командам:

npx lerna run build --scope=header
npx lerna run build --scope=footer

Что кэшируется

Lerna работает на уровне процессов. Независимо от инструментов сборки/тестирования/линтера результаты кэшируются.

Lerna устанавливает хуки для сбора stdout/stderr перед запуском команды. Весь вывод кэшируется и воспроизводится при попадании в кэш.

Lerna также кэширует файлы, сгенерированные командой. Список файлов/папок указывается в свойстве outputs файла package.json проекта:

ПРИМЕЧАНИЕ: "{projectRoot}" и "{workspaceRoot}" – специальные синтаксические конструкции, которые интерполируются раннером задач при выполнении команды. Не заменяйте их фиксированными путями – это снижает гибкость конфигурации.

E.g. packages/my-project/package.json
{
"nx": {
"targets": {
"build": {
"outputs": ["{projectRoot}/build", "{projectRoot}/public/build"]
}
}
}
}

Если свойство outputs для цели не определено в package.json проекта, Lerna проверит раздел targetDefaults в nx.json:

nx.json
{
...
"targetDefaults": {
"build": {
"dependsOn": [
"^build"
],
"outputs": [
"{projectRoot}/dist",
"{projectRoot}/build",
"{projectRoot}/public/build"
]
}
}
}

Если ни один вариант не задан, Lerna по умолчанию кэширует папки dist и build в корне репозитория.

Пропуск кэша

Иногда требуется обойти кэш. Например, при замере производительности команды используйте флаг --skip-nx-cache, чтобы пропустить проверку кэша вычислений.

npx lerna run build --skip-nx-cache
npx lerna run test --skip-nx-cache

Дополнительная конфигурация

Дополнительные способы настройки задач и кэширования описаны в документации Nx.