SSR с Symfony и Vue.js
Мы все больше и больше работаем как с серверным каркасом типа Symfony, так и с клиентским каркасом типа Vue.js. Кроме того, мы находим много статей на эту тему. Чаще всего задается вопрос, как сделать эти технологические решения эффективными.
Это, читая статью о среда кто представляет реализацию SSR (рендеринга на стороне сервера) view.js на сервере Laravel, который я сказал себе: «А почему бы не сделать это в Symfony?».
Symfony и Vue.js первая часть
Во-первых, я приглашаю вас установить Symfony 4, следуя доступным инструкциям здесь ,
У вас должен быть проект, который выглядит так:
your-project / ├── assets / ├── bin / │ └── console ├── config / │ ├── bundles.php │ ├── пакеты / │ ├── rout.yaml │ └── услуги. yaml ├── public / │ └── index.php ├── src / │ ├── ... │ └── Kernel.php ├── шаблоны / ├── тесты / ├── переводы / ├── var / └── vendor /
Первое, что нужно сделать, это установить веточку и аннотации:
композитор требует аннотации композитор требует ветку
Это позволит вам создать ваш первый контроллер в файле src / Controller / DefaultController.php
<? php namespace App \ Controller; использовать Symfony \ Component \ HttpFoundation \ Response; используйте Symfony \ Component \ Routing \ Annotation \ Route; использовать Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller; DefaultController расширяет Controller {/ ** * @Route ("/") * / public function number () {return $ this -> render ('home.html.twig'); }}
И добавьте свой шаблон ветки в templates / home.html.twig
<! DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title> {% block title%} Добро пожаловать! {% Endblock%} </ title> {% block stylesheets%} {% endblock %} </ head> <body> {% block body%} <div id = "app"> HI </ div> {% endblock%} {% block javascripts%} {% endblock%} </ body> </ HTML>
Теперь мы добавим часть view.js, используя снова Webpack от Symfony. Вы найдете документацию здесь ,
Мы сделаем очень простую конфигурацию для настройки view.js. Вы должны положить в свой файл webpack.config.js
var Encore = require ('@ symfony / webpack-encore'); Еще // директория проекта, где будут храниться скомпилированные ресурсы. setOutputPath ('public / build /') // публичный путь, используемый веб-сервером для доступа к предыдущему каталогу. setPublicPath ('/ build'). addEntry ('app', './assets/js/app.js'). cleanupOutputBeforeBuild (). enableSourceMaps (! Encore. isProduction ()). enableVueLoader (); модуль. экспорт = бис. getWebpackConfig ();
Затем мы добавим компонент Vue.js.
В папке активов я приглашаю вас создать папку js. Внутри этой папки вы можете создать компонент view.js. В файле assets / js / components / App.vue
<template> <div id = "app"> {{message}} </ div> </ template> <script> экспорт по умолчанию {data () {return {message: 'Hello World'}}} </ script>
Затем вы можете создать приложение view.js в файле assets / js / app.js, которое является точкой входа вашего приложения view.js.
импортировать приложение из ./components/App.vue '; импортировать вид из «вида»; новый вид ({el: '#app', render: h => h (App)});
В вашем файле ветки вы должны вызвать сгенерированный файл webpack, добавив его в блок javascript.
<script src = "{{asset ('build / app.js')}}"> </ script>
Вот и все, вам нужен сайт Symfony 4, который показывает вам Hello world in sight.js Если вы отключите JavaScript, у вас будет отображаться только привет.
Сделать ССР
Интерес SSR заключается не в том, чтобы интерпретировать JavaScript на клиенте во время первого вызова, а на вашем сервере. Это позволяет генерировать страницу напрямую, и повысить производительность отображения, а также в SEO.
Обычно SSR выполняется непосредственно на сервере javascript. Для этого есть библиотеки. Я призываю вас прочитать эту статью, в которой говорится о ССР по реакции ,
Но здесь мы хотим сохранить наш сервер Symfony (по многим причинам, которые я не буду объяснять).
Прежде всего мы создадим два входных файла для view.js, потому что мы должны вызывать разные функции для отображения на клиенте и на сервере.
Начнем с создания файла assets / js / entry-client.js, который позволяет «монтировать» приложение по id #app
import {createApp} из './app' createApp (). $ mount ('#app');
Затем вам нужно создать файл assets / js / entry-server.js, который позволяет вам преобразовать компонент view.js в строку символов, которую затем можно интерпретировать в php.
import {createApp} из './app' renderVueComponentToString (createApp (), (err, res) => {print (res);});
И в итоге мы обновляем файл assets / js / app.js, который позволяет экспортировать приложение, чтобы оно могло быть прочитано двумя предыдущими файлами.
импортировать приложение из ./components/App.vue '; импортировать вид из «вида»; функция экспорта createApp () {возврат нового представления ({render: h => h (App)}); }
Вам нужно изменить конфигурацию вашего веб-пакета, чтобы сгенерировать два входных файла.
var Encore = require ('@ symfony / webpack-encore'); Еще // директория проекта, где будут храниться скомпилированные ресурсы. setOutputPath ('public / build /') // публичный путь, используемый веб-сервером для доступа к предыдущему каталогу. setPublicPath ('/ build'). addEntry ('entry-client', './assets/js/entry-client.js'). addEntry ('entry-server', './assets/js/entry-server.js'). cleanupOutputBeforeBuild (). enableSourceMaps (! Encore. isProduction ()). enableVueLoader (); модуль. экспорт = бис. getWebpackConfig ();
Если вы измените блок javascript в вашем файле templates / home.html.twig этим.
<script src = "{{asset ('build / entry-client.js')}}"> </ script>
Вы должны иметь точно такой же результат, как и раньше.
Сейчас мы будем внедрять SSR. Проще говоря, мы собираемся загрузить библиотеку V8js, которая позволяет PHP использовать механизм интерпретации javascript.
Для этого вам необходимо установить расширение PHP V8js который затем позволяет вам использовать класс V8Js в вашем коде PHP.
Что мы будем делать, это получить возвращенный файл entry-server.js в строковом формате и поместить его непосредственно в шаблон.
Давайте добавим приватную функцию в нашем контроллере Symfony, которая позволит сделать это (чтобы очистить его, это должно быть сделано в сервисе).
приватная функция renderJs () {$ renderer_source = file_get_contents (__DIR__. '/../../modules_node/view-server-renderer/basic.js'); $ app_source = file_get_contents (__DIR__. '/../../public/build/entry-server.js'); $ v8 = new \ V8Js (); ob_start (); $ v8 -> executeString ('var process = {env: {VU_ENV: "сервер", NODE_ENV: "производство"}}; this.global = {process: process};'); $ v8 -> executeString ($ renderer_source); $ v8 -> executeString ($ app_source); return ob_get_clean (); }
Осталось только извлечь результат из контроллера и отправить его в шаблон.
/ ** * @Route ("/") * / публичная функция home () {$ ssr = $ this -> renderJs (); return $ this -> render ('home.html.twig', ['ssr' => $ ssr]); }
И в веточку вы можете поместить необработанное значение ssr.
<! DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title> {% block title%} Добро пожаловать! {% Endblock%} </ title> {% block stylesheets%} {% endblock %} </ head> <body> {% block body%} {{ssr | raw}} {% endblock%} {% block javascripts%} {% endblock%} </ body> </ html>
Если все в порядке, ваша страница будет отображать «Hello World» прямо в вашем исходном коде.
заключение
Это довольно просто настроить систему в большем масштабе и, следовательно, иметь мощь Javascript Framework даже при первом вызове.
Вы найдете весь код на моем github здесь ,
Js на сервере Laravel, который я сказал себе: «А почему бы не сделать это в Symfony?