Exports FiveM en Lua : exports('name', fn) et 'No such export'
Comment définir et appeler des exports dans FiveM Lua, les styles fxmanifest exports et server_exports, et comment corriger les erreurs 'No such export' causées par l'ordre de démarrage ou le mauvais côté.
Un script appelle un autre et la console répond :
No such export getCount in resource my_inventoryCet article montre comment les exports sont définis et appelés en Lua, les deux façons de les déclarer, et les raisons habituelles pour lesquelles cette erreur apparaît.
Définir un export
Un export laisse une ressource offrir une fonction aux autres. La façon simple est la fonction exports à l'intérieur d'un script :
-- my_inventory/server/main.lua
local function getCount(source, item)
-- ...
return 5
end
exports('getCount', getCount)Vous pouvez aussi passer la fonction en ligne :
exports('getCount', function(source, item)
return 5
end)C'est tout. Il n'y a rien à ajouter à fxmanifest.lua, et l'export existe du côté où le script s'exécute : mettez-le dans un script serveur et c'est un export serveur, mettez-le dans un script client et c'est un export client.
Le style du manifeste
Les ressources plus anciennes déclarent les exports dans fxmanifest.lua et définissent une fonction globale simple avec le même nom :
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
server_exports { 'getCount' }
exports { 'getOwnedCount' }-- server script
function getCount(source, item)
return 5
endexports { … }répertorie les exports client.server_exports { … }répertorie les exports serveur.
Cela fonctionne toujours, et beaucoup de ressources ESX et QBCore l'utilisent. Les deux styles ne se heurtent pas, donc une ressource peut les mélanger. Pour le nouveau code, exports('name', fn) est plus simple car la fonction et l'export vivent ensemble, et vous ne pouvez pas oublier une ligne dans le manifeste. N'oubliez pas que fxmanifest.lua est le nom du manifeste actuel : voir fxmanifest vs __resource.lua.
Appeler un export
De n'importe quelle autre ressource du même côté :
local count = exports['my_inventory']:getCount(source, 'water')Les versions point et deux-points sont la même chose, tant que le nom est un identificateur Lua valide :
local count = exports.my_inventory:getCount(source, 'water')Utilisez la forme entre crochets quand le nom de la ressource a un tiret, tel que exports['qb-core']:GetCoreObject(). L'appel est synchrone : il retourne la valeur de la fonction, et il peut attendre si la fonction attend.
Astuce : les arguments et les valeurs de retour voyagent entre les ressources, donc les tables sont copiées. Changer une table que vous avez obtenue d'un export ne change pas les données propres de l'autre ressource. Les fonctions à l'intérieur d'une table retournée fonctionnent toujours, car elles rappellent le propriétaire.
Pourquoi vous obtenez « No such export »
No such export getCount in resource my_inventoryVérifiez ceux-ci, dans cet ordre :
- La ressource n'est pas démarrée. Ouvrez la console et exécutez
ensure my_inventory. S'il ne démarre pas, corrigez d'abord cela. - Il a démarré après l'appelant. L'export n'existe que quand le propriétaire a chargé ses scripts. Voir ordre de démarrage dans server.cfg et mettez le propriétaire au-dessus des scripts qui l'utilisent.
- Le nom est mal orthographié. Les noms d'export sont sensibles à la casse :
getCountetGetCountsont différents. - Mauvais côté. Un script serveur ne peut pas appeler un export client, et inversement. L'erreur ressemble à la même.
- L'export est déclaré mais la fonction manque. Avec le style du manifeste,
server_exports { 'getCount' }a besoin d'une fonction globale appeléegetCountsur le serveur. Une fonction locale ne compte pas. - Le propriétaire a échoué ou a été arrêté. S'il s'est écrasé sur une erreur de script, ou vous l'avez arrêté, ses exports s'en vont jusqu'à ce qu'il s'exécute à nouveau. Lisez sa sortie de démarrage dans la console.
Pour les versions réelles de cette erreur, voir No such export GetSharedObject in resource es_extended et QBCore is nil: GetCoreObject.
Rendre l'ordre certain avec des dépendances
Ne comptez pas seulement sur l'ordre des lignes ensure. Déclarez la dépendance dans le manifeste du script qui appelle l'export :
dependency 'my_inventory'FiveM démarre alors my_inventory en premier, et refuse de démarrer votre ressource si elle manque, avec un message plus clair (could not find dependency).
Gérer une ressource manquante gracieusement
Si une autre ressource est optionnelle, vérifiez son état avant de l'appeler :
if GetResourceState('my_inventory') == 'started' then
local count = exports.my_inventory:getCount(source, 'water')
endGetResourceState retourne une chaîne telle que started, stopped, starting ou missing. C'est la façon propre de soutenir une intégration optionnelle sans erreur de console.
Appeler vos propres exports
Une ressource peut aussi appeler ses propres exports, avec son propre nom : exports['my_inventory']:getCount(...). Pour une fonction qui est utilisée seulement à l'intérieur de la ressource, une fonction locale normale est plus rapide et plus simple. Les exports sont pour la frontière entre les ressources.
Un mot sur la performance
Chaque appel traverse entre deux ressources, donc c'est plus lent qu'un appel de fonction normal. N'appelez pas un export dans une boucle serrée par frame si vous pouvez lire la valeur une fois et la garder. Appeler l'un quelques fois par seconde est correct.
Liste de vérification
| Symptôme | Correction |
|---|---|
No such export x in resource y |
Démarrez y, et mettez-le avant l'appelant dans server.cfg |
| Fonctionne sur le serveur, échoue sur le client | Définissez l'export dans un script client aussi, ou appelez-le depuis le serveur |
| Export de style manifeste manquant | Définissez une fonction globale avec le même nom que l'entrée du manifeste |
| La casse du nom diffère | Faites correspondre l'orthographe exactement |
| Le nom de la ressource a un tiret | exports['my-resource']:name() |
| L'intégration optionnelle remplit la console | Vérifiez d'abord GetResourceState('x') == 'started' |
Réponses rapides
Comment appeler un export d'une autre ressource ?
Utilisez exports['resource_name']:exportName(args) ou exports.resource_name:exportName(args). L'autre ressource doit être démarrée et doit définir cet export du même côté (client ou serveur).
Ai-je toujours besoin d'exports dans fxmanifest.lua ?
Non avec exports('name', fn) : il enregistre l'export depuis le script lui-même. Les listes exports {} et server_exports {} dans le manifeste sont l'ancien style, où une fonction globale est exposée par nom.
Pourquoi un export fonctionne-t-il sur le client mais pas sur le serveur ?
Les exports client et serveur sont séparés. Un export défini dans un script client n'existe que sur le client, et un défini dans un script serveur seulement sur le serveur.
Des scripts sans ce problème
Item Creator V2Créez des items utilisables avec animations, props, effets et plus — sans écrire une ligne de code.Voir le script →
Mic PhoneUn téléphone pliable qui se déplie en tablette et se prolonge jusqu’au vrai téléphone du joueur.Voir le script →
Shop CreatorCréez un magasin en moins d’une minute — propriétaires, employés, coffres et braquages inclus.Voir le script →