返回

Vite/Preact动态代理配置最佳实践:环境变量与Nginx

javascript

Vite/Preact 非硬编码代理最佳实践

在Vite+Preact项目中使用非硬编码方式配置代理,以适配后端服务地址动态变化的情况,是一个常见的需求。这个问题通常出现在后端服务部署在动态IP环境时,如Raspberry Pi等设备。本文将讨论此场景下的最佳实践方案,分析现有方案的优劣,并提供更优的解决方案。

问题分析

目前方案通过Node.js的 os 模块获取本机非内部IP地址,并动态构建代理目标地址。这种方式在开发环境能解决问题,但存在以下不足:

  1. 依赖Node.js os 模块: 此方案限制了代码的可移植性,如果在非Node.js环境(如浏览器端)需要类似逻辑,则无法直接复用。
  2. 非生产环境方案: 该方案主要用于开发阶段,在生产环境中,通常会通过Nginx等反向代理服务器处理请求转发,不会在前端代码中动态配置代理。
  3. IP 地址获取时机: os.networkInterfaces() 获取的IP地址是在Vite启动时确定的,如果后续网络环境变化,代理地址不会自动更新。
  4. 安全性考量: 直接暴露服务器内网IP地址存在一定的安全风险。

解决方案

基于以上分析,推荐以下两种解决方案,分别适用于开发环境和生产环境。

方案一: 运行时环境变量

该方案将后端服务地址配置为环境变量,在Vite启动时读取。这种方式更灵活,方便在不同环境切换后端服务地址,同时也避免了对 os 模块的依赖。

操作步骤:

  1. 修改 vite.config.js 文件:

    import { defineConfig, loadEnv } from 'vite';
    import preact from '@preact/preset-vite';
    
    export default defineConfig(({ mode }) => {
      const env = loadEnv(mode, process.cwd(), ''); // 加载 .env 文件
    
      return {
        plugins: [preact()],
        server: {
          port: 3000,
          host: '0.0.0.0',
          proxy: {
            '/api': {
              target: env.VITE_API_BASE_URL || 'http://localhost:8000', // 默认值
              changeOrigin: true,
              rewrite: (path) => path.replace(/^\/api/, ''),
            },
            '/socket': {
              target: (env.VITE_WS_BASE_URL || 'ws://localhost:8000').replace('http', 'ws'),  // 默认值,注意替换协议
              changeOrigin: true,
              ws:true, // 启用ws代理
              rewrite: (path) => path.replace(/^\/socket/, ''),
            },
          },
        },
      };
    });
    
  2. 创建 .env.development.env.production 文件:

    .env.development (开发环境)

    VITE_API_BASE_URL=http://192.168.0.99:8000
    VITE_WS_BASE_URL=ws://192.168.0.99:8000
    

    .env.production (生产环境)

    VITE_API_BASE_URL=/api
    VITE_WS_BASE_URL=/socket
    
  3. 启动Vite:

    npm run dev  # 开发环境
    npm run build && npm run preview # 生产环境
    

代码解释:

  • 使用vite提供的loadEnv方法加载.env文件。 .env 文件存储环境变量,可以区分不同环境加载不同的环境变量配置。
  • VITE_API_BASE_URLVITE_WS_BASE_URL 分别配置API和WebSocket的基地址。
  • 开发环境使用Raspberry Pi的具体IP地址和端口号。
  • 生产环境通过相对路径/api/socket进行代理,由反向代理服务器(如Nginx)处理实际的转发。
  • /socket代理配置添加ws:true选项以确保WebSocket代理正常工作。
  • 代码提供了默认值http://localhost:8000,确保在未设置环境变量时,项目也能正常启动。

安全性建议: 不要在.env文件中存储敏感信息,如密码、密钥等。生产环境应使用更安全的方式管理配置信息,如环境变量或配置中心。

方案二: 反向代理服务器

生产环境下,强烈推荐使用Nginx或类似的反向代理服务器处理请求转发。这种方式更安全、更可靠,也更符合生产环境部署的最佳实践。

操作步骤(以Nginx为例):

  1. 安装 Nginx。

    具体安装方式取决于您的操作系统,可参考Nginx官方文档。

  2. 配置 Nginx 配置文件,通常位于 /etc/nginx/sites-available//etc/nginx/conf.d/ 目录下,创建一个新的配置文件,如 my-app.conf

    server {
        listen 80;  # 监听端口
        server_name your_domain.com;  # 域名或IP地址
    
        location /api {
            proxy_pass http://192.168.0.99:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
       location /socket {
             proxy_pass http://192.168.0.99:8000;
             proxy_http_version 1.1;
             proxy_set_header Upgrade $http_upgrade;
             proxy_set_header Connection "upgrade";
             proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    
         }
        location / {
            root /path/to/your/dist;  # Vite打包后的静态文件目录
            try_files $uri $uri/ /index.html;  # 支持SPA路由
            index index.html;
        }
    }
    

    注意 :

    • 替换your_domain.com为你的域名或者服务器公网IP。
    • /path/to/your/dist 为Vite打包生成的静态资源目录。
    • /apivite.config.js 中定义的 proxy 前缀对应。
  3. 启用配置文件并重启 Nginx:

    sudo ln -s /etc/nginx/sites-available/my-app.conf /etc/nginx/sites-enabled/
    sudo nginx -t # 测试配置文件是否正确
    sudo systemctl restart nginx
    
  4. 修改 vite.config.js,将生产环境下的代理目标地址设置为相对路径:

     export default defineConfig(({ mode }) => {
        const env = loadEnv(mode, process.cwd(), '');
    
        return {
            // ...其他配置
            server: {
                // ...其他配置
                proxy: {
                  '/api': {
                    target:  env.VITE_API_BASE_URL, // 生产环境下值为/api
                    changeOrigin: true,
                    rewrite: (path) => path.replace(/^\/api/, ''),
                  },
                  '/socket': {
                    target: env.VITE_WS_BASE_URL, //  生产环境下值为/socket
                    changeOrigin: true,
                    ws: true,
                    rewrite: (path) => path.replace(/^\/socket/, ''),
                 },
                },
            },
        };
    });
    
  5. 重新构建 Vite 项目:

    npm run build
    

代码解释:

  • Nginx 监听80端口,并将 /api/socket 路径的请求转发到后端服务,生产环境中这里替换成实际的后端服务地址。
  • / 路径的请求则指向Vite打包生成的静态文件。
  • Nginx 配置中设置了 proxy_set_header ,以便将客户端真实 IP 等信息传递给后端服务。

安全性建议: 配置Nginx时,可以使用HTTPS协议,并启用防火墙,限制对服务器的访问。定期更新Nginx版本,以修复安全漏洞。

总结

在Vite+Preact项目中配置代理,应区分开发环境和生产环境采取不同的方案。开发环境可以使用运行时环境变量灵活配置后端服务地址,生产环境则应使用Nginx等反向代理服务器,提高系统的安全性、可靠性和性能。选择适合项目需求的方案,并遵循安全最佳实践,可以构建更健壮的应用程序。