Après avoir touché GraalJS, je vais essayer SSR. J'espère que cela sera utile pour les personnes qui veulent SSR même en Java.
GraalVM est une VM qui peut exécuter JVM, JavaScript, Python, Ruby, etc. GraalJS est censé optimiser les performances en s'exécutant dans l'environnement GraalVM (de la version officielle), mais comme il est écrit en Java, il s'agit d'une JVM normale Mais il est possible d'opérer. Cette fois, je voudrais essayer SSR en utilisant GraalJS avec JVM.
Je n'expliquerai pas les paramètres côté JS en détail, mais préparerai les fichiers JS côté serveur et côté client avec webpack selon le Guide VueSSR.
javascript:webpack.config.js
node: {
child_process: 'empty',
fs: 'empty',
net: 'empty',
tls: 'empty',
},
Ajoutez ce qui précède pour travailler côté serveur.
Dans l'application Java, chargez le fichier vue-server-renderer et Bundle et laissez-le dessiner le HTML.
entry-server.js
import { createApp } from './app'
const { app, router, store } = createApp()
router.push(route)
router.onReady(() => {
renderVueComponentToString(app, (err, res) => {
rendered = String(res)
})
})
J'écris un processus pour mettre le HTML obtenu par renderVueComponentToString dans la variable globale rendue.
ScriptEngine Ajoutez une bibliothèque pour utiliser GraalJS avec ScriptEngine de Java.
pom.xml
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js -->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>19.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.graalvm.js/js-scriptengine -->
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>19.2.0</version>
</dependency>
Renderer.java
public String render(String route) throws ScriptException, IOException {
ScriptEngine engine = getEngine();
ScriptContext context = getContext();
Bindings engineScope = engineSetting(engine, context);
engineScope.put("rendered", null); //Déclaration de variable globale
engineScope.put("route", route); //Déclaration de variable globale
engine.eval(read("static/js/server.js"), context);
return context.getAttribute("rendered").toString(); //Obtenir la variable rendue au type String
}
private Bindings engineSetting(ScriptEngine engine, ScriptContext context) throws ScriptException, IOException {
context.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
Bindings engineScope = context.getBindings(ScriptContext.ENGINE_SCOPE);
engine.setContext(context);
engine.eval(
"var process = { env: { VUE_ENV: 'server', NODE_ENV: 'production' }}; this.global = { process: process };",
context);
loadFiles(engine, context); // vue-server-Chargement du moteur de rendu
return engineScope;
}
Vous pouvez déclarer une variable globale avec la méthode put de la classe Bindings et obtenir la valeur avec la méthode getAttribute de la classe ScriptContext.
Renderer.java
private ScriptEngine getEngine() {
return new ScriptEngineManager().getEngineByName("graal.js");
}
private ScriptContext getContext() {
return new SimpleScriptContext();
}
Pour éviter que le côté JS ne devienne un singleton comme décrit dans le Guide VueSSR, ScriptEngine est en train de créer une nouvelle instance à chaque fois qu'il y a une demande.
Dessinez le HTML acquis avec Thymeleaf.
index.html
<body th:utext="${rendered}">
</body>
Du côté Vue, assurez-vous d'inclure l'ID d'élément utilisé pour le dessin.
Les données au moment du dessin initial sont acquises en écrivant JSON dans un fichier HTML. Ceci est réalisé avec thymeleaf.
index.html
<script th:inline="javascript">
/*<![CDATA[*/
window.__INITIAL_STATE__ = /*[[${word}]]*/ {};
/*]]>*/
</script>
J'ai publié un exemple de projet sur github, j'espère donc que vous le trouverez utile.
Il est plus facile de faire du SSR en utilisant Nuxt ou quelque chose comme ça.
Guide de rendu côté serveur Vue.js terwer/spring-vue-ssr
Recommended Posts