项目之前一直在电脑本地做的,废弃了很久才想起来部署到服务器上。因为是第一次用vue,发布时遇到了很多问题,用了5个小时才解决掉。
主要问题有两个:
- 不清楚如何发布vue项目,服务器上npm run dev只能本地测试使用。
- 数据接口的代理加载不出资源。
服务器环境:
linux 7.0 x86_64
npm 6.1.0
vue 2.9.6
docker 17.12.0-ce
开放端口8003(前端)和3000(接口)
注:以下过程为已安装好npm/vue-cli/docker且数据接口正常工作为前提。
vue在本地测试运行时是使用 $ npm run dev。
但vue环境真正的部署是要通过webpack构建成html后通过nginx等web服务解析工作的。
首先看vue的配置文件config/index.js,生产环境部署vue时网上的案例常遇到资源加载404的问题,根本原因是在构建配置时“assetsPublicPath”的问题,webpack会根据这一项配置修改资源引用的路径。
module.exports = {
...
build: {
index: path.resolve(__dirname, '../dist/index.html'),
assetsRoot: path.resolve(__dirname, '../dist'),
assetsSubDirectory: 'static',
assetsPublicPath: '/',
...
}
}
如果是配置“assetsPublicPath: '/'”,那么就要把构建出来的内容放到nginx的html根目录下(不是服务器的根目录),这样资源才能正常加载。因为服务器没有直接安装nginx,所以借用了docker环境。
$ sudo npm run build // vue项目打包
打包后生成的html文件是在项目的dist目录下,会产生一个index.html和static文件夹。也可以直接在计算机本地打包后,只将dist文件夹传到服务器上。
第二个问题是我的vue项目中请求数据使用了代理,即.get('/api/......'),而不是.get('http://......')。
在本地测试时可以直接在vue的配置文件config/index.js的dev部分配置代理,用/api替换掉了 http: //localhost:3000/。
module.exports = {
dev: {
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {
'/api': {
target: 'http://localhost:3000/',
changeOrigin: true,
pathRewrite: {
'^/api': '/',
},
},
},
...
}
但在服务器上该方法不适用,所以如果不修改nginx配置的话,是无法请求到/api/......的数据的。创建一个nginx配置文件default.conf,内容如下:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ^~/api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_set_header Host $host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://127.0.0.1:3000;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
关键部分在于 location ^~/api/{...},是将原本写在index.js配置文件中的代理用nginx来实现。当nginx接收到 http: //xxx.xxx.xxx.xxx:8003/api/... 的请求时自动转发到3000端口。
准备完毕后,docker拉取nginx的镜像,我使用的版本是nginx@latest。不用编写dockerfile,直接实例化容器:
$ sudo docker run -d --name vue -p 8003:80 -v /mnt/donghan/default.conf:/etc/nginx/conf.d/default.conf -v /mnt/donghan/vue/dist:/usr/share/nginx/html nginx:latest
在这里要注意的几个参数:
-p 8003:80 // 容器内的80端口映射到外部主机8003端口
-v /mnt/donghan/vue/dist:/usr/share/nginx/html // 将vue生成的html文件直接导入到容器中nginx的根目录下,前面的是我服务器上存放dist的目录
-v /mnt/donghan/default.conf:/etc/nginx/conf.d/default.conf // 导入nginx环境配置文件
经过这么一折腾,vue才能够在服务器上真正部署起来。整个流程做下来还是踩了不少坑,网上的那些博客解决方案都很零散。在没有描述详细服务器环境的情况下,很难根据一句话两句话搞定问题。所以在这里也希望大家以后写博客的时候能更详细的说说服务器上的环境和问题的描述,一起加油。
题外话
这次做的是express+vue+mongodb的一个站,基本核心都是nodejs,然!而!就在部署完之后我得到了这个很难过的消息:「Node之父Ryan Dahl说:Node 失误太多无力回天,Deno 前景明朗。」
nodejs零零散散接触了有一年,现在已经慢慢熟悉了,居然有种老友诀别之感。但也确实也存在各种各样的问题,Ry的PPT上的这张图相信大家都深有感触。
希望下一代的Nodejs——Deno能越走越远,也祝js家族更加壮大。