vite快速上手

前言

Vite是思维比较前卫而且先进的构建工具 他确实解决了一些webpack解决不了的问题,同时降低了一些心智负担, 已经有一些大厂在使用vite去构建项目

  1. vite基于自己得天独厚的优势,他未来一定会占有一席之地, 前段时间阿里的面试已经在问Vite了
  2. Vite是vue团队的官方出品,背靠这么大的生态,vue-cli会在下面两个版本中将vite作为预设构建工具
  3. 未来你使用vue-cli去构建vue项目的时候, 你要写的vue.config.js不再是webpack的配置, 而是vite的配置(目前只基于浏览器项目)
  4. Vite也支持直接构建react项目,也支持构建angular项目,svelte项目也支持构建

构建工具

企业级项目开发过程中, 需要做哪些工作?

  1. 浏览器他只认识html,css,js, 所以就会产生大量编译工作:
  • typescript: 如果遇到ts文件, 我们需要使用tsc将typescript代码转换为js代码
  • React/Vue: 安装react-compiler/vue-complier,将我们写的jsx文件或者.vue文件转换为render函数
  • less/sass/postcss/component-style: 我们需要安装less-loader,sass-loader等一系列编译工具
  • 语法降级: babel--->将es的新语法转换旧版浏览器可以接受的语法
  • 体积优化: uglifyjs--->将我们的代码进行压缩变成体积更小性能更高的文件
  1. 以上这些动作, 只要文件稍微改一点点东西,就要从新跑一遍, 非常麻烦
  2. 需要有一个工具能够帮你把tsc,react-compiler,less,babel,uglifyjs全部集成到一起
  • 这样, 我们只需要关心我们写的业务代码就好了
  • 只要我们写的代码一变化 --->有人帮我们自动去把tsc,react-compiler,less,babel,uglifyjs全部挨个走一遍 --->得到可执行的js
  • 这个工具就叫做**构建工具**
  • 将我们写的浏览器不认识的代码 交给构建工具进行编译处理的过程就叫做打包,
  • 打包完成以后会给我们一个浏览器可以认识的文件
  1. 一个构建工具他到底承担了哪些脏活累活:
  • 模块化开发支持: 支持直接从node_modules里引入代码 + 多种模块化支持
  • .处理代码兼容性: 比如babel语法降级,less,ts 语法转换(**不是构建工具做的,构建工具将这些语法对应的处理工具集成进来自动化处理**)
  • 提高项目性能: 压缩文件,**代码分割**
  • 优化开发体验:
    • 构建工具会帮你自动监听文件的变化,当文件变化以后自动帮你调用对应的集成工具进行重新打包,然后再浏览器重新运行(整个过程叫做热更新,hot replacement)
    • 开发服务器:跨域的问题,用react-cli create-react-element vue-cli 解决跨域的问题

构建工具是什么?

  1. 构建工具让我们不用关心代码如何在浏览器运行,
  2. 让我们专注于业务逻辑的实现
  3. 我们只需要给构建工具提供一个配置文件(如果不配置,他会有默认的配置),
  4. 他就可以按照我们的要实现代码编译, 代码压缩, 代码热更新等诸多功能
  5. 构建工具的本质是一个集成工具

常见的构建有哪些?

  • webpack
  • vite
  • parcel
  • esbuild
  • rollup
  • grunt
  • gulp

vite相对于webpack的优势: 服务的启动和更新速度更快

官方文档: https://cn.vitejs.dev/guide/why.html#the-problems

了解webpack的工作流程

  1. 当我们执行 npm run dev 类似的命令启动前端服务后, 经过这样一个流程:
复制代码
/**
  webpack支持多种模块化
*/
const lodash = require("lodash") // commonjs规范
import Vue from "vue" // es6 module规范


/**
  webpack的转译过程
  1.经过AST抽象语法分析工具分析
  2.得到JS文件的所有导入和导出操作
  3.把所有的导入和导出语法统一为webpack语法
  4.前端不能操作文件, 但是webpack运行在服务端
  5.下面是一个简单复现代码, 了解就行
*/
(function(){
    function webpack_require() {}
   // 通过webpack的配置文件指定入口文件: index.js
   modules[entry](webpack_require)
},({
    "./src/index.js": (webpack_require) => {
        const loadsh = webpack_require("lodash")
        const Vue = webpack_require("vue")
    }
}))


/**
 webpack的转译结果
*/
const loadsh = webpack_require("lodash")
const Vue = webpack_require("vue")
  1. 因为webpack支持多种模块化, 所以需要统一转译模块化代码后才能启动服务, 这种加载全部依赖后再运行项目的模式也叫全量加载
  2. 项目越大, webpack所处理的js代码越多, 启动服务器的时间就越长
  3. webpack能不能改呢? 不能, 因为这种机制性的改动, 后果是不可预估的

了解vite的工作流程

  1. 当我们执行 npm run dev 类似的命令启动前端服务后, 经过这样一个流程:
  1. 这种先启动服务, 再根据使用情况加载依赖的模式称为按需加载
  2. 按需加载相对全量加载, 冷启动和热更新的优势明星, 且项目越大优势越明显
  3. vite会不会直接把webpack干翻?
  • vite是基于es modules支持规范,关注浏览器端的开发体验,
  • webpack拥有更好的兼容性, node环境和浏览器环境都能跑
  • 侧重点不一样,不存在谁替代谁

vite是什么

vite官网搭建vite项目文档教程

vite官网: https://vitejs,dev/guide/#scaffolding-your-frst-vite-project

当我们执行`yarn create vite`命令

  • 帮我们全局安装一个东西: create-vite(vite的脚手架)
  • 直接运行这个create-vite bin目录的下的一个可执行配置

create-vite 和 vite的关系是什么?

  1. create-vite内置了vite, create-vite是脚手架, vite是构建工具
  2. 脚手架是对构建工具的进一步简化, 提供了最佳实践的配置(预设), 可以做到开箱即用
  3. 我们之前接触过的vue-cli就内置了webpack
  4. 我们先学习vite, 再使用create-vite

vite基本使用

用vite启动项目

  1. 创建工程文件

    Document

    export const count = 0

    import { count } from './counter.js'

    console.log(count);

  1. 初始化工程

    npm init -y
    npm i lodash

    import _ from 'lodash'
    console.log(_, "lodash");

    export const count = 0

复制代码
## 上面的报错意思: 就是找不到lodash模块, 检查资源引用的方式, 只识别 / ./ ../方式引入资源;
## 当我们使用非绝对路径或者相对路径引入资源, 浏览器不自动搜寻node_modules呢?
## 答案: 当我们打开HTML网页, 首先通过HTTP加载main.js, 然后再加载counter.js, 然后加载lodash, 然后 lodas还会依赖其他资源, 这些都要通过网络加载, 这些加载是非常占用网络资源的, 所以浏览器不愿意自动加载node_modules资源
## 解决: 使用vite构建工具
  1. 安装vite, 使用vite运行项目

    npm i vite -D

    {
    "name": "01tiyan",
    "version": "1.0.0",
    "description": "",
    "main": "main.js",
    "scripts": {
    "dev": "vite", // 新增
    "test": "echo "Error: no test specified" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "dependencies": {
    "lodash": "^4.17.21"
    },
    "devDependencies": {
    "vite": "^7.1.3"
    }
    }

vite的打包构建

  1. 浏览器默认支持的EsModues规范, 只识别绝对路径或相对路径的方式引入资源, 为什么使用vite启动项目后, 就能识别 import _ from 'lodash' 这段代码了呢?

  2. 在开发环境中, vite在打包的过程中会进行依赖预构建, 效果如下

    ##依赖预构建做了什么事:
    首先vite会找到对应的依赖,然后调用esbuild(对js语法进行处理的一个库),将其他规范的代码转换成esmodule规范,
    然后放到当前目录的node modules/.vite/deps中, 同时对esmodule规范的各个模块进行统一集成

    ##寻找依赖的过程
    找寻依赖的过程是自当前目录依次向上查找的过程,直到搜寻到根目录或者搜寻到对应依赖为止

    ##最终效果

    原始代码 复制代码
    import _ from "lodash"
    打包后的代码 复制代码
    import _ from "/node_modules/.vite/deps/lodash.js"
  3. vite的依赖预构建非常重要, 解决了3个问题:

  • 统一导出格式: 不同的第三方包会有不同的导出格式, 这个vite无法约束, 所以vite找到依赖之后, 会调用esbuild对js语法进行处理, 将其他规范的代码统一转换成esmodule规范, 然后放到当前目录下的 node_modules/.vite/deps中, 同时对esmodules规范的各个模块进行统一集成

  • 路径补全: 由于统一导出格式时把所有的依赖都放在了 .vite/deps 目录中, 所以路径重写就非常方便了, 只要遇到非绝对路径和相对路径的引用, 就尝试路径补全

  • 解决网络多包传输的性能问题: 有了依赖预构建以后无论有多少的额外export 和 import, vite都会尽可能的将他们进行集成, 最后只生成一个或者几个模块

    /**
    原始代码, index.js依赖a.js
    */

    a.js 复制代码
    export default function a() {}
    index.js 复制代码
    export {defaault as a} from './a.js'
    
    // 上面的语法相当于先导入再导出
    // import a from './a.js'
    // export const a = a

    /**
    vite重写之后, 被导入的代码直接替换到文件中(目的是尽可能的集成)
    */

    index.js 复制代码
    function a() {}
  1. 在生产环境中, vite会全权交给rollup这个库去完成打包的, 让代码兼容更多的环境

vite配置文件

复制代码
import { defineConfig } from 'vite'

export default defineConfig({
  optimizeDeps: {
    exclude: [] // 数组中的依赖项不进行依赖构建
  }
})

import { defineConfig } from 'vite'

export default defineConfig({})

import { defineConfig } from 'vite'

export default defineConfig({})

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": () => {
    console.log("生产环境配置文件");
    return ({ ...viteBaseConfig, ...viteProdConfig })
  },
  "serve": () => {
    console.log("开发环境配置文件");
    return ({ ...viteBaseConfig, ...viteDevConfig })
  }
}

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

{
  "name": "01tiyan",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "lodash": "^4.17.21"
  },
  "devDependencies": {
    "lodash-es": "^4.17.21",
    "vite": "^7.1.3"
  }
}

vite的环境变量

基本概念

复制代码
环境变量:  根据当前的代码环境而确定最终值的变量就叫做环境变量

代码环境:  
1,开发环境
2. 测试环境
3,预发布环境
4. 灰度环境
5,生产环境

如何配置

  1. 明确配置需求

    接入百度地图sdk,小程序的sdk
    APP KEY: 测试环境和生产还有开发环境是不一样的key

    • 开发环境: 110
    • 生产环境: 111
      我们去请求第三方sdk接口的时候需要带上的一个身份信息

    对接后端API, 生产环境和开发环境是同一个地址吗? 肯定不是

  2. 新增环境变量文件

    ENV_APP_KEY = 110
    ENV_BASE_URL = http://www.test.api/

    ENV_APP_KEY = 111
    ENV_BASE_URL = http://www.api/

    环境变量文件的分类

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

  3. 配置变量前缀

    import { defineConfig } from 'vite'

    export default defineConfig({
    envPrefix: "ENV_" // 配置vite注入客户端环境变量校验的前缀, 默认是VITE_
    })

  4. 使用环境变量

    import { defineConfig, loadEnv } from "vite"
    import viteBaseConfig from './vite.base.config'
    import viteDevConfig from "./vite.dev.config"
    import viteProdConfig from "./vite.prod.config"

    // 策略模式
    const envResolver = {
    "build": () => {
    console.log("生产环境配置文件");
    return ({ ...viteBaseConfig, ...viteProdConfig })
    },
    "serve": () => {
    console.log("开发环境配置文件");
    return ({ ...viteBaseConfig, ...viteDevConfig })
    }
    }

    export default defineConfig(({ command, mode }) => {

    // loadEnv()方法的作用: 手动确认env文件
    // 参数1: 通过mode传过来的字符擦混
    // 参数2: 当前env文件所在的目录, process.cwd()就是获取node的工作进程目录
    // 参数3: 环境变量的文件名, 默认是.env
    // 为什么? 环境变量文件是可以在配置中修改的, 如果要在这里提前拿到我们定义的环境变量, 就要这么做
    // 补充: process是Node服务给我提供的对象
    const env = loadEnv(mode, process.cwd(), "")
    // 查看生效的环境变量
    console.log("process=", env);

    return envResolvercommand
    })

    // 读取环境变量
    // 开发环境的key是110. 生产环境的key是111
    const getUserPosition = () => {
    console.log("ENV_APP_KEY", import.meta.env.ENV_APP_KEY);

    return {
    APP_KEY: import.meta.env.ENV_APP_KEY
    }
    }
    getUserPosition()

    // 读取环境变量
    // 开发环境是 http://www.test.api/
    // 生产环境是 http://www.api/
    const getBaseUrl = () => {
    console.log("ENV_BASE_URL", import.meta.env.ENV_BASE_URL);

    return {
    ENV_BASE_URL: import.meta.env.ENV_BASE_URL
    }
    }
    getBaseUrl()

    import { count } from './counter.js'
    import './request.js'

    console.log(count);

  5. 启动项目

    启动项目:

    npm run dev

    真正执行的命令:

    npm run dev --mode development

详细的执行流程

  1. 执行 npm run dev命令, node就会去package.json文件的scripts中匹配脚本, 启动 vite 服务

    补充更多细节:

    npm run dev -启动-> vite -真正执行-> vite --mode development

    简单理解为: 自动补全

    npm run dev --mode development -启动-> vite --mode development

  2. vite内置了dotenv这个第三方库, dotenv会自动读取.env文件, 解析这个文件中的环境变量, 并将其注入到process对象下 (不会直接注入,要考虑配置冲突问题)

    import { defineConfig, loadEnv } from "vite"
    import viteBaseConfig from './vite.base.config'
    import viteDevConfig from "./vite.dev.config"
    import viteProdConfig from "./vite.prod.config"

    // 策略模式
    const envResolver = {
    "build": () => {
    console.log("生产环境配置文件");
    return ({ ...viteBaseConfig, ...viteProdConfig })
    },
    "serve": () => {
    console.log("开发环境配置文件");
    return ({ ...viteBaseConfig, ...viteDevConfig })
    }
    }

    export default defineConfig(({ command, mode }) => {
    /**
    按照正常的执行流程, 在这里是拿不到环境变量的
    涉及到vite.config.js中的配置
    -- root
    -- envDir: 用来配置当前环境变量文件的地址
    既然环境变量的文件可以vite.config.js中的配置自定义
    这里连环境变量文件都没确定呢, 怎么拿环境变量中的数据?
    所以强调 "不会直接注入,要考虑配置冲突问题"
    */

    /**
    不过业务中, 我们确实有在这里使用环境变量的需求
    vite给我们提供了一些补偿机制: 我们可以调用vite的loadEnv来手动确认env文件
    因此可以提前拿到环境变量文件中的数据
    强调下 process.cwd()的作用, 就是得到工程目录, 如 D:\UserDatas\Note\21_Vite\01tiyan
    */
    const env = loadEnv(mode, process.cwd(), "")
    console.log(env); // 查看生效的环境变量

    /**
    当我们调用loadenv的时候,他会做如下几件事:
    1,直接找到.env文件不解释, 并解析其中的环境变量 并放进一个对象里
    2,会将传进来的mode这个变量的值进行拼接: 得到.env.development
    3. 根据我们提供的目录(D:\UserDatas\Note\21_Vite\01tiyan), 去取对应的配置文件并进行解析,并放进一个对象
    4.我们可以理解为
    js const baseEnvConfig=读取.env的配置 const modeEnvConfig=读取env相关配置 const lastEnvConfig = {...baseEnvConfig, ...modeEnvConfig }
    5.最终得到全部的环境变量文件的值
    6.如果是客户端,vite会将对应的环境变量注入到import.meta.env里去
    7.vite做了一个拦截, 他为了防止我们将隐私性的变量直接送进import.meta.env中,所以他做了一层拦截,
    8.如果你的环境变量不是以VITE开头的,他就不会帮你注入到客户端中去, 如果我们想要更改这个前缀,可以去使用envPrefix配置
    */

    return envResolvercommand
    })

    补充一个小知识:

    为什么vite.cong.js可以书写成esmdule的形式,这是因为vite他在读取这个vite.cong.js的时候,会率先node去解析文件语法,如果发现你是esmadule规范, 会直接将你的esmadule规范进行替换变成commonjs规范

再添加一个测试环境

  1. 新增环境变量文件

    ENV_APP_KEY = 120
    ENV_BASE_URL = http://测试

  2. 在脚本中配置mode

    {
    "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vite --mode test" // 新增
    }
    }

  3. 启动项目

相关推荐
用户461169657286 分钟前
网站 HTTPS 不稳定?证书排查指南
前端
n876517 分钟前
Playwright Java WEB UI 自动化实现框架与逻辑
java·前端·ui
keyipatience19 分钟前
TypeScript学习(1)
前端·javascript·学习·typescript·html·css3
xifangge20251 小时前
基于 JavaScript 实现 CNC 数控切削参数与螺纹公差纯前端核算引擎
开发语言·前端·javascript
wangruofeng1 小时前
2026 Web 技术选型指南,AI 时代如何选择适合项目的技术栈
前端·aigc·ai编程
honkun61 小时前
vue 表格组件 vxe-table 修改滚动条样式,修改滚动条样式,统一宽度、颜色与自动隐藏
前端·javascript·vue.js
爱勇宝2 小时前
研究数字孪生的这半年,做了个 Demo,也有了一些新想法
前端·程序员
不可能片场2 小时前
工程实践 一个缓存把选片从十分钟压到一分钟
前端·electron
前端小万2 小时前
探索副业五个月,最终以放弃告终
前端·后端·面试
FRing032 小时前
JavaScript入门到精通二十四(正则表达式、元字符、修饰符)
开发语言·前端·javascript·正则表达式