vite 构建工具介绍

本文最后更新于1 分钟前,文中所描述的信息可能已发生改变。

vite是什么

vite 是一个现代化的轻量级的前端构建工具,它具有以下特点:

  1. 轻量级:vite 使用 Rollup 进行打包,因此打包速度非常快,并且支持 ES Module,使得开发体验非常友好。
  2. 零配置:vite 默认支持 Vue、React、Svelte 等框架,并且支持 TypeScript、PostCSS 等工具,因此配置非常简单。
  3. 极速热更新:vite 使用 HMR(Hot Module Replacement)技术,使得开发时修改代码后,浏览器会自动更新,无需刷新页面。
  4. 插件支持:vite 支持使用各种插件,包括 CSS 预处理器、代码检查工具、测试工具等,使得开发体验更加丰富。
  5. 跨平台:vite 支持多种平台,包括 Node.js、浏览器、桌面应用等,使得开发体验更加丰富。
  6. 极速开发:vite 使用 VitePress 构建文档,使得开发文档非常简单,并且支持 Markdown 格式,使得文档编写更加方便。
  7. 社区活跃:vite 有着活跃的社区,社区中有很多开发者和开源爱好者一起讨论和分享经验,使得开发更加高效。
  8. 社区驱动:vite 是由 Vue 团队推出的,因此社区中很多开发者都关注 Vue,使得开发更加高效。

vite和vite脚手架的区别

当想要创建一个初始化的项目时,会使用命令npm create vite 这个命令。 命令的本质是下载并安装了一个脚手架工具,create-vitecreate-vite 是一个脚手架工具,它提供了一系列的模板,用户可以根据自己的需求选择合适的模板来创建项目。

通过运行create-vite bin下的脚本,可以创建一个初始化的项目。

create-vite会内置一个包含vite的预设模板,不需要自己再配置post-css、vue、less、babel等工具。

vite为什么快?

vite之所以快,主要原因有以下几点:

  1. 使用Rollup进行打包,Rollup具有更快的打包速度,并且支持ES Module,使得开发体验非常友好。
  2. vite使用HMR(Hot Module Replacement)技术,使得开发时修改代码后,浏览器会自动更新,无需刷新页面。
  3. 对路径的处理上,vite直接使用.vite/deps缓存文件,而不是使用node_modules中的文件,因此打包速度非常快。
  4. 同时也解决了网络传输的问题,因为vite将所有的文件都打包成一个文件,所以网络传输速度非常快。

在vite中如何根据环境动态读取不同配置(区分开发和生产环境)

在vite中,可以通过环境变量来配置不同的配置文件。 在vite.config.js中,通过读取defineConfig函数,传入一个函数,这个函数会接收到command和mode两个参数。

通过command区分开发环境和生产环境。

配置如下:

js
import { defineConfig, loadEnv } from "vite";
import devConfig from "./vite.dev.config.js"
import prodConfig from "./vite.prod.config.js"
import baseConfig from "./vite.base.config.js"


const resolveConfig = {
  "build": () => Object.assign({}, baseConfig, prodConfig),
  "serve": () => return Object.assign({}, baseConfig, devConfig)
}

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

在vite.config.js中动态加载环境变量(区分开发环境和生产环境)

vite中内置了dotenv插件,可以读取.env文件,根据环境变量的不同,加载不同的配置。 根据这一特性,可以在开发环境、测试环境和生产环境中分别配置不同的环境变量,从而实现环境变量的动态加载。 在vite中,可以通过环境变量来配置不同的配置文件。

通过在项目中创建不同的env文件,来配置不同的环境变量配置。 通常的配置文件有.env.development、.env.test、.env.production

使用loadEnv(mode, envDir, prefixes)方法来从不同的环境中加载不同的配置。

在node中,环境变量会被挂载到process。我们可以通过process来获取当前环境下的环境变量。 为了区分不同的环境,vite中内置了一个defineConfig函数,可以传入一个函数,这个函数会接收到command和mode两个参数。 command和mode分别代表当前命令和当前模式。

command和mode的取值如下:

  • command:当前命令,取值为build或者serve。
  • mode:当前模式,取值为development或者production。
js
import { defineConfig } from "vite";

export default defineConfig(({ command, mode } ) => {
  const env = loadEnv(mode, process.cwd(), '')
  console.log(env)
  return {
  }
})

通过这里的process.env.NODE_ENV来判断当前环境,然后加载不同的配置文件。

如何在客户端的代码中读取环境变量

在客户端的代码中读取环境变量,可以通过import.meta.env来获取。 例如:

js
console.log(import.meta.env)

这样获取的环境变量列表vite会进行一层过滤,只有当前环境变量以VITE_开头时,才会被保留。

这个前缀可以在vite.config.js中修改。

js
import { defineConfig } from "vite";
export default defineConfig({
  envPrefix: 'TEST_',
})

vite中对路径的处理

在vite中,路径处理通过path模块来实现。

js
console.log(path.resolve(__dirname, "./test.css"))

__dirname 是一个全局变量,表示当前文件所在的目录。 path.resolve() 方法用于将一个或多个路径解析为绝对路径。 使用path.resolve() 在服务端获取某个文件的绝对路径。

vite中常见配置说明

vite中对css.modules的配置说明(配置对css.modules的处理)

官方引用的配置说明 地址: vite官方配置说明-css_modules引用

vite默认是支持直接引入css文件的,也就是支持对css文件的处理,它会将css文件内容打包成一个js文件执行,但是默认是不支持对css文件的预处理语言的,比如sass,less等。

为了对不同的css模块作区分,vite引入了CSS Module模块,通过CSS Module,我们可以将css模块化,将css模块化后,我们可以通过import引入css模块,然后通过className的形式来使用css模块中的类名,这样就可以避免类名冲突的问题。

js
import { defineConfig } from "vite";
export default defineConfig({
  envPrefix: 'TEST_',
  css: {
    modules: {
      localsConvention: 'camelCase',    //css module 样式名命名规则
      scopeBehavior: 'local',       //css module 作用域,是本地还是全局,设置local的话,生成的css名称后会添加一段hash值,用来防止css冲突,blobal时,不会添加hash值
      generateScopedName: (name, filename, cssModule) => {  // 根据规则生成css module 的类名
        const fileName = filename.split('/').pop().split('.')[0];
        return `${fileName}_${name}`;
      },
      hashPrefix: "prefix", // 生成hash前缀
    },
  },
})

vite中对css.preProcessorOptions的配置说明

该配置用来指定传递给css预处理器的选项。 每个预处理器支持的选项可以在它们各自的文档中找到:

vite中对css.preProcessorOptions的配置说明如下:

js
css: {
  preProcessorOptions: {
    less: {
      math: "always",    // 启用数学运算,将不显示数学公式
      globalVars: {     // 定义全局变量
        color: "red"
      }
    },
    sass: {
    },
    scss: {
    },
    styl: {
      define: {
      }
    }
  }
}

vite配置中css.devSourcemap的说明

在Vite配置中,css.devSourcemap选项用于控制是否在开发过程中启用sourcemap。

什么是sourcemap?

在开发过程中,sourcemap可以提供对源代码的映射,方便调试。

js
css: {
  devSourcemap: true
}

vite配置中css.postcss的说明

在Vite配置中,css.postcss选项用于配置PostCSS。

PostCSS是一个工具集,用于转换CSS,不同于less和sass,它可以加载一系列的插件,实现对CSS的预处理和后处理。Vite配置中css.postcss选项可以配置PostCSS的插件,例如autoprefixer、postcss-nested等。

postcss-preset-env 官方地址: postcss-preset-env PostCSS Preset Env 可将现代 CSS 转换为大多数浏览器都能理解的 CSS,并根据目标浏览器或运行环境确定所需的多重填充。

js
css: {
  postcss: {
    plugins: [
      postcssPresetEnv({
      }),
    ]
  }
}

vite配置中对静态资源路径的配置

在Vite中,静态资源路径的配置可以通过vite.config.js中的resolve.alias选项来实现。

通过配置resolve.alias选项,你可以为静态资源路径进行别名映射。

例如,你可以将@映射到src目录,这样你就可以在项目中使用@/来引用src目录下的文件。

配置如下:

js
import { defineConfig } from 'vite'

export default defineConfig({
  resolve: {
    alias: {
      '@': '/src'
    }
  }
}

vite配置打包后的文件命名规则

在Vite中,你可以通过配置build.rollupOptions.output.assetFileNamesbuild.rollupOptions.output.chunkFileNames来配置打包后的文件命名规则。

  1. assetFileNames: 用于配置打包后的静态资源的命名规则。默认情况下,静态资源文件名会保留原始名称,除非它们被引用为模块,在这种情况下,它们会被重命名以避免冲突。

  2. chunkFileNames: 用于配置打包后的JavaScript文件的命名规则。默认情况下,JavaScript文件名会保留原始名称,除非它们被引用为模块,在这种情况下,它们会被重命名以避免冲突。

  3. manualChunks: 用于将一些模块单独打包成一个单独的chunk。这个配置项接收一个函数,该函数接收一个模块的id作为参数,并返回一个字符串作为chunk的名称。

javascript
export default {
  build: {
    rollupOptions: {
      output: {
        assetFileNames: '[name].[hash].[ext]',  // 自定义静态资源文件名
        chunkFileNames: '[name].[hash].js',   // 自定义js文件名
        entryFileNames: '[name].[hash].js',   // 自定义入口文件名
        manualChunks: (id) => {        // 自定义拆分文件
        },
      }
    },
    assetsInlineLimit: 4096,  // 表示打包时,小于4kb以下的静态资源会被内联到代码中,图片->base64
  }
}

vite配置打包后的文件夹名称

在Vite中,你可以通过配置build.outDir来设置打包后的文件夹名称, 配置build.assetsDir来设置静态资源的目录名称。

js
export default {
  build: {
    outDir: 'output',       // 输出目录
    assetsDir: 'assetsOutput',  // 静态资源目录
  }
}

vite配置rollup将node_modules中的依赖单独打包仅vendor

在Vite中,你可以通过配置rollupOptions来设置rollup的配置,通过output.manualChunks来将node_modules中的依赖单独打包。

js
export default {
  build: {
    rollupOptions: {
      output: {
        manualChunks: (id)=>{
          if (id.includes('node_modules')){
            return "vendor";
          }
        }
      }
    }
  }
}

vite的插件系统

在Vite中,插件系统是Vite的基础。Vite的插件系统是Vite的扩展点,可以通过插件来扩展Vite的功能。

在vite生命周期的不同阶段,可以通过插件来执行不同的操作。

vite的所有插件列表

官方插件列表 | 社区插件列表

如何自定义vite插件

vite插件的创建非常简单,只需要创建一个对象,并实现一些钩子函数即可。

约定

如果插件不使用Vite特有的钩子,可以作为兼容Rollup的插件来实现,推荐使用Rollup插件名称约定。

Rollup插件应该有一个带rollup-plugin-前缀、语义清晰的名称。在package.json中包含rollup-pluginvite-plugin关键字。这样,插件也可以用于纯Rollup或基于WMR的项目。

对于Vite专属的插件:

Vite插件应该有一个带vite-plugin-前缀、语义清晰的名称。

package.json中包含vite-plugin关键字。 在插件文档增加一部分关于为什么本插件是一个Vite专属插件的详细说明(如,本插件使用了Vite特有的插件钩子)。 如果你的插件只适用于特定的框架,它的名字应该遵循以下前缀格式:

vite-plugin-vue-前缀作为Vue插件 vite-plugin-react-前缀作为React插件 vite-plugin-svelte-前缀作为Svelte插件

vite插件实际上会返回一个函数,该函数接收一个ViteConfig对象作为参数,并返回一个ViteConfig对象。

js
export default function (options: Options): PluginOption {
  return {
    name: 'vite-aliases',
    config(config, env) {
      const alias = createAlias(options)
      return {
        alias,
      }
    },
    configureServer(server) {
      server.middlewares.use(async (req, res, next) => {
        //...
      })
    },
    transformIndexHTML(html) {
      // 转换 index.html 的专用钩子。钩子接收当前的 HTML 字符串和转换上下文。上下文在开发期间暴露ViteDevServer实例,在构建期间暴露 Rollup 输出的包。
      return html.replace(/<!--\s*alias\s*-->/g, `<script>window.__alias__ = ${JSON.stringify(createAlias(options))}</script>`)
    },
    configResolved(options) {
      // 在解析 Vite 配置后调用。使用这个钩子读取和存储最终解析的配置。当插件需要根据运行的命令做一些不同的事情时,它也很有用。
    },
    configPreviousResolve(options) {
      // 与configureServer 相同,但用于预览服务器。
      // configurePreviewServer 这个钩子与 configureServer 类似,也是在其他中间件安装前被调用。如果你想要在其他中间件 之后 安装一个插件,你可以从 configurePreviewServer 返回一个函数,它将会在内部中间件被安装之后再调用:
    }
  }
}

config方法是Vite插件中的钩子,它会在Vite配置被合并时被调用。 config参数传入当前的配置内容。 env参数是一个对象,包含Vite的运行环境信息,包括commandmode

1.[插件]vite-aliases

链接

说明: vite-aliases是一个插件,用于为vite配置别名,它将别名映射到文件路径,以便在导入时使用。

配置示例:

js
import { defineConfig } from 'vite'
import viteAliases from 'vite-aliases'
export default defineConfig({
  plugins: [
    viteAliases()
  ]
}

比如项目目录的结构如下:

src
  assets
  components
  pages
  store
  utils

最终自动生成的别名如下:

json
[
  {
    find: '@',
    replacement: '${your_project_path}/src'
  },
  {
    find: '@assets',
    replacement: '${your_project_path}/src/assets'
  },
  {
    find: '@components',
    replacement: '${your_project_path}/src/components'
  },
  {
    find: '@pages',
    replacement: '${your_project_path}/src/pages'
  },
  {
    find: '@store',
    replacement: '${your_project_path}/src/store'
  },
  {
    find: '@utils',
    replacement: '${your_project_path}/src/utils'
  },
]

2.[插件]vite-plugin-checker

nvm(node版本控制)
使用vite初始化vue3项目,并添加iconify库