No such export X in resource Y: как это исправить в FiveM
Получаете ошибку 'No such export X in resource Y' в FiveM? Причины: ресурс не запущен, неправильное имя папки, несоответствие на стороне клиента или сервера, переименованный экспорт и порядок запуска.
Консоль показывает это, часто в цикле:
SCRIPT ERROR: @my_script/server/main.lua:14: No such export GetItemCount in resource my_inventoryВаш скрипт вызвал exports['my_inventory']:GetItemCount(). В тот момент my_inventory не имел экспорта с таким именем. Сообщение называет обе части, поэтому решение — одна из небольшого числа причин. Это руководство охватывает общий случай. Если экспорт — это getSharedObject из es_extended, прочитайте вместо этого No such export getSharedObject in resource es_extended, в котором описаны причины, специфичные для ESX.
1. Ресурс не запущен
Экспорт существует только при запущенном ресурсе. Проверьте консоль при запуске:
- Указан ли ресурс в
server.cfgсensureилиstart? - Запустился ли он без ошибок или выдал
Couldn't start resourceилиFailed to load script? - Он остановлен в txAdmin? Проверьте страницу Ресурсы.
Ресурс, который не удалось запустить, например, из-за синтаксической ошибки Lua или отсутствующей зависимости, не имеет экспортов. Сначала исправьте его собственную ошибку. Смотрите Couldn't start resource и could not find dependency. Синтаксическая ошибка в частности рассмотрена в Lua syntax error: unexpected symbol near.
2. Имя ресурса неправильное
exports['my_inventory'] использует имя папки ресурса, а не название скрипта. Если папка была переименована, каждый скрипт, вызывающий его со старым именем, не работает.
Типичные ситуации:
- Вы переименовали
my_inventory-masterилиmy_inventory-mainна что-то более короткое и продолжили вызывать старое имя. - Имя использует дефис в одном месте и подчеркивание в другом:
my-inventoryиmy_inventory— это разные ресурсы. - Капитализация отличается: совпадите с папкой точно.
- Ресурс находится в папке с скобками, такой как
[qb]. Скобки — это просто категория: они не часть имени, поэтому используйтеmy_inventory, а не[qb]/my_inventory.
Некоторые ресурсы заменяют другой с помощью provide 'other_name' в их fxmanifest, так что скрипты, запрашивающие старое имя, всё ещё работают. Если вы заменили ресурс совместимым и старое имя не работает, проверьте, предоставляет ли его новый, и что вы удалили старую папку, чтобы два ресурса не конфликтовали.
3. Экспорт находится на другой стороне
Экспорты привязаны к сторонам. Экспорт, зарегистрированный в клиентском скрипте, может быть вызван только из другого клиентского скрипта, а зарегистрированный на сервере — только из серверного скрипта.
-- my_inventory/server/main.lua
exports('GetItemCount', function(source, item)
return 0
end)-- my_script/client/main.lua
-- fails: GetItemCount exists on the server only
local count = exports['my_inventory']:GetItemCount('water')Чтобы проверить, посмотрите в файлы поставщика: строка exports(...) находится в client/ или server/, или в файле, перечисленном в shared_scripts, который запускается на обеих сторонах. Если экспорт только на сервере, вызывайте его из серверного скрипта и доставляйте данные на клиент с помощью события или обратного вызова, смотрите server callbacks.
4. Экспорт был переименован или удален
Ресурсы меняются между версиями. Экспорт, называемый GetItemCount в более старой версии, может быть getItemCount или Search в новой, и имена Lua чувствительны к регистру. Если ошибка появилась после обновления одного из ресурсов:
- Откройте
fxmanifest.lua,READMEили документацию поставщика и найдите текущий список экспортов. - Поищите в папке ресурса
exports(и имя, которое вы вызываете. - Обновите ваш вызов или обновите другой ресурс до версии, для которой был написан скрипт.
Помните, что обратное также существует: скрипт обновлен для вызова нового экспорта, но поставщик все еще запускает старую версию без него.
grep -rn "exports(" resources/[mic]/my_inventoryНа Windows используйте вместо этого поле поиска вашего редактора.
5. Порядок запуска и зависимости
Если ресурс существует и имеет экспорт, но вызов происходит до того, как он готов, вы получаете ту же ошибку. Ресурсы запускаются в порядке server.cfg:
ensure oxmysql
ensure ox_lib
ensure my_inventory
ensure my_scriptПоместите поставщика выше скрипта, который его использует. Для постоянного решения укажите связь в fxmanifest.lua вызывающего:
dependency 'my_inventory'Тогда FiveM запустит my_inventory первым и откажется запускать скрипт без него. Больше информации о порядке в server.cfg resource order.
Два связанные подводные камни:
- Экспорт зарегистрирован поздно.
exports('Name', fn)запускается, когда строка достигается. Если файл ошибается выше неё или регистрирует её после долгогоWait, вызовы, которые запускаются тем временем, не работают. Регистрируйте экспорты в начале файла. - Вызов во время загрузки. Вызов верхнего уровня, такой как
local count = exports['my_inventory']:GetItemCount('water')запускается в момент загрузки вашего файла. Переместите его в событие или поток, или убедитесь, что зависимость уже запущена.
Вы также можете защитить необязательную интеграцию с pcall и проверкой того, что ресурс запущен:
if GetResourceState('my_inventory') == 'started' then
local ok, count = pcall(function()
return exports['my_inventory']:GetItemCount('water')
end)
endGetResourceState возвращает 'started', 'stopped', 'missing' или другие состояния, поэтому вы также можете записать в журнал, в каком случае находитесь. Для более глубокого взгляда на то, как работают экспорты, прочитайте FiveM exports in Lua.
6. Перезагрузили один ресурс, а не другой
Перезагрузка поставщика при работе сервера не всегда переподключает скрипты, которые содержат его объекты. После перезагрузки или обновления поставщика перезагрузите скрипты, которые его вызывают, или перезагрузите сервер.
Контрольный список
| Симптом | Решение |
|---|---|
| Ресурс не в консоли при запуске | Добавьте ensure my_inventory в server.cfg |
Couldn't start resource над ошибкой |
Сначала исправьте ошибку самого поставщика |
| Папка переименована | Используйте точное имя папки в exports['name'] |
| Экспорт вызывается с неправильной стороны | Вызывайте его со стороны, которая его определяет, или используйте событие/обратный вызов |
| Ошибка после обновления | Экспорт был переименован или удален; проверьте текущий список экспортов поставщика |
| Ошибка только при запуске | Поместите поставщика выше вызывающего; добавьте строку dependency |
| Всё ещё не работает после перезагрузки поставщика | Перезагрузите скрипты, которые его вызывают |
Короткие ответы
Что означает ошибка 'No such export X in resource Y'?
Скрипт вызвал exports['Y']:X(), а ресурс Y не имел экспорта с именем X в тот момент. Y не запущен, имеет другое имя, определяет X на другой стороне, или эта версия не имеет этого экспорта.
Чувствительно ли имя ресурса к регистру?
Рассматривайте его как чувствительное к регистру: имя в exports['name'] должно точно совпадать с именем папки, включая дефисы и подчеркивания. Это особенно важно на Linux-серверах.
Исправляет ли порядок ensure эту ошибку?
Часто да. Ресурсы запускаются в порядке server.cfg, поэтому поместите ресурс, который предоставляет экспорт, выше того, который его вызывает, или добавьте строку dependency в fxmanifest.
Скрипты без этой проблемы
Mic PhoneСкладной телефон, который раскладывается в планшет и работает и на настоящем телефоне игрока.Смотреть скрипт →
CCTV Security CamerasУстанавливаемые камеры, планшет с мультиэкраном в реальном времени и распечатанные фото-улики.Смотреть скрипт →
Item Creator V2Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →