Vite 基本配置及原理

news2025/1/20 7:04:54

Vite 基本配置及原理

  • 介绍
  • vite.config.js
    • optimizeDeps.exclude
    • 不同环境的 vite 配置
    • css配置
      • Vite 对 css 的处理
      • Vite 对 cssmodule 的处理和配置
      • Vite 对预处理器的配置
      • devSourcemap
      • Vite 对 postcss 的支持
    • Vite 静态资源别名设置
    • Vite 生产环境配置

介绍

如果你还不知道 Vite,或者不知道为什么有了 Webpack 还要出现 Vite,可以先移步看 从零入门 Vite 与 Webpack 对比 。

vite.config.js

前文说过,Vite 使用 Koa 或者 express 这种后端服务框架搭建了一个开发服务器,当我们执行 npm run dev 命令去启动这个开发服务器时,会提示我们访问 http://127.0.0.1:5173/ 这个服务地址打开项目,这就是我们的本地开发服务器。

在服务器启动后 node 会去读取项目配置文件 vite.config.js,通过配置的内容来启动我们的服务器,比如配置中有很多的插件 plugins,服务器启动过程中,在不同的插件的不同生命周期会执行插件不同的配置内容,这些配置会直接返回并影响这个本地服务器最终给出的结果,也就是呈现在浏览器的内容。

先从零开始一个 Vite 构建实例:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vite</title>
</head>
<body>
  <script src="./main.js" type="module"></script>
</body>
</html>
// main.js
import _ from 'lodash-es'
console.log('lodash', _)
// package.json
"scripts": {
  "dev": "vite",
  "build": "vite build"
}
npm init -y
npm i lodash-es

scripts 是 npm 提供的脚本命令功能,也可以使用工程内部执行指令 npx,即: npm run devnpx vite 都可以

执行 npm run dev 命令启动项目后,Vite 会自动解析根目录下名为 vite.config.js 文件:

// vite.config.js
export default {
	// 配置内容
	...
}

思考:vite.config.js 是 node 来执行的,那为什么它 可以书写成 ESModule 的形式?
因为:Vite 服务器启动后会读取 vite.config.js 文件,根据配置的内容是启动和配置服务器,这时候 node 会率先去解析文件语法,如果发现是 ESModule 规范会直接将其替换成 CommonJS 规范。

optimizeDeps.exclude

在预构建中强制排除的依赖项,在依赖预构建时,Vite 将有许多内部模块的 ESModule 依赖关系转换为单个模块:

// vite.config.js
export default {
  optimizeDeps: {
    exclude: ['lodash-es'] // 不依赖预构建的包
  }
}

或者

// vite.config.js
// 编辑器会根据 defineConfig 给出配置的 key 提示
import { defineConfig } from 'vite'
export default defineConfig({
  optimizeDeps: {
    exclude: ['lodash-es'] // 不依赖预构建的包
  }
})

是否依赖预构建打包结果如下:

  • 依赖预构建(默认):
    在这里插入图片描述

  • 不依赖预构建:
    在这里插入图片描述

不同环境的 vite 配置

// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig(({command}) => {
  if(command === 'build') {
    return {
		// 生产环境配置
	}
  } else {
    return {
		// 开发环境配置
	}
  }
})

其中 command 有两个值,根据命令行执行的命令会赋予它不同的值,当 npm run dev 时候,command 值为 serve 表示开发环境,当 npm run build 时,command 值为 build 表示生产环境,Vite 会根据执行命令的不同通过 command 值的判断来选择不同的构建配置,形成打包成果物。

为了更好地扩展性写配置,进行一下变体:

// vite.config.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': () => {
    console.log('生产环境')
    return {...viteBaseConfig, ...viteProdConfig}
  },
  'serve': () => {
    console.log('开发环境')
    return {...viteBaseConfig, ...viteDevConfig}
  }
}

export default defineConfig(({command}) => {
  // command: build(生产环境), serve(开发环境)
  return envResolver[command]()
})

css配置

Vite 对 css 的处理

如果你用过 Webpack 应该知道,Webpack 默认是不处理 .css 文件的,如果需要处理样式文件需要使用插件配置,其配置原理和具体内容可以参考 webpack入门到实战(上) 。但是,Vite 天生就支持对 .css 文件的直接处理,不需要进行额外的配置,还是上面的例子,这里我们加入引入 CSS 文件的内容:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vite</title>
</head>
<body>
  <div class="app">Vite Demo</div>
  <script src="./main.js" type="module"></script>
</body>
</html>
// main.js
import './index.css'
/* index.css */
.app{
  background-color: purple;
  color: green;
}

看下页面元素内容:

在这里插入图片描述
在这里插入图片描述

发现网络请求中的 index.css 文件内容发生了变化,并且样式内容被插入到了 index.htmlhead 中,Vite 处理 .css 的过程如下:

  1. 读取到 main.js 中导入了 index.css
  2. 使用 fs 模块读取 index.css 文件内容
  3. 创建 <style> 标签并将读取到的内容copy进这个标签中
  4. 将这个 <style> 标签及其内容插入到 index.htmlhead
  5. 将该 index.css 文件中的内容直接替换为 js 脚本(方便热更新和CSS模块化),同时设置 content-type 为 js,让浏览器以 js 脚本的形式来执行这个 .css 后缀文件。

Vite 对 cssmodule 的处理和配置

当不同组件中使用了相同的类名,打包结果中会出现类名覆盖的问题,所以需要 cssmodule,Vite 对 css 模块化的处理是修改 .css 后缀名为 .module.css,内容不用变:

// main.js
import IndexCss from './index.module.css'
document.querySelector('.app').className = IndexCss.app

在这里插入图片描述

通过 vite.config.js 配置可以修改 Vite 对 cssmodule 的默认处理方式,不过一般都没什么需要配置的,这里只是作为一个了解:

// vite.config.js
import { defineConfig } from 'vite'

export default defineConfig({
  // 对css的行为进行配置
  css: {
    // 对css模块化的默认行为进行覆盖
    modules: {
      // localsConvention: 'camelCaseOnly', // 模块化后的css类名命名规则,驼峰还是中划线形式
      // scopeBehaviour: 'local', // 配置当前的模块化行为是模块化还是全局化(结果中有hash就是开启了模块化,可以保证样式不被覆盖)
      // generateScopedName: '[name]_[local]_[hash:5]', // 生成的类名的规则(也可以接收一个函数返回最终的名字)
      // hashPrefix: '', // hash是根据文件名类名等生成的,这个前缀可以使生成的hash更加复杂更加独特
      // globalModulePaths: [] // 代表不想要参加到css模块化的路径
    }
  }
})

Vite 对预处理器的配置

相信你一定用过 less,这里引入一个 .less 样式文件:

// main.js
import IndexCss from './index.module.css'
import IndexLess from './index.module.less'

const appEle = document.querySelector('.app')
appEle.className = IndexCss.app
appEle.className += ' ' + IndexLess.app
/* index.module.less */
.app{
  font-size: 50px / 2;
}
npm i less -D

在没有构建工具的情况下,如果想要单独编译 .less 文件为 .css 文件,在安装了 less 以后就可以直接在命令行执行命令 npx lessc index.less test.css,less 编译器 lessc 会将 index.less 编译为 test.css,当我们引入了 .module.less 文件并安装 npm i less -D,Vite 就可以编译 .less 文件了。

跟 Webpack 类似,在执行命令行时也可以加入一些 Less.js Options 即编译参数,来告诉 less 编译器应该以什么方式来编译,最终结果应该呈现什么样,那么如何在构建工具 Vite 中配置 Less.js Options 呢?

// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
  css: {
    // 对css的行为进行配置
    modules: {
      ...
    },
    preprocessorOptions: {
      less: {
        math: 'always', // 始终编译数学表达式
        // 定义全局变量
        globalVars: { 
          fontSize: '24px' // .less中直接使用 @fontSize 变量
        }
      }
    }
  }
})

devSourcemap

sourceMap 代表文件之间的索引,上线后的代码是被编译压缩后的,当程序出错时,很难给出正确的错误提示位置信息。如果设置了 sourceMap 会索引源代码的错误位置。

// vite.config.js
import { defineConfig } from 'vite'
export default defineConfig({
  css: {
    modules: {
      ...
    },
    preprocessorOptions: {
      ...
    },
    devSourcemap: true // 是否开启 css 的 sourcemap
  }
})
  • devSourcemapfalse 的结果:
    在这里插入图片描述
  • devSourcemaptrue 的结果:
    在这里插入图片描述

Vite 对 postcss 的支持

postcss 到底是干什么的呢?这里做个简单的介绍,更多详细说明和配置可以去 postcss 官方文档 查阅。

  1. 对未来 css 新属性的降级兼容问题(类似 babel 对 js 语法的兼容处理)
  2. 不同浏览器的 css 属性前缀补全功能(--webkit----ms-- 等)

所以,postcss 并不是和 less、sass 同级的东西,它主要用来处理 less 和 sass 编译后的结果(css 内容),给编译结果增加语法降级和前缀补全功能,所以业内也称其为“后处理器”

Vite 天生对 postcss 有良好的支持:

npm i postcss-preset-env -D # postcss的预设plugin, 会帮我们安装postcss一些基本插件
// vite.config.js
import { defineConfig } from 'vite'
const PostcssPresetEnv = require('postcss-preset-env')
export default defineConfig({
  css: {
    ...
    devSourcemap: true,
    postcss: {
      plugins: [PostcssPresetEnv()], // 例如:width: clamp(100px, 30%, 300px); 会语法降级转化为 width: max(100px, min(30%, 300px));
    }
  }
})

ps:除了在 vite.config.js 中添加 postcss 字面量配置以外,也可以单独创建一个 postcss.config.js 配置文件,导出配置内容也一样生效。字面量的优先级高于配置文件的内容。

Vite 静态资源别名设置

对于前端来说,静态资源可能可能指的是字体、图片这些资源;但是,对于服务端而言,除了 API 对数据库的操作,其他内容几乎都可以算是静态资源,例如 .html.js 文件等等,浏览器加载这些 img 文件、.js 文件都是有网络请求的。

例如:当浏览器访问 index.html,后端在接收到这个请求时,对请求 url 进行分析判断(也就是后端路由),会去找到指定的静态 HTML 文件资源返回给浏览器,浏览器接收到返回的 HTML 文件发现是 text/html 类型,就会以页面的形式展示给用户。

vite.config.js 中对 alias 进行了别名配置,就允许开发者以下面的路径访问文件:

// main.js
// 其中 assets 文件中在 src 文件夹下,用来存放前端静态资源
import IndexCss from './index.module.css'
import IndexLess from './index.module.less'
import Img from '@/assets/quan.jpg'

const appEle = document.querySelector('.app')
appEle.className = IndexCss.app
appEle.className += ' ' + IndexLess.app

const imgEle = document.createElement('img')
imgEle.src = Img
document.body.appendChild(imgEle)

import { defineConfig } from 'vite'
import path from 'path'
export default defineConfig({
  resolve: {
    alias: {
      "@": path.resolve(__dirname, './src')
    }
  }
}

alias 别名配置的原理是什么呢?

答:在导入 quan.jpg 这个图片资源时,对于后端来说就是要去请求和加载这个静态资源文件,所以 Vite 服务器在后端路由中,先将请求的路径结合 vite.config.js 配置,将请求路径进行字符串替换,也就是将代码中请求路径中的 @ 替换成 path.resolve 方法生成后的绝对路径,通过这个绝对路径找到对应的资源再将结果返回到浏览器。

Vite 生产环境配置

尽管原生 ES Module 现在(2022年11月7日)得到了广泛支持,但由于嵌套导入会导致额外的网络往返,在生产环境中发布未打包的 ES Module 仍然效率低下,另外为了在生产环境中获得最佳的加载性能,例如 tree-shaking、懒加载、chunk 代码分割、CSS处理、不同浏览器语法兼容等,Vite 附带了一套 构建优化 的 构建命令,同样的,开箱即用,通过 build.rollupOptions 直接调整底层的 Rollup 选项,如果不额外配置打包参数,就是默认参数。

npm run build

默认执行打包结果:

在这里插入图片描述

因为浏览器在下一次访问资源时,如果发现文件名称有跟上一次一样的,就会使用上一次缓存的文件,所以当我们更改了项目内容打包后如果文件名不变,上线后很可能是看不到内容更新的,因为文件名跟上次浏览器使用了缓存的文件。也是因为这个原因,所以当打包结果文件名会加上 hash 值,项目内容有任何变化重新打包后的文件名的 hash 值都会不一样(例如:图片文件没改变,改动了 css 或者 js 内容,那么重新打包后图片资源不变,浏览器可以从缓存中取,节省了网络请求,而css 或 js 内容因为打包后文件名变了,浏览器会重新拉去最新的文件),利用好 hash 算法,可以更好的去控制浏览器缓存机制

实际项目中,打包的结果最终是要放在服务器上运行的,所以这里使用 VS Code 的插件 Live Server为什么以及如何使用这个插件)运行打包后的 index.html 文件,就是打包后的效果了。

注:Live Server 是基于当前工程目录开启服务的,所以在模拟线上打包结果运行效果时,需要重新开启一个 VS Code 用来打开打包后的结果,也就是 dist 目录(线上环境最终也是将成果物 dist 直接放在服务器),然后再通过插件运行 index.html 文件,呈现线上效果。

更多 Vite 配置

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/408793.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Vue入门必备知识篇05】--- Vue Router路由

前言❤️ 当落日余晖照在身上&#xff0c;没有污秽没有杂尘&#xff0c;只有光和希望 ❤️【Vue入门必备知识篇05】--- Vue Router路由一、前端路由的概念与原理&#xff08;1&#xff09;什么是路由&#xff08;2&#xff09;SPA 与前端路由&#xff08;3&#xff09;什么是前…

vue-router中的参数传递

文章目录前言一、本文章中练习需要的准备工作暴力引入bootstrap安装Vue Router二、项目基本架构1. 配置router文件2. 写入路由组件 一级路由3. 二级路由 实现传参3.1 使用params 传参3.1.1 在router文件下配置二级路由3.1.2 在view文件下新建二级路由组件3.1.3 在上一级路由组件…

uniapp**字符串转Json并提取字段值

uniapp字符串转Json并提取字段值 JSON有三种格式&#xff0c;每一种写法都和JS中的数据类型很像&#xff0c;可以很轻松的和JS中的数据类型互相转换 一、简单值的形式&#xff1a;JSON的简单值的格式对应着JS中的基础数据类型&#xff1a;数字 字符串 布尔值 注意事项&#…

这是我见过最牛逼的滑动加载前端框架

文章目录前言一、mescroll简介二、快速开始三、一分钟入门mescroll图片懒加载四、mescroll在vue中的使用五、小结前言 在手机端实现下拉刷新和下拉加载是最常见不过的需求了。今天大师兄就给大家分享一个非常精致的js框架&#xff1a;mescroll. 提示&#xff1a;以下是本篇文…

Cursor:GPT-4 驱动的强大代码编辑器

Cursor &#xff08;https://www.cursor.so/&#xff09;是 GPT-4 驱动的一款强大代码编辑器&#xff0c;可以辅助程序员进行日常的编码。下面通过一个实际的例子来展示 Cursor 如何帮助你编程。这个例子做的事情是网页抓取。抓取的目标是百度首页上的百度热搜&#xff0c;如下…

使用Python进行网站页面开发——HTML

目录 一、HTML基础语法 1.HTML是什么&#xff1f; 2.HTML基本结构 3.HTML注释 二、HTML常用标签介绍 1.文本标签 2.格式化标签 3.图片标签 4.超级链接标签 5.表格标签&#xff08;用来显示数据&#xff09; 6.表单标签&#xff08;用来接收数据&#xff09; 7.行内…

ACM模式下JavaScript(js)的输入输出 V8 Node

OJ在线编程常见输入输出练习场 ACM模式下分V8和node.js node.jsV8内置基本模块&#xff0c;相当于java中的JREJVMjava标准库 node就是带有能操作IO和网络库的V8引擎&#xff0c;提供了很多可调用的API使得JavaScript能够读写文件&#xff0c;网络请求&#xff0c;系统信息等…

【IIS搭建网站】本地电脑做服务器搭建web站点并公网访问「内网穿透」

文章目录1.前言2.Windows网页设置2.1 Windows IIS功能设置2.2 IIS网页访问测试3. Cpolar内网穿透3.1 下载安装Cpolar3.2 Cpolar云端设置3.3 Cpolar本地设置4.公网访问测试5.结语1.前言 在网上各种教程和介绍中&#xff0c;搭建网页都会借助各种软件的帮助&#xff0c;比如网页…

前端项目如何部署到服务器实现网址访问

目录 前言 需要用到的东西 购买云服务器和域名 绑定域名 使用Xshell连接云服务器 下载Nginx 安装nginx 配置nginx 启动nginx 传输文件 配置防火墙 卸载自带的防火墙 安装iptables防火墙 最后 前言 写了那么久的前端&#xff0c;就想着让朋友们欣赏欣赏&#xff0…

ElementUI快速上手(jar包本地下载)

Element-ui是饿了么前端团队推出的基于vue进行开发的前端框架。 最近刚学了Element-ui&#xff0c;迫不及待练练手&#xff0c;却发现现成的组件样式用不了。引用官网的使用方法&#xff0c;如图&#xff1a; 展示的效果也是不尽人意&#xff0c;在百度的过程中发现可能是链接…

相对定位relative、绝对定位absolute、固定定位fixed

注&#xff1a;默认情况下的定位是 postion&#xff1a;static&#xff1b; 使用定位时&#xff0c;常常使用偏移量对位置进行描述&#xff1a;left、right、top、bottom定位时&#xff0c;使用z-indent可以元素的堆叠顺序&#xff0c;例&#xff1a;z-indent&#xff1a;1&…

Spring Security 权限控制

日积月累&#xff0c;水滴石穿 &#x1f604; 前言 项目版本Boot2.3.12.RELEASESecurity5.3.9.RELEASE 官网文档 在前面的文章中&#xff0c;所有的接口只需要登录就能访问。并没有对每个接口进行权限限制。 在正式的系统中&#xff0c;一个用户会拥有一个或者多个角色&#…

三种架构模式——MVC、MVP、MVVM

目录 前言 一、MVC&#xff08;Model-View-Controller&#xff09; 1、简介 2、框架图 二、MVP&#xff08;Model-View-Presenter&#xff09; 1、简介 2、框架图 三、MVVM&#xff08;Model-View-ViewModel&#xff09; 1、简介 2、框架图 四、总结 前言 MV系列框…

微信小程序插件--wxml-to-canvas(生成图片)

一、需求 项目中要实现一个将图片分享到朋友圈的功能&#xff0c;将生成的海报转成图片保存到手机。用到了wxml-to-canvas插件。 二、官方示例使用方法 1.安装wxml-to-canvas npm install --save wxml-to-canvas2.JSON 组件声明 {"usingComponents": {"wxml-t…

多款顶级好用的 Vue 表单设计器测评推荐,可拖拽生成表单

本文完整版&#xff1a;《多款顶级好用的 Vue 表单设计器测评推荐&#xff0c;可拖拽生成表单》 Vue 表单设计器form-generator - 适配 Element Plus UI 框架的表单设计器form-render - 阿里团队开源表单设计器&#xff0c;自家 Antd UI 框架友好form-create - 支持Vue3 及 Ele…

内网npm私有仓库搭建以及使用教程

前言 前端团队沉淀一套通用的UI库、工具类、脚手架&#xff0c;不允许在公网发布&#xff0c;内网npm私有库搭建需求应运而生。如何在内网环境搭建npm私有仓库并使用&#xff1f;主角登场了 —— Verdaccio。接下来我来教大家使用 verdaccio 在内网环境中搭建npm私有仓库。 基…

canvas详细入门教程(1W字 吐血分享)

大家好&#xff0c;我是潘潘 今天为大家带来的是我已经写了很久了的canvas详细教程&#xff0c;对入门canvas很有帮助。 点击跳转原文&#xff1a; canvas详细教程原文 canvas是什么&#xff1f; 简单来说&#xff0c;<canvas> 是HTML5中的标签&#xff0c;它是一个容…

20分钟学会flex布局,熊二都表示学会了,你呢?

✏️ 作者&#xff1a;大二计算机专业学生 ♉ 星座&#xff1a;金牛座 &#x1f3e0; 主页&#xff1a;查看更多文章 &#x1f3c2; 关键&#xff1a;flex 前端布局 熊二都会 大家好&#xff0c;我是小周&#xff0c;今天分享的是熊二都能学会的前端 flex 布局&#xff0c;篇幅…

小程序 getActivePinia was called with no active Pinia. Did you forget to install pinia?

小程序项目使用pinia做状态管理报错&#xff1a; Error: [&#x1f34d;]: getActivePinia was called with no active Pinia. Did you forget to install pinia? const pinia createPinia() app.use(pinia) app运行打包时有个同样的错误 错误原因是&#xff1a;在外部js/t…

Collections类详解

目录 一.Collections概述&#xff1a; 1.1什么是Collections类&#xff1a; 1.2 Collections类和collection的区别和联系&#xff1a; 二. Collections类的主要方法&#xff1a; 一.Collections概述&#xff1a; 1.1 什么是Collections类&#xff1a; Java.util.Collections…