Exports FiveM em Lua: exports('name', fn) e 'No such export'
Como definir e chamar exports no FiveM Lua, os estilos de exports de fxmanifest e server_exports, e como corrigir erros 'No such export' causados por ordem de inicialização ou lado errado.
Um script chama outro e o console responde:
No such export getCount in resource my_inventoryEste artigo mostra como exports são definidas e chamadas em Lua, as duas maneiras de declará-las e as razões usuais que o erro aparece.
Definindo uma export
Uma export permite que um recurso ofereça uma função aos outros. A forma simples é a função exports dentro de um script:
-- my_inventory/server/main.lua
local function getCount(source, item)
-- ...
return 5
end
exports('getCount', getCount)Você também pode passar a função inline:
exports('getCount', function(source, item)
return 5
end)Isso é tudo. Não há nada para adicionar a fxmanifest.lua, e a export existe no lado em que o script roda: coloque-a em um script de servidor e é uma export de servidor, coloque-a em um script de cliente e é uma export de cliente.
O estilo de manifesto
Recursos mais antigos declaram exports em fxmanifest.lua e definem uma função global simples com o mesmo nome:
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
server_exports { 'getCount' }
exports { 'getOwnedCount' }-- server script
function getCount(source, item)
return 5
endexports { … }lista exports de cliente.server_exports { … }lista exports de servidor.
Isso ainda funciona e muitos recursos de ESX e QBCore o usam. Os dois estilos não entram em conflito, então um recurso pode misturá-los. Para código novo, exports('name', fn) é mais simples porque a função e a export vivem juntas e você não pode esquecer uma linha no manifesto. Lembre-se de que fxmanifest.lua é o nome do manifesto atual: veja fxmanifest vs __resource.lua.
Chamando uma export
De qualquer outro recurso no mesmo lado:
local count = exports['my_inventory']:getCount(source, 'water')As versões com ponto e dois-pontos são a mesma coisa, contanto que o nome seja um identificador Lua válido:
local count = exports.my_inventory:getCount(source, 'water')Use a forma de colchetes quando o nome do recurso tem um travessão, como exports['qb-core']:GetCoreObject(). A chamada é síncrona: retorna o valor da função e pode ceder se a função espera.
Dica: argumentos e valores de retorno viajam entre recursos, então tabelas são copiadas. Alterar uma tabela que você recebeu de uma export não altera os próprios dados do outro recurso. Funções dentro de uma tabela retornada ainda funcionam, pois chamam de volta para o proprietário.
Por que você recebe "No such export"
No such export getCount in resource my_inventoryVerifique estes, nesta ordem:
- O recurso não está iniciado. Abra o console e execute
ensure my_inventory. Se falhar ao iniciar, corrija isso primeiro. - Iniciou após o chamador. A export só existe uma vez que o proprietário carregou seus scripts. Veja ordem de inicialização em server.cfg e coloque o proprietário acima dos scripts que a usam.
- O nome está escrito errado. Os nomes de export diferenciam maiúsculas de minúsculas:
getCounteGetCountsão diferentes. - Lado errado. Um script de servidor não pode chamar uma export de cliente e vice-versa. O erro parece o mesmo.
- A export é declarada mas a função está faltando. Com o estilo de manifesto,
server_exports { 'getCount' }precisa de uma função global chamadagetCountno servidor. Uma função local não conta. - O proprietário falhou ou foi parado. Se ele travou em um erro de script ou você o parou, suas exports desapareceram até rodar novamente. Leia seu resultado de inicialização no console.
Para as versões do mundo real deste erro, veja No such export GetSharedObject in resource es_extended e QBCore is nil: GetCoreObject.
Faça a ordem certa com dependências
Não confie apenas na ordem das linhas ensure. Declare a dependência no manifesto do script que chama a export:
dependency 'my_inventory'FiveM então inicia my_inventory primeiro e se recusa a iniciar seu recurso se estiver faltando, com uma mensagem mais clara (could not find dependency).
Tratando um recurso faltante com elegância
Se outro recurso é opcional, verifique seu estado antes de chamá-lo:
if GetResourceState('my_inventory') == 'started' then
local count = exports.my_inventory:getCount(source, 'water')
endGetResourceState retorna uma string como started, stopped, starting ou missing. É a forma limpa de suportar uma integração opcional sem um erro no console.
Chamando suas próprias exports
Um recurso pode chamar suas próprias exports também, com seu próprio nome: exports['my_inventory']:getCount(...). Para uma função que é usada apenas dentro do recurso, uma função local normal é mais rápida e simples. Exports são para o limite entre recursos.
Uma palavra sobre performance
Cada chamada cruza entre dois recursos, então é mais lenta que uma chamada de função normal. Não chame uma export em um loop apertado por frame se você pode ler o valor uma vez e mantê-lo. Chamar uma algumas vezes por segundo é bom.
Lista de verificação
| Sintoma | Correção |
|---|---|
No such export x in resource y |
Inicie y e coloque-o antes do chamador em server.cfg |
| Funciona no servidor, falha no cliente | Defina a export em um script de cliente também, ou chame-a do servidor |
| Export de estilo manifesto faltando | Defina uma função global com o mesmo nome que a entrada de manifesto |
| Caso de nome diferente | Combine a ortografia exatamente |
| Nome do recurso tem um travessão | exports['my-resource']:name() |
| Integração opcional spamma o console | Verifique GetResourceState('x') == 'started' primeiro |
Respostas rápidas
Como chamo uma export de outro recurso?
Use exports['resource_name']:exportName(args) ou exports.resource_name:exportName(args). O outro recurso deve estar iniciado e deve definir aquele export no mesmo lado (cliente ou servidor).
Ainda preciso de exports no fxmanifest.lua?
Não com exports('name', fn): registra a export do próprio script. As listas exports {} e server_exports {} no manifesto são o estilo mais antigo, onde uma função global é exposta por nome.
Por que uma export funciona no cliente mas não no servidor?
Exports de cliente e servidor são separados. Uma export definida em um script de cliente só existe no cliente, e uma definida em um script de servidor só no servidor.
Scripts sem esse problema
Item Creator V2Crie itens usáveis com animações, props, efeitos e muito mais — sem escrever código.Ver script →
Mic PhoneUm celular dobrável que abre em tablet e chega ao celular de verdade do jogador.Ver script →
Shop CreatorMonte uma loja em menos de um minuto — donos, funcionários, cofres e assaltos inclusos.Ver script →