H5项目本地部署测试方案

776 阅读2分钟

h5活动都是阶段性的,每次来一个活动需求就要单独部署一次。需求不同,部署方案不同。

基本结构

项目+docker+Nginx

本地需要安装docker,Nginx。

scripts/docker_run.sh

#!/bin/sh

echo -e "\033[35m [docker] docker \033[0m"
# 获取项目名
PROJECT_NAME=$(cat package.json | grep name | head -1 | awk -F "[\"]" '/name/{print$4}')
echo $PROJECT_NAME
#  镜像
NAME=$PROJECT_NAME
# # 环境变量
API_URL=http://10.6.24.92:8080

#已存在 dist包就不再打包
# if [ ! -d "./dist" ] || [ "$1" == "-t" ]; then
#   echo "[docker] dist build"
#   npm run build
# fi

#每次都重新打包
npm run build
# -t 参数给镜像命名 . 是基于当前目录的 Dockerfile 来构建镜像
echo "[docker] docker build"
docker build . -t $NAME

# docker run -d -p 3000:80 --name docker-vue jartto-docker-demo
#-d 设置容器在后台运行 -p 表示端口映射,把本机的 3000 端口映射到 container 的 80 端口(这样外网就能通过本机的 3000 端口访问了)
# --name 设置容器名 docker-vue
# jartto-docker-demo 是我们上面构建的镜像名字

#5001映射到本机的80867
echo "[docker] docker run"
docker run -d -p 8067:5001 -e API_URL=$API_URL -e POINT_URL=$POINT_URL $NAME

package.json新增docker命令

"docker":"sh scripts/docker_run.sh"

Dockerfile文件:

#使用基础镜像库
FROM nginx

#创建工作路径
RUN mkdir -p /data/web/
# 镜像工作目录 镜像跑起来的时候默认在工作目录下
WORKDIR /data/web/

# COPY nginx.conf /etc/nginx/nginx.conf
#将dist包复制到工作目录下
COPY ./dist/ /data/web/
COPY nginx.template /tmp/
#写入变量 复制到Nginx.conf
CMD envsubst '$API_URL' < /tmp/nginx.template > /etc/nginx/nginx.conf && nginx -g "daemon off;"

nginx.template文件 (此文件单纯为测试文件)

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 20480;


events {
  use epoll;
  worker_connections 20480;
  multi_accept on;
}

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"';
    #请求量级大建议关闭acccess_log
    #access_log  /var/log/nginx/access.log  main;

    #fastcgi_intercept_errors on;
    #proxy_intercept_errors on;
    #error_page 404 /data/web/404.html;
    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_types application/javascript application/json;

    include /etc/nginx/conf.d/*.conf;
    add_header Access-Control-Allow-Origin *;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
    add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-   Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
    
    server {
        listen 5001;
        root /data/web;
        charset utf-8;
        client_max_body_size 75M;
        location / {
            try_files $uri $uri/ @router;
            index  index.html index.htm;
        }
        location @router {
            rewrite ^.*$ /index.html last;
        }
        location ^~ /js/ {
          root /data/web/static; 
        }
        location /active/GosPetsGallery {
            alias /data/web/;
            index  index.html index.htm;
            try_files $uri $uri/ /data/web/index.html;
        }
         location ~* /en {
           alias /data/web/;
        }
         location ~* /tu {
           root /data/web/;
        }
        location ~* /ru{
          return 123 "
           uri: $uri
           document_root: $document_root ";
        }
        location /static {
	 alias /data/web/static/;
	}
        location /redeem/ { 
             proxy_pass ${API_URL};
        }
    }
}

nginx 重要字段说明

  1. location的匹配规则 参考:juejin.cn/post/691979…

image.png

image.png 2. alias和root区别

访问 localhost:8067/js/index.html,用root,实际访问localhost:8067/data/web/static/js/index.html

访问 localhost:8067/home/index.html,用alias,实际访问localhost:8067/data/web/index.html

  1. proxy_pass匹配规则

proxy_pass路径加斜杆和不加斜杆的区别:

#访问 https://activity-pre.clktec.com/wsy-jp/redeem/FacebookGetAccessToken

location /wsy-jp/redeem { 

proxy_pass https://dc-pre-gateway.9longe.net:8110/redeem/;

}
#代理之后: https://dc-pre-gateway.9longe.net:8110/redeem/FacebookGetAccessToken
#访问http://www.xxx.com/aming/a.html 

location /aming/{

proxy_pass http://192.168.1.10/linux;

}
#代理之后:http://192.168.1.10/linuxa.html

执行:npm run docker

image.png 点击此容器可以看具体信息,如日志,设置的变量等:

image.png 以及进入到工作目录查看生效的nginx配置

image.png

image.png 测试nginx

cmd 执行localhost:8090/ru,注意返回了123

image.png

访问js,可见实际访问的是/data/web/js 下面的js

image.png

本地测试nginx

在nginx安装目录中,创建vhost文件夹,然后再nginx.conf中增加一行:

include vhost/*.conf;

image.png

image.png

image.png

a.conf

server {
  listen 8091;
  server_name  localhost;
  location / {
    root html;   
    index home.html home.htm;
  }
}

访问http://localhost:8091/ ,就去访问这个文件下的home.html

image.png

这样就在本地直接测试nginx而不用借助docker。

不同需求的不同nginx 配置

需求一

访问http://localhost:8067/europe-ios/lohhjnh(不管是啥结尾) 实际访问的是http://localhost:8067/europe-ios

      #location ~* /(asia-huawei|europe-ios) { //  前面的斜杆可加可不加。最后的这个斜杆一定要加!如果不加 匹配到了europe-ios,$1 就是/europe-ios ,这样又匹配到这个,就进入死循环匹配
        #       rewrite ^/(asia-huawei|europe-ios)/(.*) /$1;  //$1 就是/europe-ios 循环  
        #  }


        location ~* /(asia-huawei|europe-ios)/ { #斜杆一定要加   加了斜杆后匹配到了europe-ios ,$1 就是/europe-ios/  然后就继续下一个匹配了
             rewrite ^/(asia-huawei|europe-ios)/(.*) /$1;  // $1取到的是小括号() 里面的第一个变量,小括号指的是变量组,如果不加小括号,asia-huawei|europe-ios 这么写匹配到了不会赋值给$1,那么$1取到的是(.*)匹配到的值
        }
         location ~* (asia-huawei|europe-ios)$  { ////  前面的斜杆可加可不加  $ 以前面的东西结尾
            return 102;
        }

需求二

同一项目部署多个链接,链接子路径不同,配置不一样。

https:abc.com/a, https:abc.com/b, https:abc.com/c

1、项目里不用路由

        location / {
            # root /usr/share/nginx/html;
            index /index.html;                        
            try_files $uri $uri/ /index.html;        #匹配不到任何静态资源,跳到同一个index.html
        }
        location ~* /test-ios {
            alias /data/web/;
            index  index.html index.htm;
            try_files $uri $uri/ /data/web/index.html;
        }
         location ~* /asia-huawei {
            alias /data/web/;
            index  index.html index.htm;
            try_files $uri $uri/ /data/web/index.html;
        }

2、项目使用路由:

基础设置:

publicPath:"/", //若设置成/a,则静态打包资源会所有的都会加上/a

//注意base,若是访问localhost:9098/a,则会默认匹配/,若访问localhost:9098/a/login,则路由会会匹配login。 这就base的作用,这样nginx不需要再设置/a,/b,/c。

const router = new VueRouter({
  mode: 'history',
  base: window.location.pathname,(设置成了/a)
  routes
})
    
    server {
        listen 5001;
        root /data/web;
        charset utf-8;
        client_max_body_size 75M;
        location / {
            # root /usr/share/nginx/html;
            index /index.html;                        
            try_files $uri $uri/ /index.html;        #匹配不到任何静态资源,跳到同一个index.html
        }
         location /redeem/ { 
             proxy_pass ${API_URL};
        }
    }

需求三

多语言分享,选择一种语言之后分享出去也要显示这个语言。不同语言的分享文案语言不同,所以需要

多页面:

  pages: {
    index: {
      entry: 'src/main.js',
      template: 'public/index.html',
      filename: 'index.html'
    },
    ru: {
      entry: 'src/main.js',
      template: 'public/ru.html',
      filename: 'ru.html'
    },
    tu: {
      entry: 'src/main.js',
      template: 'public/tu.html',
      filename: 'tu.html'
    }
  },
const router = new VueRouter({
  mode: 'history',
  base: window.location.pathname,
  routes
})

        location ^~ /tu {
            index  tu.html  tu.htm;
            try_files $uri $uri/ /tu.html;
           
        }
         location ^~ /ru {
            index  ru.html  ru.htm;
            try_files $uri $uri/ /ru.html;
        }
        location / {
            alias /data/web/;
            index  index.html index.htm;
            try_files $uri $uri/ /data/web/index.html;
        }

image.png

tu语言:localhost:8091/tu

ru语言:localhost:8091/ru