Laravel-Vue-SSR-SPA 服务端渲染 / 单页面渲染实现骨架
Laravel-Vue-SSR-SPA
提供服务端渲染/单页面渲染实现骨架, 同时集成webpack打包构建 MD5文件名/gzip 实现, 内置 vue-router,vuex, axios等 vue 套件, 提供 PC端 SSR 渲染方案, Admin 前后端分离单页面方案, Mobile 前后端分离单页面方案等三种常见方案;
项目地址, 欢迎star
项目需求
基于 Laravel 和 Vue 提供的强大的功能组合, 并根据已有项目实践经验, 提供完整的 laravel-vue 集成方案, 帮助快速搭建 Laravel-vue 集成项目,主要解决如下问题
-
SSR服务端渲染
Laravel-vue 服务端渲染, 即 Laravel SSR 方案, 利于搜索引擎的 SEO 搜索抓取;
-
SPA前后端分离
Laravel-vue SPA框架, 即前后端分离下的单页面路由方案, 前后端通过 api 实现交互, 可以提供更加灵活的开发选择以及更高的开发效率, 同时潜在的一个优势是 app 可以与移动端h5共用同一套 api 体系,极大节省后期业务开发的重复工作;
-
静态资源缓存
熟悉前端开发的同学一定碰到过需要解决浏览器缓存静态资源造成的问题, 比如 js/css 等;
在 weback 的帮助下, js的编译提供 md5 文件命名方案, 可以有效的避免静态文件缓存造成的问题; -
gzip 文件压缩
在前端优化的方案里, 开启服务端 gzip压缩是一种非常好的减少资源请求的方案;
同样的, 在 webpack 里使用compression-webpack-plugin
输出 gzip 文件包, 实现 js/css 文件体积非常明显压缩(约60%-80%); -
移动端适配问题
如何解决移动端适配的问题是衡量一个移动端用户体验的基础判断标准,框架采用淘H5页面的终端适配方案,
文章详见https://github.com/amfe/article/issues/17
, 以基础 1rem=75px,进行适配, 对内置css 样式均进行了适配优化; -
内置 UI 框架
6.1 admin工程内置 iview 作为后台UI框架, 蚂蚁金服的AntV/G2作为报表插件, 这两者都提供了优雅的界面设计和丰富全面的文档说明
6.2 mobile工程内置Cube-UI框架, 同样的, 你也可以使用 vux 框架作为移动端 UI框架
6.3 PC 端内置iview, iview 作为优秀的后台 UI 框架, 在此仅作为内置示例, 你可以选择自己喜欢的 UI 框架作为替换
laravel服务端渲染基于spatie/laravel-server-side-rendering, 感谢!
方案集成
- home 即前端用户可见页面, 采用 laravel-vue 服务端渲染方案 SSR
- admin 项目采用前后端分离架构 SPA
- mobile 项目采用前后端分离架构 SPA
环境需求
-
- php 环境
确保你已经安装composer
-
- nodejs 环境
确保你已经安装node,推荐安装最新稳定版node
node 内置 npm , 已安装完成 node 即可, 无需单独安装 npm
安装完成, 检查node版本>8.0
node -v
npm 版本>5.3
npm -v
Install, 只需2步即可
1. clone代码,安装依赖
-
1.1 clone或者下载项目代码, git clone
git clone https://github.com/symenywong/laravel-vue-ssr-spa.git
项目 clone 下来后执行如下操作, 进入当前文件夹, 例如, 当前项目文件夹为 laravel-vue-ssr-spa
cd laravel-vue-ssr-spa
-
1.2 安装前端依赖
npm install
- 1.3 安装composer 依赖
composer install
- 1.4 根目录手动修改.env 文件, 添加如下配置
NODE_PATH=/usr/local/bin/
2.现在运行服务,检查是否正确启动
-
2.1 在项目目录执行, 启动 php 服务, 查看
http://localhost:8000/
php artisan serve & npm run watch
此时浏览器打开 http://localhost:8000/, 查看各工程界面
注意: 如果发现出现找不到'index/js/entry-client.js', 那么先执行下npm run build 构建一下文件
-
2.3 buid 生产环境, 在项目目录执行, 启动 webpack 自动构建服务, 生成 jss、css以及对应的 gzip 压缩文件,
由于开启 md5文件名和 gzip 压缩, 此处需要等待一段时间
npm run build
全部准备工作已经完成, 现在可以愉快的开始写代码了!
了解更多? 请阅读以下内容
项目目录
|--app
| |--Http
| | |--Controllers
|--bootstrap
|--config
|--database
|--config
|--node_modules
|--public
|--resources // 资源文件
| |--assets // vue 模板渲染
| | |--admin
| | |--home
| | |--mobile
| |--sass // sass style
| | |--admin
| | |--home
| | |--mobile
| |--views // laravel 解析blade模板
| | |--admin
| | |--home
| | |--mobile
|--routes
|--storage
|--tests
|--vendor
|--resources
|--md5File.js
|--packaje.json
|--webpack.config.js
|--webpack.mix.js
...
npm script 命令/package.json 说明
-
项目内置命令如下
"scripts": { "dev": "npm run development", "build": "npm run production && npm run copy", "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=./webpack.config.js", "watch": "node ./md5File.js --env=dev && npm run development -- --watch", "watch-poll": "npm run watch -- --watch-poll", "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js", "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=./webpack.config.js", "ii": "npm install --registry https://registry.npm.taobao.org", "copy": "node ./md5File.js" },
- npm run watch 启动dev开发环境, 并启用动态热加载, sass 预处理等任务
- npm run build 执行生产环境下的编译打包任务, 执行完成后将生成 js与css 打包压缩文件
- npm run ii 墙内用户执行npm 安装失败, 可选择此命令切换taobao 镜像源安装
webpack 说明
1. webpack.config.js 说明
laravel-mix本身内置 webpack 打包方案, 但是存在如下问题需要解决
-
- 生产环境每次生成的 js/css 文件名称相同, 会造成浏览器缓存, 无法有效避免缓存造成的影响, 因此采用 webpack 打包时, 对文件名进行 md5 扩展, 文件变动则随之生成新的 md5 文件名称
-
- js/css静态资源请求,造成用户等待时间过长, 如何压缩文件体积, 减少资源请求, 将会很大程度的提升用户体验, 框架内置 compression-webpack-plugin 对生成的文件进行 gzip 压缩, 同时生成 非压缩文件与压缩文件
,需要注意的是此方案需要服务端开启 gzip 请求配置
- js/css静态资源请求,造成用户等待时间过长, 如何压缩文件体积, 减少资源请求, 将会很大程度的提升用户体验, 框架内置 compression-webpack-plugin 对生成的文件进行 gzip 压缩, 同时生成 非压缩文件与压缩文件
2. webpack.mix.js 说明
框架内置3套工程方案
-
- PC 内置插件
> iview > vue-router > vuex > axios
-
- admin 内置插件
> iview > vue-router > vuex > axios
-
- mobile 内置插件
> cube-ui > vue-router > vuex > axios
//home mix.js('resources/assets/home/entry-client.js', 'public/index/js') .js('resources/assets/home/entry-server.js', 'public/index/js') .sass('resources/sass/home/app.scss', 'public/index/css') //admin mix.js('resources/assets/admin/app.js', 'public/admin/js') .sass('resources/sass/admin/app.scss', 'public/admin/css'); //mobile mix.js('resources/assets/mobile/app.js', 'public/mobile/js') .sass('resources/sass/mobile/app.scss', 'public/mobile/css');
注意事项
-
- SSR工程无法使用 router-link 进行跳转: PC 端前端渲染工程 SSR 内置集成 vue-router分发页面, 但如果使用 进行跳转, 使用的是 vue 单页跳转逻辑, 与服务端渲染逻辑冲突, 因此请避免使用 标签进行跳转, a 链接跳转则无此问题;
传送门
spatie/laravel-server-side-rendering
本作品采用《CC 协议》,转载必须注明作者和本文链接
性能咋样
@96qbhy
@symeny 恕我直言,性能肯定不忍直视。因为我之前也写过类似的方案。我写了两个方案,一个是用 node 来渲染 SPA 视图,然后 php 拿到后返回给客户端,这中间php调用node就要一大笔开销了。另一个方案是 php 的 v8js 扩展,这个还好一点,减少了一些开销,但是仍然不乐观。总结不论哪个方案,性能表现都不适合线上业务使用,这种同构方案做技术探索就可以了,线上还是该 SPA 就 SPA, 该 blade 就 blade,一定要服务端渲染 SPA 的话还是 用 nodejs 好,虽然性能也不是很好,但是也比 用 php + node 渲染 SPA 好点。
另外如果服务端渲染的目的是用来解决 SEO 问题的话,完全可以用 php 判断一下是不是爬虫来爬数据了 ,是的话返回对应的 html 文档,不是的话返回SPA页面,渲染就让前端浏览器自己完成,我个人觉得这个方案应该是比较折中的SEO + SPA 解决方案了。
@96qbhy
你应该是对其中的过程有些误解, build 生产环境全程未使用 nodejs, 只在 watch开发阶段借助 node + webpack进行编译 vue js 而已, 实际生产环境中是 Laravel 控制器 将数据注入 html, 返回值视图 view, 在接收到页面后js将数据由 vue 渲染dom , 并未有使用过 node的任何过程
@symeny 给你点个赞,那么我请问
这个由 vuejs 渲染 dom,是指的在浏览器渲染码?不是浏览器的话?用什么东西来执行 vuejs 呢 ?
赞!
@symeny 数据怎么渲染出来的?php执行js应该是需要用到v8js吧,如果真的是使用v8js的话性能确实不怎么样
@yanthink 选择不多,v8js 和 node 或者 其他语言的v8引擎(例如go的v8),不论哪种性能都不高,体验反而会下降。