Vite 学习笔记(三):Vite 的依赖预构建与相关配置与环境区分

Vite 依赖预构建

什么是依赖预构建?

vite会找到对应的依赖, 然后调用 esbuild (对js语法进行处理的一个库), 将其他规范的代码(比如 commonJS、UMD)转换成esmodule 规范, 然后放到当前目录下的node_modules/.vite/deps, 同时对esmodule规范的各个模块进行统一集成

为什么要预构建?

  • Vite 的开发服务器将所有代码视为原生 ES 模块。而不同的第三方包会有不同的导出格式(这个是vite没法约束人家的事情),所以预构建的目的就是将依赖转为 ES 模块统一模块规范。
  • 路径的处理上可以直接使用 .vite/deps, 方便路径重写。
  • 优化http多包传输的性能问题。
    • 因为原生 esmodule 规范不敢支持 node_modules。原因之前也说了,对于每一个 ES 模块来说,浏览器会去请求这个模块。对于像 lodash-es 这样有超过 600 个内置模块的 ES 模块来说,那我浏览器是不是要去请求 600 次? 这样会造成网络拥塞,导致页面的加载速度相当慢。
    • 而预构建后,无论他有多少的额外 export 和 import 的 ES 模块, vite 都会尽可能的将他们进行集成,最后只生成一个或者几个模块。这才能够说明可以用来优化http多包传输的性能问题

Vite 依赖预构建的相关配置

不要预构建

首先,创建 vite.config.js,该文件等价于 webpack.config.js 然后再该文件里面配置如下内容:

js 复制代码
export default {
    optimizeDeps:{
        exclude:["lodash-es"] // 当遇到lodash-es的时候 不进行预构建
    }
}

它的意思是,遇到 lodash-es 这个模块时,不进行预构建。此时,我们运行 vite 开发环境,打开网络请求,会发现它对 lodash-es 的 600多个 ES 模块 发送了网络请求

语法提示处理

defineConfig

在 vscode 里面我们可以通过 defineConfig 这个函数去配置我们的 vite,这个时候配置时会有语法提示。

js 复制代码
import { defineConfig } from "vite";

export default defineConfig({
    //...配置
})

为什么这样就会有语法提示了?因为有 TS 类型判断嘛(返回的是个 UserConfig 类型的配置对象)

类型注解

/** @type import('vite').UserConfig*/

环境处理

defineConfig中,我们可以去获取运行的命令 command 以及运行的环境

所以我们可以定义三个文件 vite.base.config.jsvite.dev.config.jsvite.prod.config.js 来配置不同环境

js 复制代码
// vite.base.config.js
import { defineConfig } from "vite";

export default defineConfig({
  optimizeDeps: {
    exclude: ["lodash-es"], // 当遇到lodash-es的时候 不进行预构建
  },
});

// vite.dev.config.js
import { defineConfig } from "vite";

export default defineConfig({

});

// vite.prod.config.js
import { defineConfig } from "vite";

export default defineConfig({

});

然后在 vite.config.js 里面引入这三个环境配置

js 复制代码
import { defineConfig } from "vite"
import viteBaseConfig from "./vite.base.config"
import viteDevConfig from "./vite.dev.config"
import viteProdConfig from "./vite.prod.config"

const envResolver = {
  "build": () => Object.assign({}, viteBaseConfig, viteProdConfig),
  "serve": () => Object.assign({}, viteDevConfig, viteDevConfig)
}

export default defineConfig(({command, mode})=>{
  return envResolver([command])();
})

这样,我们就可以区分环境进行对应的配置了

环境变量

vite 内置了 dotenv 这个第三方库来处理环境变量

dotenv 会自动读取 .env 文件, 并解析这个文件中的对应环境变量,并将其注入到 process 对象下(但是 vite 考虑到和其他配置的一些冲突问题, 他不会直接注入到process对象下)

loadEnv

vite 给我们提供了一个 loadEnv 方法来获取环境变量

js 复制代码
// vite.config.js

const envResolver = {
  "build": () => Object.assign({}, viteBaseConfig, viteProdConfig),
  "serve": () => Object.assign({}, viteBaseConfig, viteDevConfig)
}

export default defineConfig(({command, mode})=>{
  // mode 为执行指令环境
  // npm run serve => mode:development
  // npm run build => mode:production
  
  // process.cwd()方法: 返回当前 node 进程的工作目录
  const env = loadEnv(mode, process.cwd(), '')
  console.log('env', env)
  return envResolver[command]();
})

vite 不同环境变量

.env: 所有环境都需要用到的环境变量

.env.development: 开发环境需要用到的环境变量(默认情况下vite将我们的开发环境取名为development)

.env.production: 生产环境需要用到的环境变量(默认情况下vite将我们的生产环境取名为production)

js 复制代码
export default defineConfig(({command, mode}) => {
 
  const env = loadEnv(mode, process.cwd(), '')
  console.log('env==========env', env)

  return envResolver[command]();

  // mode 为执行指令环境
  // npm run serve => mode:development
  // npm run build => mode:production
})

当我们执行脚本命令 npm run dev 的时候,此时 modedevelopment,然后我们的 loadEnv 会接受 mode 作为参数,调用 loadenv,接下来它会去做下面的事情:

  1. 直接找到 .env 文件,并解析其中的环境变量并放进一个对象里

  2. 会将传进来的 mode 值进行拼接(此时是 development):.env.development,并根据我们提供的目录去取对应的配置文件并进行解析,并放进一个对象

  3. 相当于:

    js 复制代码
      const EnvConfig1 = 读取 .env1 相关配置
      const EnvConfig2 = 读取 .env2 相关配置
      const EnvConfig3 = { ...EnvConfig1, ...EnvConfig2 }

import.meta.env

import.meta.env 这个是官方提供的一个变量对象,他能够有效的读取到当前环境变量

此时我们的 .env.development 文件中的额外配置是:

js 复制代码
ENV = 112
BASE_URL = 'https:/lxq/api'

然后我们在 index.js 中打印一下看看:

我们发现,上面打印的是默认的环境变量对象,其中并没有我们设置的 ENV、BASE_URL

这是因为 vite 做了一个拦截, 他为了防止我们将隐私性的变量直接送进 import.meta.env 中, 所以他做了一层拦截, 如果你的环境变量不是以 VITE 开头的, 他就不会帮你注入到客户端中去。

更改 .env.development 的变量前缀

js 复制代码
VITE_ENV = 112
VITE_BASE_URL = 'https:/lxq/api'

此时控制台打印如下:

如果我们想要更改这个 VITE 前缀, 可以去使用 envPrefix 配置

js 复制代码
import { defineConfig } from "vite";

export default defineConfig({
  envPrefix: 'LXQ'
});

修改变量前缀

js 复制代码
LXQ_ENV = 112
LXQ_BASE_URL = 'https:/lxq/api'

控制台打印:

相关推荐
景天科技苑3 小时前
【vue3+vite】新一代vue脚手架工具vite,助力前端开发更快捷更高效
前端·javascript·vue.js·vite·vue项目·脚手架工具
niech_cn2 天前
vite + vue3 + ts解决别名引用@/api/user报错找不到相应的模块
vite
Amd7944 天前
Nuxt.js 应用中的 vite:compiled 事件钩子
自定义·vite·编译·nuxt·热更新·性能·钩子
黑色的糖果4 天前
npm上传自己封装的插件(vue+vite)
前端·vue.js·npm·vite
软件小伟5 天前
Vite是什么?Vite如何使用?相比于Vue CLI的区别是什么?(一篇文章帮你搞定!)
前端·vue.js·ecmascript·vite·vue vli
Amd7945 天前
Nuxt.js 应用中的 vite:serverCreated 事件钩子
中间件·开发·vite·日志·nuxt·跨域·钩子
亦世凡华、5 天前
React--》如何高效管理前端环境变量:开发与生产环境配置详解
react·vite·环境变量·env·env配置
19组清风6 天前
对于模块动态加载,Vite 内部做了哪些优化
前端·vite·前端工程化
Amd7946 天前
Nuxt.js 应用中的 vite:configResolved 事件钩子
vite·配置·nuxt·构建·钩子·动态·调整