webpack+nginx开启gzip压缩部署项目

首先在服务器安装nginx

sudo apt update
sudo apt install nginx

安装完毕后将前端项目打包 webpack.output.publicPath里配置资源基础路径 资源打包出来就是/publicPath开头

1.http://www.xxx.com/ publicPath: '/'

2.http://www.xxx.com/web publicPath: '/web/' 尾巴多加个/是因为按需加载的js拼static会少拼一个/ 拼出来就是/webstatic/js/... 导致资源加载不出来

假如我们是http://www.xxx.com/web访问 我们就将webpack.output.path:path.resolve(__dirname, '../web') copyWebpackPlugin里的to也为../web 保证打包后的文件夹名为web去映射nginx路径

webpack需要改项目输出文件目录名的地方:

new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../public'), // 复制public下的文件
          to: path.resolve(__dirname, '../web'), // 复制到web目录中 (这个配置是重点)
          filter: (source) => {
            return !source.includes('index.html') // 需要忽略不copy的文件 index.html已经被htmlWebpackPlugin生成了
          },
        },
      ],
    }),
  output: {
    filename: 'static/js/[name].[chunkhash:8].chunk.js', // 每个输出js的名称 只要不动公共库的代码 入口文件的代码是和公共库分开的 所以hash就不会变 使用chunkhash利于浏览器的缓存
    path: path.resolve(__dirname, '../web'), // 打包结果输出路径 (这个配置是重点)
    clean: true, // webpack4需要配置clean-webpack-plugin来删除dist文件,webpack5内置了
    publicPath: '/web/', // 打包后文件的公共前缀路径 尾巴多加个/是因为按需加载的js拼static会少拼一个/ 拼出来就是/webstatic/js/... 导致资源加载不出来 (这个配置是重点)
  },

webpack层面的工作配置完后,pnpm build打包得到文件夹web,使用scp在项目根目录命令行将文件夹上传至服务器nginx的站点目录(macos):

scp -r web 用户名@服务器ip:/usr/share/nginx/html

如果出现no such file or directory或者permission denied等错误 则服务器写入的这个文件夹/usr/share/nginx/html没有读写权限 上服务器给个权限就好了:

sudo chmod 777 /usr/share/nginx/html

nginx的默认欢迎页在/usr/share/nginx/html/index.html nginx默认会去读html文件夹下的资源 所以把打包的项目web放到/usr/share/nginx/html文件夹下

上传后我们去到/etc/nginx/conf.d目录 这个目录是nginx的子配置文件夹 里面的.conf文件会被/etc/nginx/nginx.conf主配置文件include进http节点中 我们只需要在/etc/nginx/conf.d新建子目录文件然后编写server节点即可

nginx中一个server节点即为一个服务 http节点里可以写多个server服务 一个server里可以写多个location路径映射不同的项目 这里新建一个web.conf配置文件:

server {
        listen 80; # 监听的端口 一般都是80端口 可以自己改
        server_name localhost 127.0.0.1;# 服务器域名/ip
        root /usr/share/nginx/html;# 配置服务的根目录
        index index.html index.htm;# 首页文件名
        # 直接访问服务器或者乱输404->index.html 都请求nginx欢迎页
        location / {
                try_files $uri $uri/ /index.html;
        }
        # 自己的项目 http://域名/ip/web访问站点 /web后面要加/ 完全匹配 否则/weba也能匹配
        location /web/ {
                # 当项目文件夹名和webpack的publicpath不一致时要用别名指定映射的文件夹 否则会找不到这个publicPath文件夹
                # alias /usr/share/nginx/html/web;
                # 当location匹配不到时会尝试查找$uri $uri就是请求的requestMapping 没找到会尝试查找$uri的文件夹下的资源有没有 没找到最后就请求/web/index.html 也就是处理history路由404问题
                try_files $uri $uri/ /web/index.html;
                # 非带 hash 的资源,需要配置 Cache-Control: no-cache,避免浏览器默认为强缓存
                expires -1; # 给-1表示不缓存

        }
        # static文件夹下的资源缓存
        location /web/static {
                # 带 hash 的资源,需要配置长期缓存 默认给1年
                expires 1y;
        }
        # 继续配置location加入新的站点
        # location /foo {
        
        # }

}

安装compression-webpack-plugin在webpack配置插件开启gzip压缩

    const CompressionPlugin = require('compression-webpack-plugin')
    // gzip压缩
    plugins: [

    new CompressionPlugin({
      test: /\.(js)$/i,
      filename: '[path][base].gz', // 文件命名
      algorithm: 'gzip', // 压缩格式,默认是gzip
      threshold: 10240, // 只有大小大于该值的资源会被处理。默认值是 10k
      minRatio: 0.8, // 压缩率,默认值是 0.8
    }),

    ]

一般都会用compressionwebpackplugin对js文件进行gzip压缩 打包成.gz文件减少体积 nginx当然也可以在线gzip压缩 但是nginx在线压缩会消耗服务器资源和不必要的时间浪费 所以一般打包时gzip压缩好上传 gzip压缩后同一个js会生成.js和.gz两份文件 这是为了防止.gz文件被误删后依然能访问js返回给客户端避免404报错

gzip的原理: gzip其实是属于http压缩中的一个经典方式 它通畅能节省70%左右的响应体体积 http压缩是内置到网页客户端和网页服务器里的一个资源压缩 数据从服务器里返回之前就已经被压缩过了 浏览器请求到服务器返回后的gz文件后 根据响应头的内容编码头Content-Encoding: gzip来辨识用什么格式对内容进行解码 返回的gzip就用gzip进行解码

nginx压缩一样的 只是压缩的工作是nginx做的不是我们打包时做的 每次请求时对返回的资源进行在线实时压缩 会消耗服务器的cpu 所以webpack进行gzip更多的意义是为了给服务器分压 如果服务器因为压缩在I/O上梗塞住了 那用户不还是得等 优化失去了意义 浏览器的gzip解析消耗和服务器的压缩gzip消耗去换取中间网络传输的时间和流量带宽 这消耗是微不足道的 是值得的

gzip当然也不是万能的 gzip并不能保证每个文件压缩后都能变小很多 gzip的算法是找出文件中的重复字符串进行临时替换 等到解析时进行还原 也就是说只有代码重复率越高时 压缩的效果就越大 反之亦然

nginx支持gzip:

gzip是http节点的配置在nginx.conf里,我们不提倡经常动主配置文件nginx.conf,所以我们在它同级目录创建一个gzip.conf配置文件,里面写gzip的配置 然后include到nginx.conf中的http节点

gzip.conf:

# gzip:启用gzip压缩
gzip on;
# gzip_comp_level:压缩等级 值为1-9 1表示要是程度最低,要是效率最高,9刚好相反,压缩程度最高,但是效率最低最费时间。
gzip_comp_level 5;
# gzip_min_length:启用gzip压缩的最小长度 响应体达到这个长度才压缩 nignx计量大小的单位:bytes[字节] / kb[千字节] / M[兆] 例如: 1024(b/byte) / 10k|K / 10m|M
gzip_min_length 1k;
# gzip_buffers 压缩的buffers数量和大小 默认值取决于系统一个内存页的大小 32 4k | 16 8k 这个值一般和系统有关 用默认值即可 不建议设置
# gzip_buffers 4 16k;
# gzip_proxied详解 含义: nginx作为反向代理开启压缩服务端返回数据的条件
# http里有个via头在代理服务器中传播时会被加上(不管是正向代理还是反向代理)。通过这个头部,服务器就可以知道请求经过了哪些代理
# 默认情况下,nginx不会对被代理的请求进行压缩,它通过via头识别请求是不是被代理过。如果要对被代理的请求进行压缩,可以配置这个参数
# 所有可能值及含义
# off - 关闭Nginx服务器对后台服务器返回结果的Gzip压缩
# expired - 启用压缩,如果header头中包含 "Expires" 头信息
# no-cache - 启用压缩,如果header头中包含 "Cache-Control:no-cache" 头信息
# no-store - 启用压缩,如果header头中包含 "Cache-Control:no-store" 头信息
# private - 启用压缩,如果header头中包含 "Cache-Control:private" 头信息
# no_last_modified - 启用压缩,如果header头中不包含 "Last-Modified" 头信息
# no_etag - 启用压缩 ,如果header头中不包含 "ETag" 头信息
# auth - 启用压缩 , 如果header头中包含 "Authorization" 头信息
# any - 无条件启用压缩
gzip_proxied any;# 压缩所有被代理的请求体
# gzip_vary 开启时,会在返回头插入”Vary: Accept-Encoding” 该指令用于设置使用Gzip进行压缩发送是否携带“Vary:Accept-Encoding”头域的响应头部。主要是告诉接收方,所发送的数据经过了Gzip压缩处理
gzip_vary on;
# gzip压缩的文件类型
gzip_types
application/javascript
application/x-javascript
text/javascript
text/css
text/xml
application/xhtml+xml
application/xml
application/atom+xml
application/rdf+xml
application/rss+xml
application/geo+json
application/json
application/ld+json
application/manifest+json
application/x-web-app-manifest+json
image/svg+xml
text/x-cross-domain-policy;
# 启用gzip压缩静态资源
gzip_static on;
# 设置对应的浏览器禁用gzip压缩 根据requestheader里的useragent匹配
gzip_disable "MSIE [1-6]\.";# ie1-6不开启gzip压缩
# 设置针对不同的HTTP协议版本,选择性地开启和关闭Gzip功能。
gzip_http_version 1.1;# http1.1才开启gzip压缩

关键的就是gzip ongzip_static ongzip_vary on三个值要设置开启

开启gzip后我们就可以重启nginx服务了

sudo /usr/sbin/nginx -s reload

 此时打开站点就能看到部署OK了,资源响应成功了并且服务端返回的是gzip格式 响应头也都加上了:

 history路由模式访问/web/aaa/bbb不存在的资源也返回了index.html了没有404,try_files生效了:

到这里基本部署就成功了 (*^▽^*) 

当然/web和项目根目录的文件夹名字可以随意自己取 配置根路径/访问也行 就不用/web了 直接映射到location / {}就行 将dist里的资源平铺到html/文件夹下就会自动读取index.html 这样直接访问不加任何前缀就OK了

猜你喜欢

转载自blog.csdn.net/Suk__/article/details/129748202