Export di FiveM in Lua: exports('name', fn) e 'Nessun tale export'
Come definire e chiamare export in FiveM Lua, gli stili fxmanifest exports e server_exports, e come risolvere gli errori 'Nessun tale export' causati da ordine di avvio o il lato sbagliato.
Uno script chiama un altro e la console risponde:
No such export getCount in resource my_inventoryQuesto articolo mostra come gli export sono definiti e chiamati in Lua, i due modi per dichiararli, e i motivi soliti per cui quell'errore appare.
Definire un export
Un export consente a una risorsa di offrire una funzione alle altre. Il modo semplice è la funzione exports dentro uno script:
-- my_inventory/server/main.lua
local function getCount(source, item)
-- ...
return 5
end
exports('getCount', getCount)Puoi anche passare la funzione inline:
exports('getCount', function(source, item)
return 5
end)Questo è tutto. Non c'è niente da aggiungere a fxmanifest.lua, e l'export esiste su qualunque lato lo script viene eseguito: mettilo in uno script server e è un export server, mettilo in uno script client e è un export client.
Lo stile manifest
Le risorse più vecchie dichiarano export in fxmanifest.lua e definiscono una funzione globale semplice con lo stesso nome:
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
server_exports { 'getCount' }
exports { 'getOwnedCount' }-- server script
function getCount(source, item)
return 5
endexports { … }elenca client export.server_exports { … }elenca server export.
Questo funziona ancora, e molte risorse di ESX e QBCore lo usano. I due stili non entrano in conflitto, quindi una risorsa può mescolarli. Per il nuovo codice, exports('name', fn) è più semplice perché la funzione e l'export vivono insieme, e non puoi dimenticare una riga nel manifest. Ricorda che fxmanifest.lua è il nome del manifest attuale: vedi fxmanifest vs __resource.lua.
Chiamare un export
Da qualsiasi altra risorsa nello stesso lato:
local count = exports['my_inventory']:getCount(source, 'water')Le versioni punto e due punti sono la stessa cosa, finché il nome è un identificatore Lua valido:
local count = exports.my_inventory:getCount(source, 'water')Usa la forma tra parentesi quando il nome della risorsa ha un trattino, come exports['qb-core']:GetCoreObject(). La chiamata è sincrona: restituisce il valore della funzione, e può attendere se la funzione aspetta.
Suggerimento: gli argomenti e i valori di ritorno viaggiano tra le risorse, quindi le tabelle vengono copiate. Modificare una tabella ottenuta da un export non cambia i dati propri dell'altra risorsa. Le funzioni all'interno di una tabella restituita funzionano ancora, poiché richiamano il proprietario.
Perché ricevi "Nessun tale export"
No such export getCount in resource my_inventoryControlla questi, in questo ordine:
- La risorsa non è avviata. Apri la console ed esegui
ensure my_inventory. Se non riesce ad avviarsi, correggilo prima. - Si è avviato dopo il chiamante. L'export esiste solo una volta che il proprietario ha caricato i suoi script. Vedi ordine di avvio in server.cfg e metti il proprietario sopra gli script che lo usano.
- Il nome è male scritto. I nomi degli export distinguono tra maiuscole e minuscole:
getCounteGetCountsono diversi. - Lato sbagliato. Uno script server non può chiamare un export client, e viceversa. L'errore sembra lo stesso.
- L'export è dichiarato ma la funzione manca. Con lo stile manifest,
server_exports { 'getCount' }ha bisogno di una funzione globale chiamatagetCountsul server. Una funzione locale non conta. - Il proprietario ha fallito o è stato fermato. Se si è bloccato su un errore di script, o lo hai fermato, i suoi export sono spariti fino al prossimo esecuzione. Leggi il suo output di avvio nella console.
Per le versioni nel mondo reale di questo errore, vedi Nessun tale export GetSharedObject in risorsa es_extended e QBCore è nil: GetCoreObject.
Rendi sicuro l'ordine con dipendenze
Non fare affidamento solo sull'ordine delle linee ensure. Dichiara la dipendenza nel manifest dello script che chiama l'export:
dependency 'my_inventory'FiveM quindi avvia my_inventory per primo, e rifiuta di avviare la tua risorsa se manca, con un messaggio più chiaro (non è stato possibile trovare la dipendenza).
Gestione di una risorsa mancante con eleganza
Se un'altra risorsa è opzionale, controlla il suo stato prima di chiamarla:
if GetResourceState('my_inventory') == 'started' then
local count = exports.my_inventory:getCount(source, 'water')
endGetResourceState restituisce una stringa come started, stopped, starting o missing. È il modo pulito per supportare un'integrazione opzionale senza un errore della console.
Chiamare i tuoi stessi export
Una risorsa può chiamare anche i suoi stessi export, con il suo nome: exports['my_inventory']:getCount(...). Per una funzione che viene utilizzata solo all'interno della risorsa, una funzione locale normale è più veloce e più semplice. Gli export sono per il confine tra le risorse.
Una parola sulla prestazione
Ogni chiamata attraversa le risorse, quindi è più lenta di una normale chiamata di funzione. Non chiamare un export in un ciclo tight per frame se puoi leggere il valore una volta e mantenerlo. Chiamarne uno poche volte al secondo va bene.
Checklist
| Sintomo | Soluzione |
|---|---|
No such export x in resource y |
Avvia y, e mettilo prima del chiamante in server.cfg |
| Funziona sul server, fallisce sul client | Definisci l'export anche in uno script client, o chiamalo dal server |
| Export di stile manifest mancante | Definisci una funzione globale con lo stesso nome della voce manifest |
| Le maiuscole e minuscole del nome differiscono | Abbina l'ortografia esattamente |
| Il nome della risorsa ha un trattino | exports['my-resource']:name() |
| L'integrazione opzionale spamma la console | Controlla prima GetResourceState('x') == 'started' |
Risposte rapide
Come chiamo un export da un'altra risorsa?
Usa exports['resource_name']:exportName(args) o exports.resource_name:exportName(args). L'altra risorsa deve essere avviata e deve definire quell'export nello stesso lato (client o server).
Ho ancora bisogno di export in fxmanifest.lua?
No con exports('name', fn): registra l'export dallo script stesso. Gli elenchi exports {} e server_exports {} nel manifest sono lo stile più vecchio, dove una funzione globale è esposta per nome.
Perché un export funziona sul client ma non sul server?
Gli export client e server sono separati. Un export definito in uno script client esiste solo sul client, e uno definito in uno script server solo sul server.
Script senza questo problema
Item Creator V2Crea oggetti utilizzabili con animazioni, props, effetti e altro — senza scrivere codice.Vedi script →
Mic PhoneUn telefono pieghevole che si apre in un tablet e arriva sul telefono vero del giocatore.Vedi script →
Shop CreatorCrea un negozio in meno di un minuto — proprietari, dipendenti, casseforti e rapine inclusi.Vedi script →