No such export X in resource Y: как это исправить в FiveM

Получаете ошибку 'No such export X in resource Y' в FiveM? Причины: ресурс не запущен, неправильное имя папки, несоответствие на стороне клиента или сервера, переименованный экспорт и порядок запуска.

Консоль показывает это, часто в цикле:

text
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. Экспорт находится на другой стороне

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

lua
-- my_inventory/server/main.lua
exports('GetItemCount', function(source, item)
    return 0
end)
lua
-- 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 чувствительны к регистру. Если ошибка появилась после обновления одного из ресурсов:

  1. Откройте fxmanifest.lua, README или документацию поставщика и найдите текущий список экспортов.
  2. Поищите в папке ресурса exports( и имя, которое вы вызываете.
  3. Обновите ваш вызов или обновите другой ресурс до версии, для которой был написан скрипт.

Помните, что обратное также существует: скрипт обновлен для вызова нового экспорта, но поставщик все еще запускает старую версию без него.

bash
grep -rn "exports(" resources/[mic]/my_inventory

На Windows используйте вместо этого поле поиска вашего редактора.

5. Порядок запуска и зависимости

Если ресурс существует и имеет экспорт, но вызов происходит до того, как он готов, вы получаете ту же ошибку. Ресурсы запускаются в порядке server.cfg:

cfg
ensure oxmysql
ensure ox_lib
ensure my_inventory

ensure my_script

Поместите поставщика выше скрипта, который его использует. Для постоянного решения укажите связь в fxmanifest.lua вызывающего:

lua
dependency 'my_inventory'

Тогда FiveM запустит my_inventory первым и откажется запускать скрипт без него. Больше информации о порядке в server.cfg resource order.

Два связанные подводные камни:

  • Экспорт зарегистрирован поздно. exports('Name', fn) запускается, когда строка достигается. Если файл ошибается выше неё или регистрирует её после долгого Wait, вызовы, которые запускаются тем временем, не работают. Регистрируйте экспорты в начале файла.
  • Вызов во время загрузки. Вызов верхнего уровня, такой как local count = exports['my_inventory']:GetItemCount('water') запускается в момент загрузки вашего файла. Переместите его в событие или поток, или убедитесь, что зависимость уже запущена.

Вы также можете защитить необязательную интеграцию с pcall и проверкой того, что ресурс запущен:

lua
if GetResourceState('my_inventory') == 'started' then
    local ok, count = pcall(function()
        return exports['my_inventory']:GetItemCount('water')
    end)
end

GetResourceState возвращает '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Создавайте используемые предметы с анимациями, пропами, эффектами и не только — без кода.Смотреть скрипт →

Читайте также