ForgeTotal.js 5
nl

Total.js 5

Laad een JavaScript-module vanaf een URL met IMPORT()

Total.js 5 · total5@0.0.19 modulesdownloaddependencies Uitgevoerd met Total.js 5

IMPORT(url, [callback]) downloadt een JavaScript-bestand, slaat het op in de map tmp van de applicatie en geeft terug wat het bestand exporteert (module.exports), zoals require() zou doen. Met een callback is het callback(err, module, response); zonder geeft IMPORT() een promise voor de module terug. Het adres wordt onthouden: IMPORT() opnieuw aanroepen met hetzelfde adres downloadt het bestand niet opnieuw, het laadt dat in tmp met require (en het bestand blijft daar tussen herstarts, maar het geheugen van "al gedownload" niet: na een herstart wordt het opnieuw gedownload).

Dit voert code uit het netwerk uit met alle rechten van je applicatie. Importeer alleen van een adres dat je beheert en dat je via https bereikt, nooit van een adres dat een gebruiker je heeft gestuurd of dat iemand anders kan wijzigen. Het bestand is een CommonJS-module. De status van het antwoord wordt niet gecontroleerd: een adres dat met 404 (of een willekeurige foutpagina) antwoordt, wordt opgeslagen alsof het de module is, en require() gooit dan een SyntaxError binnen de download, zodat in total5 0.0.19 de callback nooit wordt aangeroepen en de promise nooit wordt afgehandeld. Geef IMPORT() altijd een eigen tijdslimiet, zoals de laatste route doet, en controleer het adres voordat je ervan afhankelijk bent.

Hier komt het bestand van een route van dezelfde applicatie, zodat het voorbeeld geen netwerk nodig heeft. De route telt de downloads.

controllers/import.js
exports.install = function() {
	ROUTE('GET /lib/tax/', lib);
	ROUTE('POST /use/', use);
	ROUTE('POST /use-twice/', use_twice);
	ROUTE('POST /missing/', missing);
	ROUTE('GET /downloads/', downloads);
};

let count = 0;

function lib($) {
	count++;
	$.plain('module.exports = { vat: function(price) { return Math.round(price * 121) / 100; } };');
}

function downloads($) {
	$.json({ downloads: count });
}

function base() {
	return 'http://127.0.0.1:' + CONF.$port;
}

async function use($) {
	const tax = await IMPORT(base() + '/lib/tax/');
	$.json({ price: tax.vat(100) });
}

function use_twice($) {
	IMPORT(base() + '/lib/tax/', function(err, tax) {
		$.json({ err: err ? err.toString() : null, price: tax ? tax.vat(200) : null });
	});
}

async function missing($) {
	// the address does not exist: the answer is the 404 page of the application
	const winner = await Promise.race([
		IMPORT(base() + '/lib/missing/').then(() => 'answered', () => 'answered'),
		new Promise(resolve => setTimeout(() => resolve('no answer'), 1500))
	]);
	$.json({ result: winner });
}