[原文链接]http://feclub.cn/post/content/laravel_webpack_vue_boilerplate
考虑 - 决定脚手架依赖
这次的项目是一个管理后台,介于以下两点原因:
- 这个项目最终会交由后端同学维护,所以前端相关流程应该尽量简单且最好基于后端同学熟悉的框架
- 项目前端部分必须有较快的开发效率,不能沿用之前后端同学开发后台时的完全laravel、前后端完全耦合的方法(项目目录可能较为混乱、开发效率低)
所以决定用laravel(后端同学熟悉的后端脚手架) + webpack + vue(入手较为容易的JS框架)
laravel-mix
查看laravel的文档得知laravel 5.5(现在后端项目普遍用的版本)已经内嵌laravel-mix,提供的API支持利用webpack编译vue了。先试试能不能满足我们的要求:
功能总结
- 编译相关:
- .js:包括在.js里引用.vue、编译ES2017+等
- .jsx(react)
- .version(文件hash)
- .sass/.less/.postcss ...
- .copy
- .combine/.bable/.minify
- 性能相关:
- 简单的代码切割:.extract(利用CommonsChunkPlugin但只有names能够灵活配置,意味着一次只能手动指定多个公共引用分割到vendor文件)
- 开发相关:
- .browsersync:多端多浏览器同步与文件监听
- HMR
- Livereload
- 其他:
- .webpackConfig:用其他webpack的配置覆盖默认配置
- .extend:mix扩展
特点总结
优点
- 用laravel-mix的好处当然是上手快,因为laravel-mix的本质是在webpack的基础上再封装一套(供laravel 应用使用的)语法糖。
- laravel-mix可扩展(.extend),可覆盖配置(.webpackConfig),不用限制于其提供的原有的api。
缺点
- 使用的webpack版本受限于laravel-mix的依赖,不能自由升级(当前laravel-mix用的webpack版本是3.4.0)。
- laravel-mix的语法糖提供部分便利的同时又不够强大(相对复杂的配置还是得自己写,一些plugin还是得自己引用),如果对webpack比较熟悉的话,这些功能有些鸡肋。
- 使用laravel-mix进行编译时,出问题了无法马上定位到是:
- 因为自己的配置不符合webpack应有的规则
- 因为自己的配置和laravel-mix的默认配置有冲突还是
- 因为laravel-mix本身有bug
结论
还是直接用webpack吧
laravel + webpack + vue
构思怎么做脚手架
打包编译
大概了解一下,laravel中跟前端关系最大的部分就是route(php)将请求解析给某个controller(php),controller组织数据后结合views/.blade.php(html)来render出一个页面,.blade.php里引用css/js/image等静态资源丰富前端页面展示及完成前端功能。从上可知,从views开始的流程才和前端有较大关系。所以打包编译的过程可以简述成:
- 打包编译js文件(当然webpack在这一步还能打包引用的样式文件)
- 生成引用这些js文件(等其他静态文件)的html
打包编译完成后,只需要将route和controller简单配置好即可。
生产环境(包括测试环境)和开发环境所用前端服务
生产环境不用多说,有现成的服务,只要完成html和所需静态资源的打包编译,即可。
至于开发环境,为了方便本地开发,可以起一个简易node服务来作web服务。
前期准备
- 首先从
https://git.qufenqi.com/CM/component/auto.project.template
(开林搭的一个汽车项目laravel基础框架)copy一份现有的过来。以下简称这个项目的根目录为proot
。 - 创建一个新的仓储,clone下来,将项目根目录下的
.git
文件夹替换到proot
下,可以删掉刚clone下来的新仓储,并把laravel脚手架改名成新仓储的名称。 - 生成APP_KEY,除了以下命令,这一步有两个点要注意:
- 本仓储会gitignore掉APP_KEY所在的.env了,所以需要修改.env.example作为git会追踪的文件,再从.env.example复制一个.env出来。不建议直接去掉git ignore中的.env,因为.env有一部分作用相当于koa-grace server中的server.json。
- 本仓储的laravel的版本是
5.5.3
,与之对应的php版本必须≥7,但大部分同学的Mac自带的php版本并不满足,所以,要么更新本地php(很麻烦),要么找个php版本满足开发机直接操作。cd ${proot} mv .env.example .env php artisan key:generate mv .env .env.example
- 接下来得把你的项目同步到开发机上了,有两种方法(以sublime text 3 为例),一种是利用smb协议,一种是利用SFTP/FTP协议:
- samba:项目推远程分支 -> 到开发机上clone并pull该远程分支 -> 打开Finder -> command + k -> 输入
smb://${开发机ip}
-> 连接 -> 输入用户名密码 -> 点自己的宗卷 -> 好 -> 关闭Finder -> 打开sublime -> 左上角菜单File -> Open -> 左侧Share底下的开发机ip -> 找到自己宗卷下的对应项目。 - sublime + sftp插件,此方法会在
proot
下生成一个sftp-config.json
文件,必须在.gitignore追加此文件名,告知git忽略此文件。
- samba:项目推远程分支 -> 到开发机上clone并pull该远程分支 -> 打开Finder -> command + k -> 输入
目录
laravel仓储
├─ ...
├─ public // 编译产出的静态文件目录
│ ├─ css
│ ├─ fonts
│ ├─ image
│ └─ js
├─ resources
│ ├─ assets // 代码源文件
│ ├─ build // 编译相关
│ ├─ ...
│ └─ views // HTML模板文件、
│ // 编译生成的HTML文件、
│ // laravel自用的HTML文件
├─ routes // laravel路由文件
├─ ...
开发/生产的编译步骤概述
需要注意的点
- 开发时起的server,需要处理两类请求,一类是偏向前端的请求,比如请求doc、静态文件等;一类是偏向后端的,比如接口。后者往往需要调用服务或和数据库交互,本地环境不支持,所以得代理到测试环境/线上环境。
- 多入口需要做一套入口生成规则:
- 哪些是手动配置的入口
- 哪些是可以直接遍历文件目录而产生的入口
- 遍历文件目录时去去除哪些入口
- 如果不用多线程编译(parallel-webpack),html-webpack-plugin等跟入口(entry)相关的插件或配置可以直接配置到webpack.config里面。但是如果要用到多线程编译,需要将webpack.config(不包含入口相关插件/配置)按照一定数量,正常是cpu数或者cpu数-1(要不会很卡),将webpack.config分成多个子配置,然后再往子配置里加入入口相关的插件或配置。
- 利用webpack-dev-middleware和webpack-hot-middleware打开HMR功能的时候,记得把express的静态文件配置放在对上面两个中间件的引用之后,否则HMR需要用到的通信文件将会落到你的静态文件目录上,结果404。
- HMR功能依赖于webpack-dev-middleware,这是一个默认将文件写在内存中而不写在磁盘里的中间件,启用后会将html-webpack-plugin生成的模板文件一并写进内存中。所以配置时记得加上:
当然html-webpack-plugin的作者还写了个html-webpack-harddisk-plugin,是可以强行将模板文件写到磁盘中的,但有点鸡肋。writeToDisk(filePath) { return /blade\.php$/.test(filePath); }
BUG和待优化
- 启用HMR时,首次编译后用浏览器打开页面会报错,目前是在其首次编译后的钩子里重新触发一次编译。
- 尽管使用了默认不写磁盘的webpack-dev-middleware,但是HMR产生的部分通信文件仍然会写到编译产出目录下,目前是先ignore掉,并在为生产环境编译(npm run build)的时候进行一次清除。
- 生产环境生成的主文件有几个是MB级别的,需要优化。
- 使用多线程编译(parallel-webpack)后用浏览器打开页面会报错,表现是一串字符串乱码放在了注释外。
- 可以用DllPlugin + DllReferencePlugin将公共引用(vue、vue-router等)单独编译出结果,以供正常编译的直接引用。
- hard-source-webpack-plugin
- 。。。
总结
读懂文档搞清楚流程永远比动手实践来得容易,且行且珍惜。