来屡屡前端包部署以及nginx配置

1,470 阅读4分钟

作为一个新时代的前端搬砖民工,光会视觉还原、接口联调是不行的,作为一个有理想的前端不得不卷入内卷的洪流之中。下面就回顾一下最近我做服务迁移遇到的一些问题,大家有碰到类似的问题照搬就可以了,不用大海捞针一样去寻找答案。

前端大致的一个工作流程:项目搭建 -> 编码 -> 构建 -> 部署

我们主要讨论部署,这里以vue为例。在讨论这个问题之前先了解 publicPath

环境准备

  • 本地安装nginx
  • 通过vue-cli创建一个项目

publicPath

  • vuecli cli.vuejs.org/zh/config/#…
  • webpack webpack.docschina.org/guides/publ… 这个publicPathvue-cliwebpack都存在这个api,目的都是为了给构建出来的静态包提供一个自定义公共路径的功能,默认情况都是/。如果你是用vuecli搭建的项目,在vue.config.js自定义publicPath就OK,不要在output里配置。

模拟部署测试

1、启动vue项目、构建出dist

2、把dist包提取到nginx静态文件夹下

publicPath: '/'

注:Mac系统nginx默认安装路径/usr/local/bin,配置文件路径/usr/local/etc/nginx,静态文件夹/usr/local/var/www

修改nginx.conf配置

...
location / {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}
...

3、启动服务 在安装路径下/usr/local/bin 执行

nginx

4、浏览器调试

image.png 截屏2021-10-26 下午6.02.33.png image.png

看上图,所有构建的静态资源都放在跟路径,也可以正常访问了,到这里就完成部署了,好像没什么问题。如果是这样的话那就没必要写这篇文章了,且听下文分享

多个静态包部署在同一个域名

在实际开发部署中,不太可能会是一个包有一个单独的域名,而是一个域名下会部署多个包,这种场景再套用上面的配置那就会出问题了,怎么办?

此时就需要派上publicPath了,通过在域名后拼接一个标识来区分

比如我想在a.b.com域名下部署projectA、projectB、projectC

http://a.b.com/projectA/

http://a.b.com/projectB/

http://a.b.com/projectC/

现在方案有了,接下来就是编码配置了

vue.config.js

...
publicPath: '/projectA/'
...

这个publicPath是作用于资源引用路径上,我们还需要在vue项目访问页面的路径上有所体现,类似http://a.b.com/projectA/,那就要在router里配置一个公共路径

const router = createRouter({
  history: createWebHistory('/projectA/'),
  routes: routes
})

如果是vue2.x的配套路由的话要在baseUrl里配

image.png

可以看到配置的publicPath在模板index.html文件引用资源时体现了

image.png

image.png

点开sourses,可以看到图片文件夹不见了,页面空白,可以判断是没有映射到资源

万能的百度发挥作用了,一通检索,做了如下nginx配置

...
location / {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /index.html;
}
location /projectA {
    alias /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /projectA/index.html;
}
...

image.png

vue项目的路由模式,不管是history还是hash模式,配置方式都一样的,不过有一点要注意,如果要发静态包到github pages,history模式好像不行,要用hash模式的路由

此时,也就把开始抛出的疑问解决了。不知道大家有没有别的疑问?rootalias 有啥区别?

rootalias 的区别

使用alias,实际的路径就是:alias值。

例如,
有一张图片,URL是:www.awaimai.com/static/a.jp…

它在服务器的路径是:/var/www/app/static/a.jpg

那么用root的配置是:

location /static/ {
    root /var/www/app/;
}

用alias的配置就是:

location /static/ {
    alias /var/www/app/static/;
}

对于alias,location值可以随便取,例如:

location /hello/ {
    alias /var/www/app/static/;
}

这样,我们访问图片的地址就是:www.awaimai.com/hello/a.jpg

注意:
很多文章说:alias 后面必须要用 “/” 结束,是错误的,亲测加不加/效果是一样的。
alias在使用正则匹配时,必须捕捉要匹配的内容,并在指定的内容处使用。
alias只能位于location块中,root可以不放在location中。

域名 + /index.html

接着往下,有个这样的链接 http://a.b.com/group/test/index.html

项目结构也是一个vue的项目,原来由于是手动上传到CDN,套了几层目录,现在迁移到云服务用流水线发布。考虑到怕改变了链接有影响,怎样在访问链接不变动的情况顺利的迁移。

1、改造构建产物套几层目录

修改输出目录

vue.config.js

...
outputDir: 'dist/group/test',
...

image.png

2、正常的发布到nginx静态文件目录下

3、配置nginx

location /group/test/index.html {
    root /usr/local/var/www/dist;
    index index.html index.htm;
    try_files $uri $uri/ /group/test/index.html;
}

根据root和alias的区别,

指向路径:/usr/local/var/www/dist/group/test/index.html

nginx配置

nginx.conf

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    keepalive_timeout  65;
    #gzip  on;
    include /etc/nginx/conf.d/*.conf;
}

default.conf

server {
	listen        80 ;
	server_name   localhost;
	root          /usr/share/nginx/html;
	index         index.html;  # 入口文件
	charset        utf-8;   # 编码

	location / {
		try_files $uri $uri/ /index.html;
	}

	#location ^~/gatewayApi {
	#	proxy_set_header X-Real-IP $remote_addr;
	#	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	#	proxy_buffering off;
	#	rewrite ^/gatewayApi/(.*)$ /$1 break;
	#	proxy_pass http://gateway.xxxx.com/;
	#}
}
include /etc/nginx/conf.d/*.conf;

这句代码的意思是部署的时候把default.conf提到nginx目录里conf.d文件夹去,然后自动引入nginx.conf配置文件中。这个好处就是default.conf可以写在开发项目里,方便做一些nginx的配置