阿里云主机折上折
  • 微信号
您当前的位置:网站首页 > 多页面应用配置问题

多页面应用配置问题

作者:陈川 阅读数:56586人阅读 分类: 构建工具

多页面应用配置问题

Vite.js 作为现代前端构建工具,原生支持单页面应用(SPA),但在实际项目中经常遇到需要配置多页面应用(MPA)的场景。多页面应用指一个项目包含多个独立的 HTML 入口文件,每个页面拥有自己的 JavaScript 和 CSS 资源。

基础目录结构

典型的 MPA 项目目录结构如下所示:

project-root/
├── public/
│   ├── favicon.ico
│   └── global-assets/
├── src/
│   ├── page1/
│   │   ├── index.html
│   │   ├── main.js
│   │   └── style.css
│   ├── page2/
│   │   ├── index.html
│   │   ├── main.js
│   │   └── style.css
│   └── shared/
│       ├── components/
│       └── utils/
└── vite.config.js

Vite 配置核心方案

在 vite.config.js 中需要通过 build.rollupOptions.input 指定多页面入口:

import { defineConfig } from 'vite'
import path from 'path'

export default defineConfig({
  build: {
    rollupOptions: {
      input: {
        main: path.resolve(__dirname, 'src/page1/index.html'),
        about: path.resolve(__dirname, 'src/page2/index.html'),
        contact: path.resolve(__dirname, 'src/page3/index.html')
      }
    }
  }
})

动态入口配置

当页面数量较多时,推荐使用动态扫描方式生成入口配置:

import fs from 'fs'
import path from 'path'

function getPageEntries(dir) {
  const pagesDir = path.resolve(__dirname, dir)
  return fs.readdirSync(pagesDir).reduce((entries, page) => {
    const pagePath = path.join(pagesDir, page)
    const indexPath = path.join(pagePath, 'index.html')
    
    if (fs.existsSync(indexPath)) {
      entries[page] = indexPath
    }
    return entries
  }, {})
}

export default defineConfig({
  build: {
    rollupOptions: {
      input: getPageEntries('src/pages')
    }
  }
})

HTML 模板处理

每个页面的 HTML 需要正确引用资源,Vite 会自动处理资源路径:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Page 1</title>
  <!-- 正确引用 CSS -->
  <link rel="stylesheet" href="./main.css">
</head>
<body>
  <div id="app"></div>
  <!-- 正确引用 JS -->
  <script type="module" src="./main.js"></script>
</body>
</html>

公共代码拆分

为避免重复打包公共依赖,需要配置代码分割:

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (id.includes('node_modules')) {
            return 'vendor'
          }
          if (id.includes('src/shared/')) {
            return 'shared'
          }
        }
      }
    }
  }
})

开发服务器配置

开发环境下需要确保正确返回各个页面:

export default defineConfig({
  server: {
    open: '/page1/index.html' // 默认打开页面
  }
})

环境变量处理

不同页面可能需要不同的环境变量:

// vite.config.js
export default defineConfig({
  define: {
    __APP_ENV__: JSON.stringify(process.env.APP_ENV || 'development')
  }
})

// 页面中使用
console.log('Current env:', __APP_ENV__)

路由匹配问题

在 MPA 中需要特别注意路由配置:

// src/page1/main.js
import { createRouter, createWebHistory } from 'vue-router'

const router = createRouter({
  history: createWebHistory('/page1/'), // 注意基础路径
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
})

静态资源引用

公共静态资源应放在 public 目录,页面专用资源放在各自目录:

public/
  images/
    logo.png  # 全局可用,直接通过 /images/logo.png 引用
src/
  page1/
    assets/
      banner.jpg  # 页面专用,通过相对路径引用

构建输出优化

自定义构建输出目录结构:

export default defineConfig({
  build: {
    outDir: 'dist',
    rollupOptions: {
      output: {
        chunkFileNames: 'assets/js/[name]-[hash].js',
        entryFileNames: 'assets/js/[name]-[hash].js',
        assetFileNames: 'assets/[ext]/[name]-[hash].[ext]'
      }
    }
  }
})

预渲染集成

结合 vite-plugin-ssr 实现部分页面预渲染:

import ssr from 'vite-plugin-ssr'

export default defineConfig({
  plugins: [
    ssr({
      prerender: {
        partial: true,
        pages: ['page1', 'page2']
      }
    })
  ]
})

热更新问题处理

多页面开发时可能出现 HMR 失效,需要检查:

export default defineConfig({
  server: {
    watch: {
      usePolling: true,
      interval: 100
    }
  }
})

代理配置差异

不同页面可能需要不同的 API 代理:

export default defineConfig({
  server: {
    proxy: {
      '/page1-api': {
        target: 'http://localhost:3001',
        rewrite: path => path.replace(/^\/page1-api/, '')
      },
      '/page2-api': {
        target: 'http://localhost:3002',
        rewrite: path => path.replace(/^\/page2-api/, '')
      }
    }
  }
})

自定义页面构建

针对特定页面应用不同的构建选项:

export default defineConfig({
  build: {
    rollupOptions: {
      output: {
        entryFileNames: chunkInfo => {
          return chunkInfo.name.includes('admin') 
            ? 'admin/js/[name]-[hash].js' 
            : 'assets/js/[name]-[hash].js'
        }
      }
    }
  }
})

多框架混合项目

一个项目中同时使用 Vue 和 React:

import vue from '@vitejs/plugin-vue'
import react from '@vitejs/plugin-react'

export default defineConfig({
  plugins: [
    vue({
      include: [/\.vue$/, /\.md$/],
      exclude: ['src/react-pages/**']
    }),
    react({
      include: 'src/react-pages/**'
    })
  ]
})

部署路径问题

处理不同环境的部署基础路径:

export default defineConfig(({ mode }) => {
  const base = mode === 'production' 
    ? 'https://cdn.example.com/project/' 
    : '/'
    
  return {
    base,
    build: {
      assetsDir: 'static'
    }
  }
})

性能监控集成

为不同页面添加性能监控:

// vite.config.js
export default defineConfig({
  plugins: [
    {
      name: 'inject-analytics',
      transformIndexHtml(html, { filename }) {
        const pageName = path.basename(path.dirname(filename))
        return html.replace(
          '</head>',
          `<script>trackPageView('${pageName}')</script></head>`
        )
      }
    }
  ]
})

多主题支持

实现基于页面的主题切换:

// vite.config.js
export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @import "./src/themes/default.scss";
          @import "./src/themes/${process.env.THEME || 'light'}.scss";
        `
      }
    }
  }
})

类型检查配置

为多页面项目配置 TypeScript 路径别名:

import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'

export default defineConfig({
  plugins: [tsconfigPaths()],
  resolve: {
    alias: {
      '@components': path.resolve(__dirname, 'src/shared/components')
    }
  }
})

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

前端川

前端川,陈川的代码茶馆🍵,专治各种不服的Bug退散符💻,日常贩卖秃头警告级的开发心得🛠️,附赠一行代码笑十年的摸鱼宝典🐟,偶尔掉落咖啡杯里泡开的像素级浪漫☕。‌