
(
Abbildung )
Die leitenden Webentwickler Anton und Alexei setzen die Geschichte des schwierigen Kampfes mit Nuxt fort. In der vorherigen Runde des Kampfes mit diesem Framework haben sie gezeigt, wie man ein Projekt auf Nuxt startet, damit alle glücklich sind. In einem neuen Artikel werden wir über die tatsächliche Anwendung des Frameworks sprechen.Wir haben begonnen, das Projekt mit einer enormen technischen Verschuldung umzuschreiben. Das monatliche Publikum betrug 6-7 Millionen Besucher, aber die vorhandene Plattform verursachte zu viele Probleme. Daher wurde beschlossen, sie in den Ruhestand zu schicken. Natürlich war die Leistung unser größtes Anliegen, aber ich wollte auch keine SEO verschwenden.
Nach einigen Diskussionsrunden entschieden sie sich, sich nicht nur beim serverseitigen Rendern auf den traditionellen Ansatz zu verlassen, sondern sich nicht beim clientseitigen Rendern zu engagieren. Als Ergebnis haben wir begonnen, eine Lösung zu entwickeln, die auf
Nuxt.js basiert.
Gute alte Nuxt.js
Wir verwenden das "Framework für Framework" basierend auf
Vue.js, das uns bereits
im letzten Artikel bekannt war, um universelle Client-Server-Anwendungen zu erstellen. In unserem Fall arbeitet die Anwendung in Verbindung mit einer ziemlich komplizierten API (den Feinheiten von Microservices, aber zu einem anderen Zeitpunkt) und mehreren Ebenen des Caching. Sie rendert Inhalte, die von Editoren bearbeitet werden können, und gibt bereits statische Inhalte für blitzschnelle Leistung zurück. Großartig, richtig?
Tatsächlich gibt es hier nichts Neues. Was Nuxt.js jedoch interessant macht, ist die Möglichkeit, ein Projekt mit Client-Server-Rendering schnell zu starten. Manchmal müssen Sie gegen das etablierte Framework des Frameworks verstoßen. Das haben wir getan.
Keine Zeit zu erklären, einmal zu bauen, viele einzusetzen!
Eines Tages kam ein Techlide auf uns zu und war verwirrt: Wenn wir Änderungen am Repository vornehmen, müssen wir jede Umgebung (Entwicklungs-, Bühnen- und Produktumgebung) separat erstellen. Es war langsam. Aber was ist der Unterschied zwischen diesen Builds? Ja, nur in Umgebungsvariablen! Und was er verlangte, klang logisch und vernünftig. Aber unsere erste Reaktion war: O_o
Das einmalige Erstellen vieler Strategien ist in der Welt der Softwareentwicklung sinnvoll. Aber in der Javascript-Welt ... Wir haben eine ganze Reihe von Compilern, Transpilern, Vor- und Nachprozessoren sowie Tests und Lintern. All dies braucht Zeit, um sie für jede der Umgebungen zu konfigurieren. Darüber hinaus gibt es viele potenzielle Probleme mit dem Verlust vertraulicher Daten (Geheimnisse, API-Schlüssel usw., die in Konfigurationen gespeichert werden können).
Und wir fingen an
Natürlich haben wir mit einer Suche bei Google begonnen. Dann haben wir mit den Betreuern von Nuxt.j gesprochen, aber ohne großen Erfolg. Was zu tun ist - ich musste selbst eine Lösung finden und diese nicht aus StackOverflow kopieren (dies ist die Grundlage unserer Aktivitäten, oder?).
Lassen Sie uns herausfinden, wie Nuxt.js das macht.
Nuxt.js hat eine Konfigurationsdatei mit dem erwarteten Namen nuxt.config.js. Es wird verwendet, um Konfigurationen programmgesteuert an die Anwendung zu übertragen:
const config = require('nuxt.config.js') const nuxt = new Nuxt(config)
Es ist möglich, die Umgebung über env-Variablen festzulegen. Im Allgemeinen ist es üblich, die Konfigurationsdatei dynamisch zu verbinden. All dies wird dann in das definePlugin-Webpack übertragen und kann auf Client und Server verwendet werden.
process.env.propertyName
// oder
context.env.propertyName.
Diese Variablen werden während der Montage gebacken. Weitere Informationen finden Sie hier:
Nuxt.js env-Seite .
Haben Sie das Webpack bemerkt? Ja, das bedeutet Zusammenstellung, und das wollen wir nicht.
Versuchen wir es anders
Zu verstehen, wie Nuxt.js funktioniert, bedeutet für uns:
- In nuxt.config.js können wir env nicht mehr verwenden.
- Alle anderen dynamischen Variablen (z. B. innerhalb von head.meta) sollten zur Laufzeit an das Objekt nuxt.config.js übergeben werden.
Code in server / index.js:
const config = require('../nuxt.config.js')
Wechseln zu:
Wo utils / extendedNuxtConfig.js:
import config from 'config' import get from 'lodash/get'
Wir haben den Elefanten nicht einmal bemerkt
Nun, wir haben das Problem gelöst, dynamische Variablen von außerhalb der env-Eigenschaft des Konfigurationsobjekts in nuxt.config.js zu erhalten. Das ursprüngliche Problem ist jedoch immer noch nicht gelöst.
Es wurde angenommen, dass einige abstrakte sharedEnv.js verwendet werden für:
- client - Erstellen Sie eine env.js-Datei, die global heruntergeladen wird (window.env.envKey).
- Server - wird bei Bedarf in Module importiert,
- isomorpher Code, so etwas wie
context.isClient? window.env [Schlüssel]: global.sharedEnv [Schlüssel].
Irgendwie nicht so toll. Diese Abstraktion würde das schwerwiegendste Problem lösen - das Durchsickern vertraulicher Daten in die Clientanwendung, da es notwendig wäre, den Wert bewusst zu erhöhen.
Vuex wird uns helfen
Bei der Untersuchung des Problems haben wir festgestellt, dass der Vuex-Speicher in ein Fensterobjekt exportiert wird. Diese Lösung muss den Isomorphismus von Nuxt, js, unterstützen. Vuex ist ein von Flux inspiriertes Data Warehouse, das speziell für Vue.js-Anwendungen entwickelt wurde.
Warum nicht für unsere gemeinsamen Variablen verwenden? Dies ist ein organischerer Ansatz - Daten in einem globalen Repository passen zu uns.
Beginnen wir mit server / utils / sharedEnv.js:
import config from 'config' const sharedEnv = {
Der obige Code wird beim Serverstart ausgeführt. Fügen Sie es dann dem Vuex-Repository hinzu:
const getSharedEnv = () => process.server ? require('~/server/utils/sharedEnv').default || {} : {}
Wir werden uns darauf verlassen, dass nuxtServerInit während der Serverinitialisierung gestartet wird. Es gibt einige Schwierigkeiten: Achten Sie auf die Methode getSharedEnv. Hier wird die Überprüfung auf wiederholte Ausführung auf dem Server hinzugefügt.
Was ist passiert?
Jetzt haben wir gemeinsame Variablen, die in Komponenten wie diesen extrahiert werden können:
this. $ store.state.sharedEnv.canonicalDomain
Sieg!Oh nein. Was ist mit Plugins?
Einige Plugins erfordern Umgebungsvariablen zum Konfigurieren. Und wenn wir sie nutzen wollen:
Vue.use (MyPlugin, {someEnvOption: 'Es gibt keinen Zugriff auf den vuex-Speicher'})
Vue.js versucht, sich selbst zu initialisieren, bevor Nuxt.js sharedEnvobject im Vuex-Repository registriert.
Obwohl die Funktion zum Registrieren von Plugins den Zugriff auf das Context-Objekt ermöglicht, das den Repository-Link enthält, ist sharedEnv noch leer. Dies ist ganz einfach zu lösen - machen wir das Plugin zu einer asynchronen Funktion und warten, bis nuxtServerInit ausgeführt wird:
import Vue from 'vue' import MyPlugin from 'my-plugin' export default async (context) => {
Jetzt ist der Sieg.