Featured image of post Vite配置文件

Vite配置文件

声明环境变量配置文件

在根目录下新建文件 .env.dev以及 .env.prod环境变量配置文件。

.env.dev开发环境

# 变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_BASE_PATH = 'https://vitejs.dev.cn/'

.env.prod生产环境

# 变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_BASE_PATH = 'https://vitejs.prod.cn/'

在配置中使用环境变量

配置 Vite | Vite 官方中文文档

环境变量通常可以从 process.env 获得。

注意 Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完 Vite 配置后才能确定加载哪一个,举个例子,rootenvDir 选项会影响加载行为。不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。

import { defineConfig, loadEnv } from 'vite'

export default ({ mode }) => {
  // 根据当前工作目录中的 `mode` 加载 .env 文件
  const env = loadEnv(mode, process.cwd())
  return defineConfig({
    base: env.VITE_BASE_PATH,
  })
}
  • loadEnv函数:根据传入的mode参数,找到并读取对应的环境配置文件(如.env.dev.env.prod等)中的环境变量,然后将这些变量 解析成一个对象 ,并将这个对象赋值给env常量,使得这些环境变量可以在当前进程中使用(如env.VITE_BASE_PATH)。
  • mode:通常是一个字符串,表示当前的环境模式,比如developmentproduction等。这个参数用于指定从哪个环境配置文件中加载变量。
  • process.cwd()process对象的一个方法,返回Node.js进程的当前工作目录。这个参数用于指定环境配置文件所在的目录。同**__dirname**的值相同。

如果要使用 dev 环境,就要在package.json里添加配置,比如:

  "scripts": {
    "dev": "vite --mode dev",
    "build:dev": "vite build --mode dev",
    "build:prod": "vite build --mode prod",
    "preview": "vite preview",
  },

Vite 中的 plugin 配置

Vite提供的官方插件

@vitejs/plugin-vue:默认插件

默认配置只有 vue 插件,当有其他需求时,需要自行导入其他插件;

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

// https://vitejs.dev/config/
export default defineConfig(({ mode}) => {
  const env = loadEnv(mode, process.cwd());
  return {
    plugins:[vue()] // 默认配置vue插件
  };
})

@vitejs/plugin-legacy:兼容旧版浏览器

新代码无法兼容旧版浏览器

在使用 Vite 开发时,默认情况下仅处理语法转译,不包含任何 polyfill。这对于较低版本的浏览器来说,可能会导致它们无法支持 ES6 的语法和新 API,如 ProxySymbolPromise 等。为了解决这个问题,我们可以使用 @vitejs/plugin-legacy 插件。

作用

这个插件可以自动生成兼容旧版浏览器的代码块,并提供所需的 polyfill(补丁),使得不支持原生 ESM 的浏览器能够按需加载这些代码

在项目中安装插件:npm install @vitejs/plugin-legacy --save-dev

–save-dev 等价于 -D , –save 可省略

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import legacy from '@vitejs/plugin-legacy'

export default ({ mode }) => {
	const env = loadEnv(mode, process.cwd())
  return defineConfig({
    plugins: [
      vue(),
      legacy({
          targets: ['defaults', 'ie >= 11', 'chrome 52'],  // 需要兼容的目标列表,可以设置多个
          additionalLegacyPolyfills: ['regenerator-runtime/runtime'], // 需要加载的额外旧版浏览器兼容性补丁
          renderLegacyChunks:true, // 是否需要为旧版浏览器渲染额外的代码块
          polyfills:[
              'es.symbol',
              'es.array.filter',
              'es.promise',
              'es.promise.finally',
              'es/map',
              'es/set',
              'es.array.for-each',
              'es.object.define-properties',
              'es.object.define-property',
              'es.object.get-own-property-descriptor',
              'es.object.get-own-property-descriptors',
              'es.object.keys',
              'es.object.to-string',
              'web.dom-collections.for-each',
              'esnext.global-this',
              'esnext.string.match-all'
          ]
      })
    ]
  })
})

renderLegacyChunks: 启用后,Vite 会为不支持现代 JavaScript 特性的浏览器生成特定代码块,确保它们能够正常加载和运行应用程序。

比如说,对于一些较旧版本的浏览器,它们可能无法理解和运行现代的 ES6 语法或某些新的 JavaScript API。为了让这些浏览器也能正常显示和运行应用程序,Vite 会创建专门针对它们的代码块,这些代码块经过了适当的转换和处理,以适应这些浏览器的能力。

unplugin-auto-import/vite:自动导入Vue和Vue相关库的API

在项目中安装插件:npm install unplugin-auto-import --save-dev

–save-dev 等价于 -D , –save 可省略

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite' // 导入按需自动加载API插件

// https://vitejs.dev/config/
export default defineConfig(({ mode}) => {
  const env = loadEnv(mode, process.cwd()); 
  return {
    plugins:[
      vue(), // 默认配置vue插件
      AutoImport({ imports: ["vue", "vue-router"] }), // 配置vue、vue-router的API自动加载
    ]
  }
})

上面配置成功后,vue3组件中就不需要再手动书写 import 语句引入 vue3 API,可直接在页面中书写 vue3 API,并且控制台不会报错,不会影响页面渲染

unplugin-vue-components/vite:自动注册Vue组件

在项目中安装插件:npm install unplugin-vue-components --save-dev

常用于组件库的自动导入

import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' // 自动引入对应的组件样式
// import { VantResolver } from '@vant/auto-import-resolver' // 自动引入对应的组件样式

// https://vitejs.dev/config/
export default defineConfig(({ mode}) => {
  const env = loadEnv(mode, process.cwd());
  return {
    plugins:[
      vue(), // 默认配置vue插件
      AutoImport({
        resolvers: [ElementPlusResolver()],
      }),
      Components({
        resolvers: [ElementPlusResolver()],
      }),
      /*
      AutoImport({
        resolvers: [VantResolver()],
      }),
      Components({
        resolvers: [VantResolver()],
      }),
      */
    ]
  }
})

Vite 中的 resolve 配置

import { defineConfig, loadEnv } from 'vite'
import path from 'path'
import { fileURLToPath, URL } from 'node:url'

// https://vitejs.dev/config/
export default defineConfig(({ mode}) => {
  const env = loadEnv(mode, process.cwd());
  return {
    resolve:{ // 设置模块如何被解析
      alias: {
          // 第一种方式(最简洁)
          '@': path.resolve(__dirname, './src'),
          // 第二种方式
          '@style': fileURLToPath(new URL('./src/assets/style', import.meta.url)),
          '@images': fileURLToPath(new URL('./src/assets/images', import.meta.url)),
        },
        // 在导入模块时可以省略的文件扩展名。隐式导入越多,解析路径所需的时间就越多。所以最好明确导入路径
        // 选项默认为 ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']
        extensions: ['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json']
    }
  }
})

共享选项 | Vite 官方中文文档:resolve.extensions

导入时想要省略的扩展名列表。注意, 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。

Vite 中的 css 配置

在项目中安装插件:npm i -D postcss-pxtorem

import { defineConfig, loadEnv } from 'vite'
import postCssPxToRem from 'postcss-pxtorem' // 将 px 值转换成 rem 值,行内样式中的px不会被转化为rem

// https://vitejs.dev/config/
export default defineConfig(({ mode}) => {
  const env = loadEnv(mode, process.cwd()); 
  return {
    css:{
      devSourcemap: true, // 可以查看 CSS 的源码
      postcss: {
        plugins: [
          postCssPxToRem({
            rootValue: 37.5, 	// 1rem的大小
            /*
            	// 当UI设计稿的全屏基准宽度是750px时 此处设置的值为75 但项目中使用了vant组件库 vant的设计稿总宽度是375px 其十分之一应是37.5(需要区分设置)
							rootValue ({ file }) {
                return file.indexOf('vant') !== -1 ? 37.5 : 75
              },
            */
            propList: ['*'], 			// 需要转换的属性,*代表全部转换
            // 若想设置部分样式不转化 可以在配置项中写出
            // eg: 除 border和font-size外 所有px均转化为rem
            // propList: ["*", "!border","!font-size"], 
          }),
          // 其他插件
        ]
      }
    }
  }
})

常见的 css 选项

  1. preprocessorOptions:用于配置预处理器(如 Sass、Less、Stylus 等)的选项。例如,你可以在这里配置 Sass 的全局变量、mixin 等。
import { defineConfig } from 'vite';

export default defineConfig({
  css: {
    preprocessorOptions: {
      less: {
        // 启用严格模式
        math: 'strict',
        // 启用 JavaScript 表达式
        javascriptEnabled: true,
        // 导入变量文件
        additionalData: `@import "${path.resolve('src/styles/variables.less')}";`
      }
    }
  }
});

import { defineConfig } from 'vite';

export default defineConfig({
  css: {
    preprocessorOptions: {
      scss: {
        // 导入变量文件
        'additionalData': `@import "${path.resolve('src/styles/variables.scss')}";`
      }
    }
  }
});

 Sass  Less 预处理器中`math`  `javascriptEnabled` 并不是默认的配置选项它们是特定于某些预处理器插件 `sass-loader`  `less-loader`的配置选项

- `math`这个选项用于配置 Sass 的数学运算模式默认情况下Sass 会尽可能地简化数学表达式例如 `1px + 2px` 会被简化为 `3px`如果你希望 Sass 按照数学规则进行精确计算而不进行任何简化你可以设置 `math: 'strict'`

- `javascriptEnabled`这个选项用于启用或禁用 Sass 中的 JavaScript 表达式默认情况下Sass 会禁用 JavaScript 表达式以防止潜在的安全风险如果你希望启用 JavaScript 表达式你可以设置 `javascriptEnabled: true`
  1. postcss:用于配置 PostCSS 的选项。例如,你可以在这里添加 PostCSS 插件,如 autoprefixerpostcss-pxtorem 等。
css: {
  postcss: {
    plugins: [
      require('autoprefixer'),
      require('postcss-pxtorem')({
        rootValue: 16,
        propList: ['*'],
        selectorBlackList: ['.ignore', '.hairlines']
      })
    ]
  }
}
  1. modules:用于配置 CSS Modules。你可以在这里设置 CSS Modules 的行为,如是否使用局部作用域、是否生成 JSON 文件等。
css: {
  modules: {
    scopeBehavior: 'local',
    globalModulePaths: [/global\.css$/],
    generateScopedName: '[name]__[local]___[hash:base64:5]'
  }
}

- scopeBehaviour决定 CSS 是默认作用于局部还是全局可选值为 local局部默认值 global全局)。

- globalModulePaths可以通过正则表达式指定哪些文件不参与模块化处理

- generateScopedName定义生成类名的规则默认情况下是 [hash:base64]你可以自定义为更易读的格式例如 [name]__[local]___[hash:base64:5]
  1. devSourcemap:用于配置开发环境下的 CSS Source Map。默认为 false
css: {
  devSourcemap: true
}

Vite 中的 server 配置

代理的原理

在开发环境中,使用代理可以有效解决跨域问题,代理的工作原理如下:

  1. 请求转发:客户端将请求发送到代理服务器,代理服务器将其转发给目标服务器。
  2. 响应转发:目标服务器处理请求后,将响应返回给代理服务器,随后代理再返回给客户端。
  3. 中间处理:代理服务器可以在请求和响应过程中进行额外处理,如修改请求头、添加身份验证信息和缓存响应。

vite.config.js 中进行代理配置:

export default {
	server: {
      open: true,
      port: 8080, // 代理服务器是运行在http://localhost:8080上的开发服务器。
      hmr: true,
      headers: { Connection: 'keep-alive' }, // 设置HTTP请求头。在这l,设置了Connection: 'keep-alive',表示保持连接活跃。
      proxy: {
        '/apiProxy': { 
          target: 'http://服务器地址:端口号', // 目标服务器
          changeOrigin: true, // 允许跨域。它修改了HTTP请求头中的Origin字段,使其与目标服务器的主机名和端口匹配,从而绕过了浏览器的同源策略限制。
          headers: { Connection: 'keep-alive' }, // 为代理请求设置 HTTP 头部信息,这里设置了Connection: 'keep-alive',表示保持连接活跃。
          ws: true, // 开启 websockets 代理
          secure: false, // 验证 SSL 证书
          rewrite: (path) => path.replace(/^\/apiProxy/, '') // 重写请求路径,将/apiProxy前缀去掉,使请求直接发送到目标服务器。
        }
      }
		}
}

WebSocket 代理: WebSocket 是一种在单个TCP连接上进行全双工通信的协议。它允许服务器和客户端之间进行实时、双向的数据交换。与HTTP不同,WebSocket连接一旦建立,就可以在客户端和服务器之间进行持续的、低延迟的数据传输。适合需要即时交互的应用。

全双工通信:是一种通信模式,允许数据在两个方向上同时进行传输,即数据可以在同一时间点在两个方向上同时发送和接收。

Vite 中的 build 配置

import { defineConfig } from 'vite';

export default defineConfig({
  // 构建选项
  build: {
    // 构建输出目录,默认为 'dist',可省略
    outDir: 'dist',
    // 静态资源目录,默认为 'assets',可省略
    assetsDir: 'assets',
    // 构建目标(浏览器版本),默认为根据项目依赖自动推断
    target: 'es2015',
    // 是否生成 Source Map,默认为开发环境下为 true,生产环境下为 false,可省略
    sourcemap: true,
    // 是否压缩输出文件,boolean | 'terser' | 'esbuild',客户端构建默认为'esbuild',SSR构建默认为 false
    minify: 'esbuild',
    // 启用/禁用 CSS 代码拆分,默认为true,如果禁用,整个项目中的所有 CSS 将被提取到一个 CSS 文件中。
    cssCodeSplit: 'false'
    // Rollup 选项
    rollupOptions: {
      // 入口文件,默认为 'src/main.js'
      input: 'src/main.js',
      // 输出选项
      output: {
        // 输出目录,默认为 'dist'
        dir: 'dist',
        // 输出格式(esm、cjs、iife、umd、system),默认为 'es'
        format: 'es',
        // 全局变量,用于将库暴露为全局变量
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
});
Licensed under CC BY-NC-SA 4.0