- Как устранить ограничения длины пути к APK React Native в Windows -
1. Краткое содержание
В Windows сборка APK для приложения React Native на основе Expo CNG может завершиться ошибкой следующим образом.
ninja: error: Stat(...): Filename longer than 260 characters
Эта проблема вызвана не кодом приложения, а ограничениями Windows на длину пути и структурой путей артефактов нативной сборки, создаваемых CMake/Ninja.
Рекомендуются следующие три решения.
-
Создайте Junction в корне проекта, чтобы сократить путь, используемый для запуска сборки.
-
Переместите buildStagingDirectory CMake в короткий абсолютный путь.
-
Удалите существующий кэш .cxx и выполните полную пересборку.
Junction 생성 → buildStagingDirectory 지정 → android/app/.cxx 삭제 → 재빌드
subst Виртуальные диски, созданные с помощью , могут сократить пути, но их использование не рекомендуется, поскольку пути Metro, realpath и кэша Gradle могут смешаться и вызвать другие проблемы.
2. Причина
Общее ограничение длины пути Win32 в Windows — MAX_PATH, то есть 260 символов. Даже если поддержка длинных путей в Windows включена, инструменты, не подготовленные для использования этой функции, всё равно могут завершаться ошибкой при обработке длинных путей.
Новая архитектура React Native или автоматически подключаемые нативные модули собирают код C++ с помощью CMake и Ninja. В этом процессе пути к объектным файлам могут стать чрезвычайно длинными.
<빌드 스테이징 경로>/<빌드 타입>/<해시>/<ABI>/
<target>_autolinked_build/CMakeFiles/<target>.dir/
<원본 소스 경로를 포함한 경로>
В частности, длинные пути к исходным файлам C++ в каталоге node_modules снова включаются в пути к объектным файлам. Если путь к проекту имеет много уровней вложенности и добавляются такие нативные пакеты, как react-native-screens, safe-area-context, ограничение в 260 символов легко может быть превышено.
Ниже приведены примеры самых длинных путей к объектным файлам для каждого расположения промежуточных файлов.
|
Путь сборки |
Самый длинный путь к объектному файлу |
Результат |
|---|---|---|
|
Обычный путь к проекту + .cxx по умолчанию |
331 символ |
Ошибка |
|
Путь через Junction + .cxx по умолчанию |
290 символов |
Ошибка |
|
Путь через Junction + короткий путь промежуточных файлов |
248 символов |
Успешно |
Недостаточно сократить только путь к корню проекта; необходимо также сократить расположение промежуточных артефактов CMake.
3. Реализация
3.1 Создание Junction
Если проект находится по длинному пути, свяжите корень монорепозитория с коротким путём с помощью Junction.
cmd /c mklink /J C:\v "C:\Users\<사용자>\<긴 경로>\<프로젝트 루트>"
После этого запускайте нативную сборку из пути Junction.
C:\v\<프로젝트 경로>
Junction работает как настоящий элемент каталога на том же томе. substВ отличие от корня виртуального диска, созданного отдельно с помощью , он обеспечивает более согласованное разрешение путей файловой системы.
3.2 Сокращение пути промежуточных файлов CMake
Добавьте следующую настройку в блок android {} файла android/app/build.gradle.
externalNativeBuild {
cmake {
buildStagingDirectory = file("C:/cxx-build")
}
}
buildStagingDirectoryуказывает расположение, в котором создаются артефакты внешней нативной сборки CMake и файлы, связанные с Ninja. Вместо пути по умолчанию .cxx используйте более короткий корневой путь, чтобы уменьшить общую длину путей к объектным файлам.
3.3 Удаление существующего кэша CMake
После изменения настроек пути обязательно удалите существующий кэш.
rm -rf android/app/.cxx
В Windows PowerShell можно выполнить следующую команду.
Remove-Item -Recurse -Force android\app\.cxx
Кэш CMake может содержать канонические пути из первоначальной конфигурации. Если не удалить кэш, старые длинные пути могут продолжать использоваться даже после применения Junction и более коротких путей промежуточной сборки.
3.4 Запуск сборки
Запустите нативную сборку из пути Junction.
.\gradlew.bat assembleRelease --max-workers=2
Перед сборкой релизной версии рекомендуется завершить работу Metro и всех серверов веб-разработки, поскольку конкуренция за память может привести к ошибкам Gradle Worker Daemon.
4. Принципы работы и меры предосторожности
Используйте Junction вместо subst
substможет сопоставить путь с короткой буквой диска, но при совместном использовании пути виртуального диска и фактического пути C: могут возникнуть следующие проблемы.
-
Ошибки различающихся корневых путей в Codegen
-
Невозможность разрешить пакеты рабочей области или псевдонимы в Metro
-
Конфликты с каноническими путями, сохранёнными в глобальном кэше Gradle
-
Сопоставление исчезает после перезагрузки, и его необходимо настраивать заново каждый раз
Поэтому для сокращения пути используйте Junction.
Запускайте Metro из канонического пути
Запускайте нативные сборки Gradle из пути Junction, но Metro запускайте из канонического пути к проекту.
|
Задача |
Путь выполнения |
|---|---|
|
Нативная сборка C++ (gradlew, expo run:android) |
Путь Junction |
|
Сборщик Metro (expo start) |
Канонический путь C: |
Некоторые проекты Expo/React Native используют пути TypeScript paths, псевдонимы на основе конфигурации Babel или Metro и разрешение пакетов рабочей области. Запуск Metro из пути Junction может привести к различию между корнем проекта и реальным путём к файлам, что вызовет проблемы с разрешением псевдонимов или пакетов рабочей области.
Помните, что эти файлы создаются Expo CNG
android/ каталог создаётся Expo CNG. Если выполнить expo prebuild --clean, настройка android/app/build.gradle , добавленная непосредственно в buildStagingDirectory , может быть удалена.
Эта настройка изменяет только путь к промежуточным артефактам при локальных сборках в Windows и не влияет на результирующий APK. Поэтому ею можно управлять, попросив ответственного за нативные сборки в Windows применить её вручную.
Если в долгосрочной перспективе требуется автоматизация, рассмотрите подход с выборочной активацией на основе свойства Gradle, позволяющий пользователям Windows избирательно указывать это значение. Не задавайте абсолютный путь для всех операционных систем и сборок EAS через Config Plugin.
5. Разделение среды разработки и развёртывания
Java и Android Studio
При открытии проекта android/ в Android Studio, если синхронизация Gradle завершается с ошибкой, проверьте совместимость сочетания Gradle Wrapper, Android Gradle Plugin и плагина Kotlin в проекте с версией JDK.
Используйте версию JDK, проверенную для проекта, в качестве JDK Gradle. Например, в среде с Java 21 это можно настроить следующим образом.
$env:JAVA_HOME = "C:\Program Files\Microsoft\jdk-21"
$env:ANDROID_HOME = "C:\Users\<사용자>\AppData\Local\Android\Sdk"
У Android Studio android/ папка является артефактом, созданным CNG, а не постоянным исходным кодом. Используйте Android Studio для проверки нативных журналов и состояния Gradle, а настройки, которые должны сохраняться, размещайте в app.json или Config Plugin.
Отладочный APK и релизный APK
|
Категория |
Отладка |
Релиз |
|---|---|---|
|
JS-бандл |
Загружается в реальном времени из Metro |
Включён внутри APK |
|
Условия выполнения |
Требует доступа к Metro на компьютере для разработки |
Может работать автономно |
|
Назначение |
Локальная разработка и отладка |
Распространение среди коллег и тестировщиков |
|
Время сборки |
Относительно короткое |
Может быть больше, поскольку включены все ABI |
Артефакты APK обычно можно найти по указанному ниже пути.
android/app/build/outputs/apk/debug/app-debug.apk
android/app/build/outputs/apk/release/app-release.apk
Гибридные приложения часто загружают большинство экранов с сервера через WebView.
-
Изменения веб-экрана: полностью закройте и перезапустите приложение после развертывания веб-контента
-
Изменения оболочки RN: изменения панели вкладок, deep links, мостов, нативных SDK и т. д. требуют повторной сборки и переустановки APK
Justin