掘金文章归档 · 第 48 篇 Vue 系列 6/6 Vue.js · Vite · 部署

VUE 部署服务器二级目录及更深层目录,白屏问题解决

VUE3 + VITE 部署二级目录白屏:base 设置 + nginx 配置

原文作者:随意_(掘金) | juejin.cn/post/7221003401997303845 | 发布于 2023-04-12 | 阅读 2,098 · 约 3 分钟

0背景

本文主要介绍项目如何放到 nginx 二级目录,或者 nginx 部署多个站点,大致 3 点:

  1. 路由 base 设置;
  2. vite 或 webpack 的 base 设置;
  3. nginx 配置。

1技术栈

采用的 vue3+vite+ts 构建的,当然,技术栈不重要,重要的是解决方式,vue3+webpack 的方式,放在文章最后解决。

2Vite 部署二级目录(6 步)

第 1 步:根目录新建 .env.development 文件(环境变量必须 'VITE_' 开头)

NODE_ENV='development'
VITE_BASE_PATH='/'

第 2 步:根目录新建 .env.production 文件('front-test' 为部署服务器的二级目录名称,注意名称统一)

NODE_ENV='production'
VITE_BASE_PATH=/front-test/

第 3 步:package.json 修改(--mode 传入环境变量)

"scripts": {
    "dev": "vite --mode development",
    "build": "vue-tsc && vite build --mode production",
    "preview": "vite preview"
  },

第 4 步:router 中设置 base(vue-router@4.0 以上版本 base 字段取消,具体修改如下)

// 路由
const router = createRouter({
    history: createWebHistory(import.meta.env.VITE_BASE_PATH),
    routes
})

import.meta.env.VITE_BASE_PATH 可取到环境变量,设置 base。

第 5 步:vite.config.ts 设置 vite 的 base

由于 vite 项目的启动顺序,import.meta.env.VITE_BASE_PATH 无法在 vite.config.ts 中直接获取,但是提供了 loadEnv(mode, process.cwd()) 来获取:

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import type { UserConfig, ConfigEnv } from 'vite'

// 配置@别名
import { resolve } from "path";

// 自动导入vue中hook reactive ref等
import AutoImport from "unplugin-auto-import/vite"
//自动导入ui-组件 比如说ant-design-vue element-plus等
import Components from 'unplugin-vue-components/vite';
// element-ui
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';

// https://vitejs.dev/config/
export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
  const env = loadEnv(mode, process.cwd());
  return {
    base: env.VITE_BASE_PATH,
    plugins: [
      vue(),
      AutoImport({
        //安装两行后你会发现在组件中不用再导入ref,reactive等
        imports: ['vue', 'vue-router'],
        //存放的位置
        dts: "src/auto-import.d.ts",
        resolvers: [ElementPlusResolver()]
      }),
      Components({
        // 引入组件的,包括自定义组件
        // 存放的位置
        dts: "src/components.d.ts",
        resolvers: [ElementPlusResolver()]
      }),
    ],
    resolve: {
      // ↓路径别名
      alias: {
        "@": resolve(__dirname, "./src")
      },
    }
  }
})
📌 仅仅关注 base 字段设置即可,plugins、resolve 不影响。

第 6 步:npm run build

把 dist 打包好的文件,直接复制到二级目录下,访问即可。

3Nginx 配置

如服务器目录为 ai-chat-room-h5,nginx 的 root 默认为 html 文件夹,可以更改 root 指向,这里就不更改了,nginx 需要对应配置:

# 配置前端访问
        location /ai-chat-room-h5/ {
            #二级路由时需要使用别名alias,不用root
            alias html/ai-chat-room-h5/;
            index  index.html;
            #若不配置try_files,刷新会404 history模式
            try_files $uri $uri/ /ai-chat-room-h5/index.html;
        }

接口代理 proxyAiApis,意思为遇见 proxyAiApis 做代理,为了解决跨域。如:遇见 proxyAiApis 给我代理到 https://test-zdzk.com 上面,proxyAiManApis/api/counselling/findSessionId? 会被代理成 https://test-zdzk.com/api/counselling/findSessionId?:

location /proxyAiManApis/ {
                proxy_send_timeout 600s;
                proxy_read_timeout 600s;
                proxy_pass http://10.56.180.64:8091/;
        }

此时 vite.config.js 可做同样配置:

'/proxyAiManApis': {
        target: 'http://10.56.180.64:8091',
        changeOrigin: true,
        pathRewrite: {
          '^/proxyAiManApis': ''
        }
      }

关于 nginx 的斜杠问题,可以参考 nginx 斜杠使用。

4Webpack 解决方式

第 1 步:.env.development、.env.production、package.json 修改雷同,不重复书写

第 2 步:router 设置 base

const router = createRouter({
  scrollBehavior(to, from, savedPosition) {
    return { top: 0 };
  },
  history: createWebHistory(`/${process.env.PROD_PREFIX}`),
  routes
});

PROD_PREFIX 为 webpack 中的环境变量名称,可以自行命名,process.env 在 webpack 中获取环境变量,注意与 vite 区分。

第 3 步:vue.config.js publicPath

const isProduction = process.env.NODE_ENV === 'production';
module.exports = {
  publicPath: isProduction ? `/${process.env.PROD_PREFIX}` : '/',
}
⚠️ webpack 配置 base 字段为 publicPath,注意与 VITE 的 base 字段区分。

5三级及更多目录

如项目具体需求,部署的目录不在二级,二级更深的层级,如目录如下:

safety/midscr/zdldzhpc/pc/video-list

则需要把:

VITE_BASE_PATH=/safety/midscr/zdldzhpc/pc/video-list
📌 注意带不带 "/" 的问题,只要确保 router 和 publicPath 字段拼接成功有 "/" 开头即可。VITE_BASE_PATH 不带 "/" 则 router 和 publicPath 要拼接 "/";如 VITE_BASE_PATH 带 "/" 则不需要拼接,直接取用。