Vue项目打包部署总结配合nginx部署

news2024/11/29 12:44:54

你可能还想了解:https://blog.csdn.net/weixin_52901235/article/details/129437990?spm=1001.2014.3001.5502

使用Vue做前后端分离项目时,通常前端是单独部署,用户访问的也是前端项目地址,因此前端开发人员很有必要熟悉一下项目部署的流程与各类问题的解决办法了。Vue项目打包部署本身不复杂,不过一些前端同学可能对服务器接触不多,部署过程中还是会遇到这样那样的问题。本文介绍一下使用nginx服务器代理前端项目的方法以及项目部署的相关问题,内容概览:

一、准备工作——服务器和nginx使用


1. 准备一台服务器

我的是ubuntu系统,linux系统的操作都差不多。没有服务器怎么破?

如果你只是想体验一下,可以尝试各大厂的云服务器免费试用套餐,比如华为云免费试用,本文相关操作即是在华为云上完成的。不过如果想时常练练手,我觉得可以购买一台云服务器,比如上面的华为云或者阿里云都还挺可靠。

2. nginx安装和启动

轻装简行,这部分不作过多赘述,毕竟网上相关教程一大堆。

# 安装,安装完成后使用nginx -v检查,如果输出nginx的版本信息表明安装成功

sudo apt-get install nginx

# 启动

sudo service nginx start

启动后,正常情况下,直接访问http://服务器ip 或 http://域名 (本文测试用的服务器没有配置域名,所以用ip,就本文而言,域名和ip没有太大区别)应该就能看到nginx服务器的默认页面了——如果访问不到,有可能是你的云服务器默认的http服务端口(80端口)没有对外开放,在服务器安全组配置一下即可。

3. 了解nginx: 修改nginx配置,让nginx服务器代理我们创建的文件

查看nginx的配置,linux系统下的配置文件通常会存放在/etc目录下,nginx的配置文件就在/etc/nginx文件夹,打开文件/etc/nginx/sites-available/default(nginx可以有多个配置文件,通常我们配置nginx也是修改这个文件):

可以看到默认情况下,nginx代理的根目录是/var/www/html,输入 http://服务器ip 会访问这个文件夹下的文件,会根据index的配置值来找默认访问的文件,比如index.html、index.htm之类。

我们可以更改root的值来修改nginx服务代理的文件夹:

  1. 创建文件夹/www,并创建index.html,写入"Hello world"字符串

mkdir /www
echo'Hello world' > /www/index.html​
  1. 修改root值为 /www

  1. sudo nginx -t 检查nginx配置是否正确

  1. 加载nginx配置:sudo nginx -s reload

再次访问页面,发现页面内容已经变成了我们创建的index.html:

二、Vue项目打包同步文件到远程服务器


1. 打包

默认情况下,使用vue-cli创建的项目,package.json里的script应该已经配置了build指令,直接执行yarn build 或者 npm run build即可。

2. 同步到远程服务器

我们使用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文件中。

3. 同步ssh key

  1. 生成ssh key:使用git bash或者powershell执行ssh-keygen可以生成ssh key。会询问生成的key存放地址,直接回车就行,如果已经存在,则会询问是否覆盖:

  1. 同步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打包配置。

1. nginx配置

只需要添加一条location规则,分配访问路径和指定访问文件夹。我们可以把/test指向之前创建的/www文件夹,这里因为文件夹名称和访问路径不一致,需要用到alias这个配置:

如果文件夹名称与访问路径一致都为test,那这里可以用root来配置:

这里要将/test配置放到/之前,意味着在路由进入的时候,会优先匹配/test。如果根路径/下的项目有子路由/test,那http://xxxx/test只会访问到/www里的项目,而不会访问该子路由。

2. 项目配置

为了解决打包后资源路径不对的问题,需要在vue.config.js中配置publicPath,这里有两种配置方式,分别将publicPath配置为./和/test:

更新nginx配置,发布后即可正常访问啦。这里的两种配置方式是有区别的,接下来会看一下它们的区别。

如果不进行项目配置,直接发布访问会出现JS、CSS等资源找不到导致页面空白的问题:

该问题原因是资源引用路径不对,页面审查元素可以看到,页面引用的js都是从根路径下引用的:

查看打包后的文件结构,可以看到js/css/img/static等资源文件是与index.html处于同级别的:

对于两种配置方式,看看都是怎么生效的:

  1. publicPath配置为./, 打包后资源引用路径为相对路径:

  1. publicPath配置为/test,打包后资源相对路径为从域名根目录开始的绝对路径:

  1. 两种配置都可以正确地找到JS、CSS等资源。不过还有个问题,那就是static中的静态资源依旧会找不到。

3. 绝对路径引用的静态资源找不到的问题

因为在打包过程中,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文件夹下的静态资源。

  • 如果需要使用图片等作为背景图片等,尽量使用内联方式使用吧,像在模板中使用一样。

  • 如果需要引入样式文件,则在index.html中使用插值方式引入吧。

关于静态资源的问题,vue-cli的推荐是尽量将资源作为你的模块依赖图的一部分导入(即放到assets中,使用相对路径引用),避免该问题的同时也带来其它好处:

四、history模式部署


Vue项目默认使用的是hash路由模式,就是URL中会包含一个#号的这种形式。#号以及之后的内容是路由地址的hash部分。

正常情况下,当浏览器地址栏地址改变,浏览器会重新加载页面,而如果是hash部分修改的话,则不会重新加载,这就是前端路由的原理,即允许根据不同的路由页面局部更新而不刷新整个页面。H5新增了history的pushState接口,也允许前端操作改变路由地址但是不触发页面刷新,history模式即利用这一接口来实现。因此使用history模式可以去掉路由中的#号。

1. 项目配置

在vue-router路由选项中配置mode选项和base选项,mode配置为'history';如果部署到非域名根目录,还需要配置base选项为前文配置的publicPath值(注意:此情况下,publicPath必须使用绝对路径/test的配置形式,而不能用相对路径./)

export default new Router({
    mode: 'history',
    base:process.env.BASE_URL
})

2. nginx配置

对于history模式,假设项目部署到域名下的/test目录,访问http://xxx/test/about的时候,服务器会去找/test指向的目录下的about子目录或文件,很显然因为是单页面应用,并不会存在a这个目录或者文件,就会导致404错误:

我们要配置nginx让这种情况下,服务器能够返回单页应用的index.html,然后剩下的路由解析的事情就交给前端来完成即可。

location /test {
    alias /www
    try_files $uri $uri/ /test/index.html
}

这句配置的意思就是,拿到一个地址,先根据地址尝试找对应文件,找不到再试探地址对应的文件夹,再找不到就返回/test/index.html。再次打开刚才的about地址,刷新页面也不会404啦:

3. history模式部署到非域名根路径下

非域名根目录下部署,首先肯定要配置publicPath。需要注意的点前面其实已经提过了,就是这种情况下不能使用相对路径./或者空串配置publicPath。为什么呢?

原因是它会导致router-link等的表现错乱,使用测试项目分别使用两种配置打包发布,审查元素就能看出区别。在页面上有两个router-link,Home和About:

<div id="app">
    <div id="nav">
        <router-link to="/">Home</router-link>.
        <router-link to="/about">About</router-link>
    </div>
    <router-view/>
</div>

两种配置打包后的结果如下。

  1. publicPath配置为./或者空串:

  1. publicPath配置为/test:

publicPath配置为相对路径的router-link打包后地址变成了相对根域名下地址,很明显是错误的,所以非域名根路径部署应该将publicPath配置为完整的前缀路径。

五、结语


关于Vue项目发布的相关问题就先总结这么多,几乎在每一步都踩过坑才有所体会。

写博客很累,不过收获也很多,还是要坚持;有时候别人转载自己的原创文章也不标明出处,竟然将写文章日期改得比原创还早,有点心累。本文中使用到的图片都加了个自己的水印,是前端实现的,原理也很简单,之后写一篇简短的文章分享一下。

(完)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/401907.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C#要点技术(二) - Dictionary 底层源码剖析

Dictionary 底层代码我们知道 Dictionary 字典型数据结构&#xff0c;是以关键字Key 和 值Value 进行一一映射的。Key的类型并没有做任何的限制&#xff0c;可以是整数&#xff0c;也可以是的字符串&#xff0c;甚至可以是实例对象。关键字Key是如何映射到内存的呢&#xff1f;…

【python】如何用python写一个下拉选择框和页签?

文章目录前言ttk模块下拉选择框combobox下拉选择框2页签Notebook前言 python学习之路任重而道远&#xff0c;要想学完说容易也容易&#xff0c;说难也难。 很多人说python最好学了&#xff0c;但扪心自问&#xff0c;你会用python做什么了&#xff1f; 刚开始在大学学习c语言&…

【玩转c++】stack和queue的介绍和模拟实现

本期主题&#xff1a;list的讲解和模拟实现博客主页&#xff1a; 小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐stack的介绍和使用1.1.stack的介绍1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上…

论文阅读-MGTAB: A Multi-Relational Graph-Based Twitter Account DetectionBenchmark

目录 摘要 1. 引言 2. 相关工作 2.1. 立场检测 2.2.机器人检测 3.数据集预处理 3.1.数据收集和清理 3.2.专家注释 3.3. 质量评估 3.4.特征分析 4. 数据集构建 4.1.特征表示构造 4.2.关系图构建 5. 实验 5.1.实验设置 5.2.基准性能 5.3训练集大小的研究 5.4 社…

Matlab进阶绘图第6期—雷达图/蜘蛛图/星图

雷达图&#xff08;Radar Chart&#xff09;&#xff0c;又称星图、蜘蛛图、蜘蛛网图、网络图、Kiviat图等&#xff0c;是一种以从同一点开始的轴上表示的三个以上变量的二维图表的形式&#xff0c;来显示多变量数据的图形方法。 雷达图可以直观地对多维数据集目标对象的性能、…

三步搞定OOM内存溢出,记一次使用Arthas处理OOM内存溢出问题java.lang.OutOfMemoryError: Java heap space

记一次OOM内存溢出问题修复java.lang.OutOfMemoryError: Java heap spaceOutOfMemoryError1.使用article找到问题线程2.分析线程运行链路&#xff0c;找出问题代码位置3.使用堆文件确认问题Arthas 是Alibaba开源的Java诊断工具&#xff0c;功能强大&#xff0c;操作简单 Arthas…

我们为什么使用docker 优点 作用

1. 我们为什么使用Docker? 当我们在工作中&#xff0c;一款产品从开发设计到上线运行&#xff0c;其中需要开发人员和运维工程师&#xff0c;开发人员负责代码编写&#xff0c;开发产品&#xff0c;运维工程师需要测试环境&#xff0c;产品部署。这之间就会有分歧。 就好比我…

信创国产化,试试 Solon v2.2.2

Solon 是一个高效的 Java 应用开发框架&#xff1a;更快、更小、更简单。它不是 Spring、没有用 Servlet、也无关 JavaEE&#xff0c;是一个有自己接口标准的开放生态。可以为应用软件国产化提供支持&#xff0c;助力信创建设。 150来个生态插件&#xff0c;覆盖各种不同的应用…

不知道Redis?来这里可以带你快速学完Redis,干活满满!

文章目录一、NoSQL的基本介绍二、为什么要使用NoSQL&#xff0c;难道SQL不够你用吗&#xff1f;三、Redis的基本概念四、Redis基本操作命令五、Redis五大数据类型及其操作命令六、三种特殊的数据类型及其操作命令七、 Redis事务八、Redis对key的监控九、Redis数据库密码十、Jed…

广州蓝景分享—8大Web前端开发的趋势

2023 年 1 月 11 日&#xff0c;2022 年度 StateOfJS 调查结果正式公布&#xff01;StateOfJS 是前端生态圈中比较有影响力的且规模较大的数据调查。本文就来解读一下 2022 年 StateOfJS 的调查结果&#xff01; JavaScript 发展很快&#xff0c;但似乎 JavaScript 开发人员的…

《传感器技术》考试学习笔记

文章目录一、选择题二、简答题1.什么是传感器&#xff1f;传感器的共性是哪些&#xff1f;2.差动变气隙式传感器电感传感器的灵敏度推导过程是什么&#xff08;推导公式&#xff09;&#xff1f;与单极性进行比较它们的优缺点是哪些&#xff1f;3.霍尔传感器如何进行微位移测量…

uniapp上实现左右关联滚动

先看效果&#xff1a; 代码&#xff1a; <template><view class"container"><!-- 左侧fixed导航区域 --><view class"left"><viewv-for"item in leftList":key"item.id"class"left_item":class…

JVM结构-类加载(类加载子系统,类加载的角色,类加载的过程,类加载器分类,双亲委派机制,类的主/被动使用)

JVM 结构-类加载2.1类加载子系统2.2类加载的角色2.3类加载的过程2.3.1加载2.3.2链接2.3.3初始化2.4类加载器分类2.4.1 引导类加载器2.4.2扩展类加载器2.4.3应用程序类加载器2.5双亲委派机制2.6类的主动/被动使用2.1类加载子系统 类加载器子系统负责从文件系统或者网络中加载 cl…

【深度强化学习】(1) DQN 模型解析,附Pytorch完整代码

大家好&#xff0c;今天和各位讲解一下深度强化学习中的基础模型 DQN&#xff0c;配合 OpenAI 的 gym 环境&#xff0c;训练模型完成一个小游戏&#xff0c;完整代码可以从我的 GitHub 中获得&#xff1a; https://github.com/LiSir-HIT/Reinforcement-Learning/tree/main/Mod…

腾讯云新用户怎么配置服务器的方法教程

腾讯云新用户怎么配置服务器&#xff1f;腾讯云服务器配置选择攻略&#xff0c;先选择云服务器地域和可用区&#xff0c;然后根据用户使用场景需要平衡型、计算型或高IO型等特性来选择云服务器CVM实例规格&#xff0c;主机教程网来详细说下腾讯云服务器配置选择攻略。 1、腾讯云…

政府工作报告连提9年科技创新 企业研发如何“又快又好”

今年的政府工作报告&#xff0c; “科技创新” 这一描述连续出现7次&#xff0c;这也是自2015年开始&#xff0c; “科技创新” 这一概念在全国“两会”政府工作报告中连续九年被提到。政府工作报告指出&#xff0c;科技政策要聚焦自立自强&#xff0c;完善新型举国体制&#x…

ccc-pytorch-LSTM(8)

文章目录一、LSTM简介二、LSTM中的核心结构三、如何解决RNN中的梯度消失/爆炸问题四、情感分类实战&#xff08;google colab&#xff09;一、LSTM简介 LSTM&#xff08;long short-term memory&#xff09;长短期记忆网络&#xff0c;RNN的改进&#xff0c;克服了RNN中“记忆…

ArcGIS动态表格批量出图

一.产品介绍&#xff1a;ArcGIS动态表格扩展模块Mapping and Charting Solutions&#xff0c;可用于插入动态表格&#xff0c;与数据驱动结合&#xff0c;出图效率无敌。注&#xff1a;优先选择arcgis10.2.2。 二、下载连接&#xff1a; https://www.xsoftnet.com/share/a001CX…

Idea+maven+spring-cloud项目搭建系列--12 整合grpc

前言&#xff1a; grpc 是geogle 开源的rpc 通信框架&#xff0c;通过定义proto生成通信存根&#xff0c;像本地调用服务一样&#xff0c;进行远程服务的调用&#xff1b; 1 消费端服务提供&#xff1a; 1.1 引入grpc 和 protobuf <!-- RPC --> <!-- RPC 服务调用 …

最大子矩阵(蓝桥杯)暴搜 JAVA

题目描述&#xff1a; 小明有一个大小为NM的矩阵&#xff0c;可以理解为一个N行M列的二维数组。 我们定义一个矩阵m 的稳定度f(m) 为f(m)max(m)-min(m)。 其中max(m)表示矩阵m中的最大值&#xff0c;min(m) 表示矩阵m 中的最小值。 现在小明想要从这个矩阵中找到一个稳定度不大…