vue3 vite 多页面应用(MPA) vite.config.ts配置

前言

整理了一下vue3多页面结构和vite.config.ts配置, 提供一种MPA思路, 最终实现打包

1. vite.config.ts 完整配置

import { fileURLToPath, URL } from 'node:url'
import path from 'path'
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import vueDevTools from 'vite-plugin-vue-devtools'
import fs from 'fs'
import legacy from '@vitejs/plugin-legacy';
import postCssPxToRem from 'postcss-pxtorem'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from '@vant/auto-import-resolver'
import viteCompression from 'vite-plugin-compression'

// 获取多页面文件
const getEntryPath = () => {
  const pages: Record<string, string> = {}
  const entryPath = path.resolve(__dirname, './')
  const htmlFiles = fs.readdirSync(entryPath).filter((file: string) => file.endsWith('.html'))
  htmlFiles.forEach((item: string) => {
    const pageName = item.split('.')[0]
    pages[pageName] = path.resolve(__dirname, `./${pageName}.html`)
  })
  return pages
}

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd())
  const fileName: string = env.VITE_APP_MODEL
  const pages = getEntryPath()
  let pageInfo: Record<string, string> = {}
  if (fileName) {
    pageInfo[fileName] = pages[fileName]
  } else {
    pageInfo = { ...pages }
  }

  return {
    // 项目根目录(index.html 文件所在的位置)
    root: process.cwd(),

    plugins: [
      vue(),
      vueJsx(),
      vueDevTools(),
      AutoImport({
        resolvers: [VantResolver()],
      }),
      Components({
        resolvers: [VantResolver()],
      }),
      // gzip压缩 生产环境生成 .gz 文件
      viteCompression({
        verbose: true, // 输出压缩详情(可选)
        disable: false,
        threshold: 10240, // 仅压缩 >10KB 的文件
        algorithm: 'gzip', // 或 'brotli'(需服务端支持)
        ext: '.gz', // 压缩文件扩展名
        deleteOriginFile: false, // 是否删除原始文件
        compressionOptions: { level: 9 }, // 压缩级别,1-9,越高压缩率越大
        filter: /.js|css|json|html|ico|svg$/i, // 过滤不压缩的文件类型
      }),
      legacy({
        // 定义支持的浏览器
        targets: ["defaults", "not IE 11", "Android >= 4.4", "ios >= 9"],
        modernPolyfills: true,
      }),
    ],

    resolve: {
      alias: {
        '@': fileURLToPath(new URL('./src', import.meta.url)),
        '~/': `${path.resolve(__dirname, './src')}`,
        '@style': fileURLToPath(new URL('./src/assets/style', import.meta.url)),
        '@images': fileURLToPath(new URL('./src/assets/images', import.meta.url)),
        '@one': path.resolve(__dirname, './src/modules/one'),
        '@two': path.resolve(__dirname, './src/modules/two'),
      },
      // 导入时想要省略的扩展名列表。 vite官方不建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。
      extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],
    },

    css: {
      // 按需导入
      preprocessorOptions: {
        less: {
          // additionalData: '@import "@/assets/style/main.less";',
        },
      },
      postcss: {
        plugins: [
          postCssPxToRem({
            // postcss-pxtorem 插件的版本需要 >= 5.0.0
            rootValue({ file }) {
              // return file?.indexOf('vant') !== -1 ? 37.5 : 75;
              return 37.5
            },
            // 所有px均转化为rem
            propList: ['*'],
            // 若想设置部分样式不转化 可以在配置项中写出
            // eg: 除 border和font-size外 所有px均转化为rem
            // propList: ["*", "!border","!font-size"],
          }),
        ],
      },
    },

    server: {
      port: 3000,
      open: false,
      hot: true,
      cors: true, // 跨域设置允许
      proxy: {
        // 选项写法
        '/api': {
          target: 'http://xxx.com',
          changeOrigin: true,
          rewrite: (path) => path.replace(/^\/api/, ''),
        },
        // 简写(字符串)
        '/mock': env.VITE_BASE_API,
        // 代理 websockets 或 socket.io 写法:ws://localhost:5173/socket.io -> ws://localhost:5174/socket.io
        '/socket.io': {
          target: 'ws://localhost:5174',
          // 支持 websocket
          ws: true,
        },
      },
    },

    build: {
      sourcemap: mode !== 'production', // 默认false(可省略),是否构建sourcemap文件(生产不需要)
      // outDir: 'dist', //指定输出路径(相对于 项目根目录). 默认dist(可省略)
      // assetsDir: 'assets', //指定生成静态资源的存放路径 默认assets(可省略)
      // 客户端默认构建是esbuild,需安装terser:`npm i -D terser`
      minify: 'terser',
      rollupOptions: {
        // input: {
        //   one: path.resolve(__dirname, 'one.html'),
        //   two: path.resolve(__dirname, 'two.html'),
        // },
        input: pageInfo,
        output: {
          dir: `./dist/${fileName}`,
          // 静态资源打包分类
          assetFileNames: 'assets/[name].[hash].[ext]',
          chunkFileNames: 'js/[name].[hash].js',
          entryFileNames: 'js/[name].[hash].js',
        },
      },
      terserOptions: {
        compress: {
          // 生产环境移除console、debugger
          drop_console: env.VITE_ENV === 'production',
          drop_debugger: env.VITE_ENV === 'production',
        },
      },
      // cssCodeSplit: true,         // 启用CSS代码分割
      //默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
      emptyOutDir: true,
    },
  }
})

2. 多页面 package.json 环境变量 moudles结构附图

26aa39c85632d22af7917d81b9cf71a0

2.1 打包结果

dist/
image

dist/one/
image

2.2 说明

这里也可以把one.html放到moudles和main.ts同级, 改一下vite.config.ts引入入口文件配置

打包和package.json配置需要再完善一下,这里是分享一种方法

posted @ 2025-07-23 15:51  sk-xm  阅读(557)  评论(0)    收藏  举报