Vite学习笔记

前言:

在浏览器支持 ES 模块之前,JavaScript 并没有提供原生机制让开发者以模块化的方式进行开发。这也正是我们对 "打包" 这个概念熟悉的原因:使用工具抓取、处理并将我们的源码模块串联成可以在浏览器中运行的文件。

打包构建工具演变:

webpack、Rollup 和 Parcel 等,然后到vite,它们极大地改善了前端开发者的开发体验。

需求衍生:

由于JavaScript 代码量也呈指数级增长,包含数千个模块的大型项目相当普遍。

启动开发服务器通常需要很长时间,有时候长达6/7分钟之久,即使使用模块热替换(HMR),文件修改后的效果也需要几秒钟才能在浏览器中刷新出来,极大影响开发体验,需要升级工具。

选择vite理由:

  1. 原生 ESM 开发服务器,Vite 还通过原生 ESM 导入提供了许多主要用于打包场景的增强功能。
  2. Vite 通过在一开始将应用中的模块区分为 依赖源码 两类,改进了开发服务器启动时间,Vite 将会使用 esbuild 预构建依赖。esbuild 使用 Go 编写,并且比以 JavaScript (node.js)编写的打包器(webpack)预构建依赖快 10-100 倍。
  3. Vite 以 原生 ESM 方式提供源码。这实际上是让浏览器接管了打包程序的部分工作:Vite 只需要在浏览器请求源码时进行转换并按需提供源码。根据情景动态导入代码,即只在当前屏幕上实际使用时才会被处理。
  4. Vite利用 HTTP 头让浏览器进行文件请求时,启用协商缓存来缓存源码模块,而依赖模块请求则进行强缓存,因此一旦被缓存它们将不需要再次请求,大大提高加载速度。
  5. Vite 附带了一套构建优化的构建命令,开箱即用。
  6. 支持自定义后端集成。
  7. Vite 还提供了强大的扩展性,可通过其 插件 API 和 JavaScript API 进行扩展,并提供完整的类型支持。

配置 Vite:

当以命令行方式运行 vite 时,Vite 会自动解析项目根目录下名为 vite.config.js 的配置文件(也支持其他 JS 和 TS 扩展名)。

javascript 复制代码
/**vite.config.js或vite.config.ts**/
//最基础的配置
export default {
  // 配置选项
}
javascript 复制代码
/**vite.config.js或vite.config.ts**/
//配置智能提示
/** @type {import('vite').UserConfig} */
//defineConfig工具函数,这样不用jsdoc注解也可以获取类型提示
import { defineConfig } from 'vite'
export default defineConfig({
  // ...
})

/**
情景配置:
如果配置文件需要基于(dev/serve 或 build)命令或者不同的 模式 来决定选项,
亦或者是一个 SSR 构建(ssrBuild),则可以选择导出这样一个函数:
**/
export default defineConfig(({ command, mode, ssrBuild }) => {
  if (command === 'serve') {
    return {
      // dev 独有配置
    }
  } else {
    // command === 'build'
    return {
      // build 独有配置
    }
  }
})

/**
异步配置:
如果配置需要调用一个异步函数,也可以转而导出一个异步函数。
这个异步函数也可以通过 defineConfig 传递,以便获得更好的智能提示:
**/
export default defineConfig(async ({ command, mode }) => {
  const data = await asyncFunction()
  return {
    // vite 配置
  }
})

/**
在配置中使用环境变量:
环境变量通常可以从 process.env 获得。
注意 Vite 默认是不加载 .env 文件的,因为这些文件需要在执行完Vite配置后才能确定加载哪一个,
举个例子,root 和 envDir 选项会影响加载行为。
不过当你的确需要时,你可以使用 Vite 导出的 loadEnv 函数来加载指定的 .env 文件。
**/
import { defineConfig, loadEnv } from 'vite'

export default defineConfig(({ command, mode }) => {
  // 根据当前工作目录中的 `mode` 加载 .env 文件
  // 设置第三个参数为 '' 来加载所有环境变量,而不管是否有 `VITE_` 前缀。
  const env = loadEnv(mode, process.cwd(), '')
  return {
    // vite 配置
    define: {
      __APP_ENV__: JSON.stringify(env.APP_ENV),
    },
  }
})

//共享配置及常用配置,不需要的可以不添加属性,将启用默认配置:
import { defineConfig } from 'vite'
import { viteMockServe } from 'vite-plugin-mock'
const localEnabled = process.env.USE_MOCK || false;
const prodEnabled = process.env.USE_CHUNK_MOCK || false;
export default defineConfig(({ command, mode }) => {
  return {
    root: process.cwd(), //默认process.cwd()。tips:项目根目录(index.html 文件所在的位置)。可以是一个绝对路径,或者一个相对于该配置文件本身的相对路径。
    base: '/', //默认/。合法值:[1.绝对 URL 路径名,例如 /foo/,2.完整的 URL,例如 https://foo.com/,3.空字符串或 ./(用于嵌入形式的开发)]
    mode: '', //'development' 用于开发,'production' 用于构建
    define: 'XXX', //Record<string, any>定义全局常量替换方式,其中每项在开发环境下会被定义在全局,而在构建时被静态替换
    //plugins: 需要用到的插件数组。Falsy 虚值的插件将被忽略,插件数组将被扁平化(flatten)
    plugins: [ 
	    vue(), // vue原生插件
	    viteMockServe({  //引入mock插件配置,tips:mock,模拟真实数据以测试软件功能
		   mockPath: "./src/server/mock",  //mock配置数据文件路径
		   localEnabled: localEnabled, // 开发打包开关 true时打开mock  false关闭mock
		   prodEnabled: prodEnabled, //prodEnabled, // 生产打包开关
		   // 这样可以控制关闭mock的时候不让mock打包到最终代码内
		   injectCode: `
		    import { setupProdMockServer } from './mockProdServer';
		    setupProdMockServer();
		   `,
		   logger: false, // 是否在控制台显示请求日志
		   supportTs:false // 打开后,可以读取 ts 文件模块 打开后将无法监视 .js 文件
		 })
    ], 
    publicDir: 'public' //作为静态资源服务的文件夹,该值可以是文件系统的绝对路径,也可以是相对于项目根目录的相对路径,设定为 false 关闭此项功能
    cacheDir: "node_modules/.vite", //默认:node_modules/.vite,存储缓存文件的目录,此目录下会存储预打包的依赖项或 vite 生成的某些缓存文件。此选项的值可以是文件的绝对路径,也可以是以项目根目录为基准的相对路径。当没有检测到 package.json 时,则默认为 .vite。
    resolve: {
  		alias: [{ find: '@', replacement: resolve(__dirname, 'src') }],// 配置别名,
  		dedupe: '', // 如果你在你的应用程序中有相同依赖的副本(比如 monorepos),请使用此选项强制 Vite 始终将列出的依赖项解析为同一副本(从项目根目录)。
  		conditions: [], //情景导出 package.json 配置中的exports字段
  		mainFields: '', //默认['module', 'jsnext:main', 'jsnext'],如果一个入口点从 exports 成功解析,resolve.mainFields 将被忽略
  		browserField: ''//已废弃
  		extensions: [], //默认['.mjs', '.js', '.mts', '.ts', '.jsx', '.tsx', '.json'],导入时想要省略的扩展名列表。注意,不 建议忽略自定义导入类型的扩展名(例如:.vue),因为它会影响 IDE 和类型支持。
  		preserveSymlinks: false, //启用此选项会使 Vite 通过原始文件路径(即不跟随符号链接的路径)而不是真正的文件路径(即跟随符号链接后的路径)确定文件身份。
  	},
  	css: {
  		modules: '', // 配置 css modules 的行为
		preprocessorOptions:{
		  scss: {
		    additionalData:`$injectedColor:orange;` //指定传递给 css 预处理器的选项
		  },
		  less: {
	        math: 'parens-division',    //指定传递给 less 预处理器的选项
	      },
	      styl: {    //指定传递给 styl/stylus 预处理器的选项
	        define: {
	          $specialColor: new stylus.nodes.RGBA(51, 197, 255, 1),
	        },
	      },
	},
	json: {
	  namedExports: true,//是否支持从 .json 文件中进行按名导入
	  stringify: false, //若设置为 true 导入的json会被转为 export default JSON.parse("..") 会比转译成对象字面量性能更好	  
	},
	//继承自 esbuild 转换选项,最常见的用例是自定义 JSX
	esbuild: {
	  jsxFactory: "h",
	  jsxFragment: "Fragment",
	  jsxInject:`import Vue from 'vue'`
	},
	assetsInclude: ['**/*.gltf'], //静态资源处理
	logLevel: 'info', //选项:'info' | 'warn' | 'error' | 'silent',调整控制台输出的级别,默认为 'info'
	/**
	自定义 logger 记录消息:
	import { createLogger, defineConfig } from 'vite'
	const logger = createLogger()
	const loggerWarn = logger.warn
	logger.warn = (msg, options) => {
	  // 忽略空 CSS 文件的警告
	  if (msg.includes('vite:css') && msg.includes(' is empty')) return
	  loggerWarn(msg, options)
	}
    **/
	customLogger:logger,//自定义 logger 记录消息
	clearScreen: true, //设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息。
	envDir: 'root'//默认root, //用于加载 .env 文件的目录。可以是一个绝对路径,也可以是相对于项目根的路径。
	envPrefix: 'VITE_',//默认VITE_,以 envPrefix 开头的环境变量会通过 import.meta.env 暴露在你的客户端源码中
	appType: 'spa',//默认spa,选项['spa' | 'mpa' | 'custom'], tips: SPA-单页应用, MPA-多页应用,custom- SSR和自定义HTML处理的框架
	//server:本地运行配置,以及反向代理配置
	server: {
		  host: "localhost",
		  https: false,//是否启用 http 2
		  cors: true,//为开发服务器配置 CORS , 默认启用并允许任何源
		  open: true,//服务启动时自动在浏览器中打开应用
		  port: "9000",
		  strictPort: false, //设为true时端口被占用则直接退出,不会尝试下一个可用端口
		  force: true,//是否强制依赖预构建
		  hmr: false,//禁用或配置 HMR 连接
		  // 传递给 chockidar 的文件系统监视器选项
		  watch: {
		   ignored:["!**/node_modules/your-package-name/**"]
		  },
		  // 反向代理配置
		  proxy: { 
		   '/api': {
		    target: "https://xxxx.com/",
		    changeOrigin: true,
		    rewrite: (path) => path.replace(/^\/api/, '')
		   }
		  }
	},
	//打包配置
	build: {
		  target: "modules", //浏览器兼容性  "esnext"|"modules"
		  outDir: "dist", // 指定输出路径
		  assetsDir: "assets", // 生成静态资源的存放路径
		  assetsInlineLimit: 4096, // 小于此阈值的导入或引用资源将内联为 base64 编码,以避免额外的 http 请求。设置为 0 可以完全禁用此项
		  cssCodeSplit: true, // 启用/禁用 CSS 代码拆分
		  sourcemap: false, // 构建后是否生成 source map 文件
		  rollupOptions: {}, // 自定义底层的 Rollup 打包配置
		  commonjsOptions: {}, // @rollup/plugin-commonjs 插件的选项
		  lib: {}, //构建的库
		  manifest: false, // 当设置为 true,构建后将会生成 manifest.json 文件,设置为 false 可以禁用最小化混淆,,或是用来指定使用哪种混淆器
		  minify: "terser", // boolean | 'terser' | 'esbuild',terser 构建后文件体积更小
		  terserOptions: {},  // 传递给 Terser 的更多 minify 选项。
		  write: true,  // 设置为 false 来禁用将构建后的文件写入磁盘
		  emptyOutDir: true,  // 默认情况下,若 outDir 在 root 目录下,则 Vite 会在构建时清空该目录。
		  brotliSize: true, // 启用/禁用 brotli 压缩大小报告
		  chunkSizeWarningLimit: 500 // chunk 大小警告的限制
	ssr: {
	  // 列出的是要为 SSR 强制外部化的依赖,类型:string[]
	  external: [], 
	  // 列出的是防止被 SSR 外部化依赖项。类型:string | RegExp | (string | RegExp)[] | true
	  noExternal: [
	  ]
	}
})
相关推荐
我要洋人死9 分钟前
导航栏及下拉菜单的实现
前端·css·css3
科技探秘人20 分钟前
Chrome与火狐哪个浏览器的隐私追踪功能更好
前端·chrome
科技探秘人21 分钟前
Chrome与傲游浏览器性能与功能的深度对比
前端·chrome
JerryXZR26 分钟前
前端开发中ES6的技术细节二
前端·javascript·es6
七星静香28 分钟前
laravel chunkById 分块查询 使用时的问题
java·前端·laravel
q24985969331 分钟前
前端预览word、excel、ppt
前端·word·excel
数据与后端架构提升之路33 分钟前
从神经元到神经网络:深度学习的进化之旅
人工智能·神经网络·学习
小华同学ai36 分钟前
wflow-web:开源啦 ,高仿钉钉、飞书、企业微信的审批流程设计器,轻松打造属于你的工作流设计器
前端·钉钉·飞书
一行143 分钟前
电脑蓝屏debug学习
学习·电脑
Gavin_9151 小时前
【JavaScript】模块化开发
前端·javascript·vue.js