Heim  >  Artikel  >  Web-Frontend  >  Erstellen einer Laufzeit

Erstellen einer Laufzeit

Linda Hamilton
Linda HamiltonOriginal
2024-10-27 09:55:03864Durchsuche

Criando uma Runtime

Hallo, mein Name ist Lucas Wasilewski und genau wie ich es in der Projektbeschreibung auf meinem Github eingegeben habe, wollte ich es schon immer tun, seit ich mit NodeJS angefangen habe (Anfang 2021). Ich habe etwas geschrieben, das wie das Tool aussah. Dies verstärkte sich erst, nachdem ich mir die Dokumentation über das Projekt angesehen hatte, und ich war erstaunt darüber, wie die Open-Source-Welt mehrere Wendungen haben und sehr einladend sein kann, wenn sie möchte. Und nach einer Woche voller Kopfzerbrechen habe ich beschlossen, diesen Artikel zu schreiben, damit zukünftige verrückte Programmierer, die diese Herausforderung wollen, nicht die gleichen Fehler machen wie ich.

Javascript-Laufzeiten

Dieser Begriff kann jeden, der nicht viel über das Thema versteht, leicht in die Irre führen und daher ist eine gute Definition erforderlich:

Eine Javascript-Laufzeitumgebung ist ein Tool, mit dem Sie die Sprache außerhalb des Browsers ausführen können

Heutzutage gibt es drei beliebte Laufzeiten: NodeJS, Deno (Node Killer) und Bun (Deno Killer), aber sie machen im Grunde das Gleiche: Sie ermöglichen es Ihnen, Javascript außerhalb des Browsers zu verwenden und andere Bibliotheken zu verwenden, um neue Funktionen zu erstellen diejenigen, und das ist sehr gut, da Sie jede davon verwenden können, um einen Server zu erstellen, Bibliotheken zu erstellen und sogar mobile oder Terminalanwendungen.

Sowohl Node als auch Deno wurden von derselben Person erstellt: Ryan Dahl, und er hat das Tool bereits 2009 erstellt, um Entwicklern die Erstellung von „asynchronen IO“-Anwendungen zu ermöglichen, das heißt, die den Hauptthread nicht blockierten, ihn aber trotzdem weiterhin blockierten Um auf Anfragen zu reagieren, hat er vor diesem Hintergrund Libuv erstellt, eine Bibliothek, die genau das tut. Bis dahin war das Projekt nur ein großer Haufen C, und wenn er wollte, dass mehr Leute das Tool nutzen, brauchte er eine Sprache, die leichter zu verstehen und zu verwenden war. Zufälligerweise brachte Google gleichzeitig V8 auf den Markt, was im Allgemeinen ein ultra-modernes Tool ist. Schneller Javascript-Compiler, der ihn dazu brachte, die beiden zu kombinieren und so Node zu erstellen.

Einige Zeit später (genauer gesagt 9 Jahre) verließ Ryan das Projekt und arbeitete an anderen Dingen, die er für interessanter hielt. Dadurch wurde ihm klar, dass mehrere Fehler in Node behoben werden konnten, aber die Community war bereits sehr groß und einen großen Schritt zurück machen zu müssen, war unmöglich, also erstellte er, entschlossen, einen besseren Job zu machen, Deno, eine weitere IO-Laufzeit, die verspricht, Node deutlich überlegen zu sein. Ab heute (2024) ist Deno in Version 2.0 und sehr gut stabil für Projekte und die Community.

Diese ganze Geschichte hat dazu geführt, dass mehr Menschen der Runtime-Community beigetreten sind, und das hat uns auch zur Entwicklung von Bun geführt, und noch viel besser, meiner und Ihrer Runtime! Kommen wir nun zur Sache.

Kompilieren von V8

Wie bereits erwähnt, ist V8 die Node-Engine, daher müssen wir sie tatsächlich herunterladen und manuell kompilieren, um Zugriff auf ihre Bibliotheken und Header zu haben. Da es sich um ein Google-Projekt handelt, haben sie ihre eigenen Methoden zum Herunterladen und Kompilieren. Dazu müssen wir dem Link „Handbuch:“ folgen. Durch einfaches Kopieren und Einfügen gelangen Sie zu den endgültigen Befehlen.

Allerdings habe ich hier einen Fehler gemacht, der 3 Tage dauerte, bis mir klar wurde, dass ich alles falsch gemacht habe. Nach dem Generieren der Build-Konfigurationsdateien mit:

tools/dev/v8gen.py x64.release

Sie müssen mit der Datei args.gn im Ordner out.gn/x64.release/ sehr vorsichtig sein, da sie die Build-Konfiguration enthält, die der Ninja (Kompilierungstool) zum Generieren der Bibliotheksdateien verwendet, einige alte Tutorials Verwenden Sie den Parameter v8_monolithic = true, dieser wird jedoch in neueren Versionen nicht mehr verwendet. Laut diesem StackOverflow-Kommentar müssen wir jetzt den Parameter is_component_build = true verwenden, um die richtigen Dateien zu generieren und die Flags beim Kompilieren der Datei zu ändern, etwas sehr Dummes, das wertvolle Zeit verschwenden kann, wenn man es nicht beachtet.

Nachdem wir die restlichen Flags korrekt platziert haben, müssen wir nur noch den Befehl ausführen, um das Projekt zu kompilieren

ninja -C out.gn/x64.release

Gehen Sie in der Zwischenzeit etwas essen, denn V8 ist ein sehr umfangreiches Projekt mit unzähligen Tests. Abhängig von Ihrer Maschine kann dieser Vorgang leicht 1 Stunde oder länger dauern. Lassen Sie es also laufen und lesen Sie weiter.

Wo ist console.log?

Nach dem Kompilieren können Sie sich v8/samples/hello-world.cc ansehen und eine Vorstellung davon bekommen, wie man Javascript kompiliert, insbesondere diese Zeilen:

v8::Local<v8::String> source =
          v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");

// Compile the source code.
v8::Local<v8::Script> script =
          v8::Script::Compile(context, source).ToLocalChecked();

Spielen Sie weiter mit der Zeichenfolge, die „Hello World“ enthält, erstellen Sie Funktionen, Schleifen und Bedingungen und werden Sie verrückt, wenn Sie feststellen, dass Sie, wenn Sie die klassische console.log() einschließen, ein Undefiniertes erhalten, das zunächst einmal verwirrt Ich dachte immer, dass das Konsolenobjekt Teil von V8 selbst sei, aber tatsächlich enthält Node es selbst und Browser schließen es als Teil des DOM ein (Beitrag aus dem Jahr 2012, in dem es heißt, dass console.log von Browsern wahrscheinlich nicht unterstützt wird), also wir Ich muss es selbst erstellen.

Hallo Welt!

Um unsere eigenen Funktionen erstellen zu können, müssen wir zunächst verstehen, dass V8 mit mehreren Bereichen arbeitet, einer davon ist der Kontext, wodurch die Laufzeit weiß, wo und wie sie das Skript einzeln darin ausführen muss Möglicherweise gibt es ein globales Objekt, das von allen anderen gemeinsam genutzt wird, und darin werden wir unsere benutzerdefinierten Funktionen einfügen.

tools/dev/v8gen.py x64.release

Mit diesen Zeilen konnten wir ein Objekt namens „global“ erstellen. Wir haben eine „Druck“-Funktionsvorlage eingefügt, die bei Ausführung die Druckfunktion aufruft.

v8::Local<v8::String> source =
          v8::String::NewFromUtf8Literal(isolate, "'Hello' + ', World!'");

// Compile the source code.
v8::Local<v8::Script> script =
          v8::Script::Compile(context, source).ToLocalChecked();

Die Print-Funktion empfängt diesen verrückten Parameter, der Informationen über den Funktionsaufruf in Javascript enthält, und über ihn iterieren wir über alle darin enthaltenen Elemente, wandeln sie in einen C-String um und drucken sie auf dem Bildschirm aus, ganz direkt. Sehr einfach und es erfüllt seine Aufgabe. Es reicht aus, es in eine Datei zu legen, es zu lesen und auf dem V8 abzuspielen (das lasse ich in Ihren Händen).

v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(GetIsolate());
global->Set(GetIsolate(), "print", v8::FunctionTemplate::New(GetIsolate(), this->Print));
v8::Local<v8::Context> context = v8::Context::New(GetIsolate(), nullptr, global);

Libuv

Nun, ich hoffe, dass Sie inzwischen mitmachen konnten und sogar mit dem Lesen aufgehört haben, um einige einzigartige Implementierungen für Ihren selbstgemachten Node zu erstellen, aber V8 wird uns nur so weit bringen, dass wir einem näher kommen können Als professionelle Laufzeit müssen wir Javascript in die Lage versetzen, mehr Operationen auszuführen. Dazu verwenden wir Libuv, das genau dafür erstellt wurde.

Das Tutorial zum Installieren und Kompilieren finden Sie hier. Dabei ist es wichtig zu beachten, dass es uns die Freiheit gibt, asynchrone Vorgänge durchzuführen, d Steckdose).

Die Funktionalität zum Erstellen eines http-Servers ist bereits integriert, sodass wir ihn nur mit den V8-Aufrufen synchronisieren müssen. Täuschen Sie sich nicht, das ist keine leichte Aufgabe, denn die Schnittstelle der beiden Bibliotheken unterscheidet sich stark, so dass es schwierig ist, beide zu verbinden, aber es gibt immer einen Weg und der Quellcode des Knotens ist offen, also stellen Sie sicher, dass Sie einige Ideen stehlen dort

Schlussfolgerungen

Wir sind am Ende eines weiteren Artikels angelangt und gehen damit auf einige Details ein, die mir bei der Umsetzung aufgefallen sind. Das erste ist definitiv die Komplexität, natürlich ist es kein einfaches Projekt, aber wenn man erst einmal verstanden hat, wie man mit der V8-Schnittstelle interagiert, geht es sehr schnell.

Durch dieses Projekt habe ich auch Node viel besser verstanden. Die Tatsache, dass die Laufzeit nur ein Konglomerat kommunizierender Bibliotheken ist, macht es sehr einfach zu verstehen, wie komplexere Dinge (wie die „Ereignisschleife“) funktionieren.

Wenn Sie sehen möchten, was ich richtig oder wahrscheinlich sehr falsch gemacht habe, werfen Sie bitte einen Blick auf das Projekt auf Github: done

Reden ist günstig, zeig mir den Code – Linus Torvalds

## Referenzen

https://github.com/libuv/libuv
https://v8.dev/docs
https://stackoverflow.com/questions/71213580/cant-get-v8-monolith-to-genorate
https://github.com/ErickWendel/myownnode
https://github.com/WasixXD/done

Das obige ist der detaillierte Inhalt vonErstellen einer Laufzeit. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn