本文发布于个人我的网站: http://wintc.top/article/29,转载请注明出处。
使用Vue作先后端分离项目时,一般前端是单独部署,用户访问的也是前端项目地址,所以前端开发人员颇有必要熟悉一下项目部署的流程与各种问题的解决办法了。Vue项目打包部署自己不复杂,不过一些前端同窗可能对服务器接触很少,部署过程当中仍是会遇到这样那样的问题。本文介绍一下使用nginx服务器代理前端项目的方法以及项目部署的相关问题,内容概览:css
个人是ubuntu系统,linux系统的操做都差很少。没有服务器怎么破?html
若是你只是想体验一下,能够尝试各大厂的云服务器免费试用套餐,好比华为云免费试用,本文相关操做便是在华为云上完成的。不过若是想时常练练手,我以为能够购买一台云服务器,好比上面的华为云或者阿里云都还挺可靠。个人我的网站就是部署在阿里云,你能够点击个人推广连接进行购买,近期有活动首次购买不到100块/年。前端
轻装简行,这部分不做过多赘述,毕竟网上相关教程一大堆。vue
# 安装,安装完成后使用nginx -v检查,若是输出nginx的版本信息代表安装成功 sudo apt-get install nginx # 启动 sudo service nginx start
启动后,正常状况下,直接访问http://服务器ip 或 http://域名 (本文测试用的服务器没有配置域名,因此用ip,就本文而言,域名和ip没有太大区别)应该就能看到nginx服务器的默认页面了——若是访问不到,有多是你的云服务器默认的http服务端口(80端口)没有对外开放,在服务器安全组配置一下便可。linux
查看nginx的配置,linux系统下的配置文件一般会存放在/etc目录下,nginx的配置文件就在/etc/nginx文件夹,打开文件/etc/nginx/sites-available/default(nginx能够有多个配置文件,一般咱们配置nginx也是修改这个文件):webpack
能够看到默认状况下,nginx代理的根目录是/var/www/html,输入 http://服务器ip会访问这个文件...,会根据index的配置值来找默认访问的文件,好比index.html、index.htm之类。nginx
咱们能够更改root的值来修改nginx服务代理的文件夹:git
建立文件夹/www,并建立index.html,写入"Hello world"字符串github
mkdir /www echo 'Hello world' > /www/index.html
再次访问页面,发现页面内容已经变成了咱们建立的index.html:web
默认状况下,使用vue-cli建立的项目,package.json里的script应该已经配置了build指令,直接执行yarn build 或者 npm run build便可。
咱们使用nginx部署Vue项目,实质上就是将Vue项目打包后的内容同步到nginx指向的文件夹。以前的步骤已经介绍了怎样配置nginx指向咱们建立的文件夹,剩下的问题就是怎么把打包好的文件同步到服务器上指定的文件夹里,好比同步到以前步骤中建立的/www。
同步文件能够在git-bash或者powershell使用scp指令,若是是linux环境开发,还可使用rsync指令:
scp -r dist/* root@117.78.4.26:/www 或 rsync -avr --delete-after dist/* root@117.78.4.26:/www
注意这里以及后续步骤是root使用用户远程同步,应该根据你的具体状况替换root和ip(ip换为你本身的服务器IP)。
为了方便,能够在package.json脚本中加一个push命令,以使用yarn为例(若是你使用npm,则push命令中yarn改为npm run便可):
"scripts": { "build": "vue-cli-service build", "push": "yarn build && scp -r dist/* root@117.78.4.26:/www" },
这样就能够直接执行yarn push 或者npm run push直接发布了。不过还有一个小问题,就是命令执行的时候要求输入远程服务器的root密码(这里使用root来链接远程的,你能够用别的用户,毕竟root用户权限过高了)。
为了不每次执行都要输入root密码,咱们能够将本机的ssh同步到远程服务器的authorized_keys文件中。
同步ssh key到远程服务器,使用ssh-copy-id指令同步
ssh-copy-id -i ~/.ssh/id_rsa.pub root@117.78.4.26
输入密码后,以后再次同步就不须要输入密码了。其实ssh_key是同步到了服务器(此处是root用户家目录)~/.ssh/authorized_keys文件里:
固然你也能够手动复制本地~/.ssh/id_rsa.pub(注意是pub结尾的公钥)文件内容追加到服务器~/.ssh/authorized_keys的后面(从命名能够看出该文件能够存储多个ssh key)
注意: 这里全程使用的是root用户,因此没有文件操做权限问题。若是你的文件夹建立用户不是远程登陆用户,或许会存在同步文件失败的问题,此时须要远程服务器修改文件夹的读写权限(命令 chmod)。
建立了一个测试项目(点击本连接能够在gihub查看)试一下,打包、文件上传一句指令搞定啦:
访问一下,果真看到了咱们熟悉的界面:
至此,常规状况下发布Vue项目就介绍完了,接下来介绍非域名根路径下发布以及history路由模式发布方法。
有时候同一台服务器同一端口下可能会根据目录划分出多个不一样的项目,好比咱们但愿项目部署到http://a.com/test下,这样访问http://a.com/test访问到的是项...,而非test前缀的地址会访问到其它项目。此时须要修改nginx配置以及Vue打包配置。
只须要添加一条location规则,分配访问路径和指定访问文件夹。咱们能够把/test指向以前建立的/www文件夹,这里由于文件夹名称和访问路径不一致,须要用到alias这个配置:
若是文件夹名称与访问路径一致都为test,那这里能够用root来配置:
这里要将/test配置放到/以前,意味着在路由进入的时候,会优先匹配/test。若是根路径/下的项目有子路由/test,那http://xxxx/test只会访问到/ww...,而不会访问该子路由。
为了解决打包后资源路径不对的问题,须要在vue.config.js中配置publicPath,这里有两种配置方式,分别将publicPath配置为./和/test:
更新nginx配置,发布后便可正常访问啦。这里的两种配置方式是有区别的,接下来会看一下它们的区别。
若是不进行项目配置,直接发布访问会出现JS、CSS等资源找不到致使页面空白的问题:
该问题缘由是资源引用路径不对,页面审查元素能够看到,页面引用的js都是从根路径下引用的:
查看打包后的文件结构,能够看到js/css/img/static等资源文件是与index.html处于同级别的:
对于两种配置方式,看看都是怎么生效的:
两种配置均可以正确地找到JS、CSS等资源。不过还有个问题,那就是static中的静态资源依旧会找不到。
由于在打包过程当中,public下的静态资源都不会被webpack处理,咱们须要经过绝对路径来引用它们。当项目部署到非域名根路径上时,这点很是头疼,你须要在每一个引用的URL前面加上process.env.BASE_URL(该值即对应上文配置的publicPath),以使得资源能被正常访问到。咱们能够在main.js把这个变量值绑定到Vue.prototype,这样每一个Vue组件均可以使用它:
Vue.prototype.$pb = process.env.BASE_URL
在模板中使用:
<img :src="`${pb}static/logo.png`">
然而,更加头疼而且没有良好解决方案的问题是在组件style部分使用public文件夹下的静态资源。
关于静态资源的问题,vue-cli的推荐是尽可能将资源做为你的模块依赖图的一部分导入(即放到assets中,使用相对路径引用),避免该问题的同时也带来其它好处:
默认状况下,Vue项目使用的是hash路由模式,就是URL中会包含一个#号的这种形式。#号以及以后的内容是路由地址的hash部分。正常状况下,当浏览器地址栏地址改变,浏览器会从新加载页面,而若是是hash部分修改的话,则不会,这就是前端路由的原理,容许根据不一样的路由页面局部更新而不刷新整个页面。H5新增了history的pushState接口,也容许前端操做改变路由地址可是不触发页面刷新,history模式即利用这一接口来实现。所以使用history模式能够去掉路由中的#号。
在vue-router路由选项中配置mode选项和base选项,mode配置为'history';若是部署到非域名根目录,还须要配置base选项为前文配置的publicPath值(注意:此状况下,publicPath必须使用绝对路径/test的配置形式,而不能用相对路径./)
对于history模式,假设项目部署到域名下的/test目录,访问http://xxx/test/about的时候,服务器会去找/test指向的目录下的about子目录或文件,很显然由于是单页面应用,并不会存在a这个目录或者文件,就会致使404错误:
咱们要配置nginx让这种状况下,服务器可以返回单页应用的index.html,而后剩下的路由解析的事情就交给前端来完成便可。
这句配置的意思就是,拿到一个地址,先根据地址尝试找对应文件,找不到再试探地址对应的文件夹,再找不到就返回/test/index.html。再次打开刚才的about地址,刷新页面也不会404啦:
非域名根目录下部署,首先确定要配置publicPath。须要注意的点前面其实已经提过了,就是这种状况下不能使用相对路径./或者空串配置publicPath。为何呢?
缘由是它会致使router-link等的表现错乱,使用测试项目分别使用两种配置打包发布,审查元素就能看出区别。在页面上有两个router-link,Home和About:
两种配置打包后的结果以下。
publicPath配置为相对路径的router-link打包后地址变成了相对根域名下地址,很明显是错误的,因此非域名根路径部署应该将publicPath配置为完整的前缀路径。
关于Vue项目发布的相关问题就先总结这么多,几乎在每一步都踩过坑才有所体会。 写博客很累,不过收获也不少,仍是要坚持;有时候别人转载本身的原创文章也不标明出处,居然将写文章日期改得比原创还早,有点心累。本文中使用到的图片都加了个本身的水印,是前端实现的,原理也很简单,以后写一篇简短的文章分享一下。(完)