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 扩展名)。

/**vite.config.js或vite.config.ts**/
//最基础的配置
export default {
  // 配置选项
}
/**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定义全局常量替换方式,其中每项在开发环境下会被定义在全局,而在构建时被静态替换
    //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: [
	  ]
	}
})

你可能感兴趣的:(学习,前端,vite)