webpack+nginx opens gzip compression deployment project

First install nginx on the server

sudo apt update
sudo apt install nginx

After the installation is complete, package the front-end project. Configure the resource base path in webpack.output.publicPath. The packaged resource starts with /publicPath

1. http://www.xxx.com/ publicPath: ‘/’

2. http://www.xxx.com/web publicPath: ‘/web/’ Add an extra / at the end because the js loaded on demand will spell static less one /, and the spelling is /webstatic/js/… Resulting in Resources cannot be loaded

If we visit http://www.xxx.com/web, we will set the to in webpack.output.path:path.resolve(__dirname, ‘../web’) copyWebpackPlugin to ../web to ensure that after packaging The folder name is web to map the nginx path

Where webpack needs to change the project output file directory name:

new CopyWebpackPlugin({
      patterns: [
        {
          from: path.resolve(__dirname, '../public'), // copy the files under public
          to: path.resolve(__dirname, '../web'), // Copy to the web directory (this configuration is the key point)
          filter: (source) => {
            return !source.includes('index.html') // Need to ignore files that are not copied index.html has been generated by htmlWebpackPlugin
          },
        },
      ],
    }),
 output: {
    filename: 'static/js/[name].[chunkhash:8].chunk.js', // As long as the name of each output js does not change the code of the public library, the code of the entry file is separate from the public library, so the hash is It will not change the use of chunkhash to benefit the browser's cache
    path: path.resolve(__dirname, '../web'), // output path of packaging results (this configuration is the key point)
    clean: true, // webpack4 needs to configure clean-webpack-plugin to delete dist files, webpack5 built-in
    publicPath: '/web/', // The public prefix path of the packaged file is added with an extra / at the end because js loaded on demand will be spelled with one less / when it is spelled out to be /webstatic/js/... resulting in resource loading failure Come out (this configuration is the key point)
  },

After configuring the work at the webpack level, pnpm build packages the folder web, and uses scp to upload the folder to the site directory of the server nginx (macos) on the project root directory command line:

scp -r web username@server ip:/usr/share/nginx/html

If there are errors such as no such file or directory or permission denied, the folder /usr/share/nginx/html written by the server does not have read and write permissions. The permissions are just fine:

sudo chmod 777 /usr/share/nginx/html

The default welcome page of nginx is in /usr/share/nginx/html/index.html Nginx will read the resources under the html folder by default, so put the packaged project web into the /usr/share/nginx/html folder Down

After uploading, we go to the /etc/nginx/conf.d directory. This directory is the sub-configuration folder of nginx. The .conf file will be included in the http node by the main configuration file of /etc/nginx/nginx.conf. We only need to /etc/nginx/conf.d creates a new subdirectory file and then writes the server node

A server node in nginx is a service. Multiple server services can be written in the http node. Multiple location paths can be written in a server to map different items. Here is a new web.conf configuration file:

server {
        listen 80; # The listening port is generally port 80, you can change it yourself
        server_name localhost 127.0.0.1;# server domain name/ip
        root /usr/share/nginx/html;# Configure the root directory of the service
        index index.html index.htm;# Home page file name
        # Directly access the server or randomly input 404->index.html to request the nginx welcome page
        location / {
                try_files $uri $uri/ /index.html;
        }
        # Own project http://domain name/ip/web access site /web should be followed by / to match completely, otherwise /weba can also match
        location /web/ {
                # When the project folder name is inconsistent with the publicpath of webpack, use an alias to specify the mapped folder, otherwise the publicPath folder will not be found
                # alias /usr/share/nginx/html/web;
                # When the location cannot be matched, it will try to find $uri $uri is the requestMapping of the request. If it is not found, it will try to find the resources under the folder of $uri. question
                try_files $uri $uri/ /web/index.html;
                # For non-hash resources, you need to configure Cache-Control: no-cache to prevent browsers from defaulting to strong caching
                expires -1; # Give -1 to indicate no cache

        }
        # Resource cache under the static folder
        location /web/static {
                # For resources with hash, you need to configure long-term cache. The default is 1 year
                expires 1y;
        }
        # Continue to configure the location to join the new site
        # location /foo {
        
        # }

}

Install compression-webpack-plugin and enable gzip compression in the webpack configuration plugin

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

    new CompressionPlugin({
      test: /\.(js)$/i,
      filename: '[path][base].gz', // file name
      algorithm: 'gzip', // compression format, the default is gzip
      threshold: 10240, // Only resources with a size larger than this value will be processed. The default is 10k
      minRatio: 0.8, // Compression ratio, the default value is 0.8
    }),

    ]

Generally, compressionwebpackplugin is used to gzip compress js files and package them into .gz files to reduce the volume. Of course, nginx can also compress online gzip, but online compression of nginx will consume server resources and waste unnecessary time. Therefore, gzip compression is generally done when packaging and uploaded. A js will generate two files, .js and .gz. This is to prevent the .gz file from being deleted by mistake and still be able to access the js and return it to the client to avoid 404 errors.

The principle of gzip: After the browser requests the gz file returned by the server, according to the content encoding header of the response header Content-Encoding: gzip to identify what format to use to decode the content, the returned gzip is decoded with gzip

Nginx compression is the same, except that the compression work is done by nginx, not when we package it. Online real-time compression is performed on the returned resources every time a request is made

nginx supports gzip:

gzip is the configuration of the http node in nginx.conf, we do not advocate frequent active configuration file nginx.conf, so we create a gzip.conf configuration file in its same level directory, write gzip configuration in it and include it to nginx.conf http node in

gzip.conf:

# gzip: enable gzip compression
gzip on;
# gzip_comp_level: The compression level value is 1-9. 1 means that if the degree is the lowest, if the efficiency is the highest, 9 is just the opposite. The degree of compression is the highest, but the efficiency is the lowest and the most time-consuming.
gzip_comp_level 5;
# gzip_min_length: The minimum length of gzip compression is enabled. The response body reaches this length before compressing the unit of nignx measurement size: bytes[bytes] / kb[kilobytes] / M[megabytes] For example: 1024(b/byte) / 10k| K / 10m|M
gzip_min_length 1k;
# gzip_buffers The number and size of compressed buffers. The default value depends on the size of a memory page in the system. 32 4k | 16 8k This value is generally related to the system. It is not recommended to set it with the default value
# gzip_buffers 4 16k;
# gzip_proxied detailed meaning: nginx acts as a reverse proxy to open the conditions for compressing the data returned by the server
# There is a via header in http that will be added when it is propagated in the proxy server (whether it is a forward proxy or a reverse proxy). Through this header, the server can know which proxies the request has passed through
# By default, nginx does not compress the proxied request, it identifies whether the request has been proxied through the via header. If you want to compress the proxied request, you can configure this parameter
# All possible values and meanings
# off - Turn off the Gzip compression of the results returned by the Nginx server to the background server
# expired - enable compression if header contains "Expires" header
# no-cache - enable compression if the "Cache-Control:no-cache" header is included in the header
# no-store - enable compression if the header contains the "Cache-Control:no-store" header
# private - enable compression if the "Cache-Control:private" header is included in the header
# no_last_modified - enable compression if header does not contain "Last-Modified" header
# no_etag - enable compression if the "ETag" header is not included in the header
# auth - enable compression if header contains "Authorization" header
# any - enable compression unconditionally
gzip_proxied any; # Compress all proxied request bodies
# When gzip_vary is enabled, "Vary: Accept-Encoding" will be inserted in the return header. This command is used to set whether to use Gzip to compress and send the response header with the "Vary: Accept-Encoding" header field. Mainly to tell the receiver that the sent data has been compressed by Gzip
gzip_vary on;
# gzip compressed file type
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;
# Enable gzip to compress static resources
gzip_static on;
# Set the corresponding browser to disable gzip compression Match according to useragent in requestheader
gzip_disable "MSIE [1-6]\.";# ie1-6 does not enable gzip compression
# Set to selectively enable and disable the Gzip function for different HTTP protocol versions.
gzip_http_version 1.1;# http1.1 only enables gzip compression

The key is to set the three values of gzip on, gzip_static on and gzip_vary on to enable

After enabling gzip, we can restart the nginx service

sudo /usr/sbin/nginx -s reload

Open the site at this time and you can see that the deployment is OK, the resource response is successful, and the server returns the gzip format response headers are also added:

History routing mode accesses resources that do not exist in /web/aaa/bbb and returns index.html without 404, and try_files takes effect:

The basic deployment here is successful (*^▽^*)

Of course, the folder names of /web and the root directory of the project can be chosen at will. The root path /access can be configured by yourself, so /web can be directly mapped to location / {}, and the resources in the dist can be tiled under the html/ folder. Automatically read index.html so direct access without any prefix is OK