Relationship of ServerName, ServerAlias, host.file and how to define them in httpd-vhosts.conf

I wonder what is the relationship of ServerName & ServerAlias with host.file. As I know ServerName sets the hostname and port that the server uses to identify itself and ServerAlias is the alternate names for a host. But does the ServerName and ServerAlias need to be identified in host.file? Do we need to put the exact domain name or it can be an alternate name in ServerName or ServerAlias? Let's say my actual domain is www.example.com and I have set up SSL and my website are now run as https+www.example.com, now I'm trying to redirect my website from http+example.com when I type it in the browser and I expect my browser will redirect me to https+www.example.com, what ServerName or ServerAlias should I put in httpd-vhost.conf? Below are my host.file:

127.0.0.1 example.com www.example.com
::1 example.com www.example.com
127.0.0.1 localhost
::1 localhost

Below are my httpd-vhosts.conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot "d:/wamp64/www/example"
    <Directory  "d:/wamp64/www/example/">
        Options +Indexes +Includes +FollowSymLinks +MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
        Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
    </Directory>
</VirtualHost>

Does my definition of ServerName and ServerAlias correct in httpd-vhosts.conf? This is what I put in .htacess to redirect my website from http+example.com to https+ww.example.com but it does not work and I believe it related with my definition of ServerName and ServerAlias:

RewriteCond %{HTTPS} !on 
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule .* https://www.example.com%{REQUEST_URI} [R=301,L]

Below is the outcome of my redirection logs:

[perdir D:/wamp64/www/example/] RewriteCond: input='off' pattern='!on' => matched 
[perdir D:/wamp64/www/example/] RewriteCond: input='' pattern='^example\\.com$' => not-matched

This is what I get from Firefox debugger:

Firefox debugger

Update

I've update my .htaccess to below:

RewriteCond %{HTTP_HOST} example.com [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [R=301,L]

I update my ServerName in vhost to www.example.com Here's the logs that I got:

example per-dir prefix: D:/wamp64/www/example/index.php/news-and-events/news-and-events/news -> index.php/news-and-events/news-and-events/news
applying pattern '.*' to uri 'index.php/news-and-events/news-and-events/news'
RewriteCond: input='off' pattern='!on' => matched
RewriteCond: input='www.example.com' pattern='example.com' [NC] => matched
rewrite 'index.php/news-and-events/news-and-events/news' -> 'https://www.example.com/index.php/news-and-events/news-and-events/news'
explicitly forcing redirect with https://www.example.com/index.php/news-and-events/news-and-events/news
trying to replace prefix D:/wamp64/www/example/ with /
escaping https://www.example.com/index.php/news-and-events/news-and-events/news for redirect
redirect to https://www.example.com/index.php/news-and-events/news-and-events/news [REDIRECT/301]

Here is what I got from firefox debugger raw header:

GEThttp://example.com/

Request URL:http://example.com/
Request Method:GET

Request Headers (328 B) 
Raw Headers
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

This is what I get from Microsoft Edge:

General
Request URL: http://example.com/
Referrer Policy: no-referrer-when-downgrade
Request Headers
Provisional headers are shown
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 Edg/80.0.361.111

Please help and do point me out if I've done anything wrong and thanks in advance!


The host file (& how it's not related)

First, you don't need anything in your hosts file if the authoritative DNS for example.com is pointing to the public IP address of your server.

127.0.0.1 example.com www.example.com

This simply overrides the DNS when example.com is used from the same machine. It makes the server to use local loopback instead of the public IP, but in fact you seldom use a website from the server, anyway.

Relationship of ServerName & ServerAlias

It doesn't really matter whether the hostname matched against the Host header is in ServerName or ServerAlias; they are treated the same. It's just that you MUST have a single hostname as the ServerName and list of the other hostnames in the ServerAlias.


This is one of the conditions When not to use mod_rewrite

Your HTTP virtual host doesn't need to have any document root and it doesn't have to read the RewriteRule from the .htaccess, but you can redirect directly from the <VirtualHost> block, preferably using mod_alias instead of mod_rewrite.

Your configuration can be as short as:

<VirtualHost *:80> 
    ServerName example.com 
    ServerAlias www.example.com 
    Redirect permanent / https://www.example.com/
</VirtualHost>

Then, you can replace the second rewrite condition by adding a separate virtual host (in your httpd-ssl.conf) for non-www HTTPS:

<VirtualHost *:443> 
    ServerName example.com 

    # SSL cert/key headers here

    # This is the correct place for HSTS.
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

    Redirect permanent / https://www.example.com/
</VirtualHost>

Now you have eliminated the need for any rewrite rules at all and using .htaccess files in the first place, which makes your configuration both simple and efficient.