# vite

它主要由两部分组成:

  • 一个开发服务器,它基于原生ES模块提供了丰富的内建功能,HMR的速度非常快速;
  • 一套构建指令,它使用rollup打包代码,并且它是预配置的,可以输出生成环境的优化过的静态资源;

现代的浏览器是可以识别es module,在script标签上配置一下type即可。

如果我们不借助于其他工具,直接使用ES Module来开发有什么问题呢?

  • 首先,我们会发现在使用loadash时,加载了上百个模块的js代码,对于浏览器发送请求是巨大的消耗;
  • 其次,我们的代码中如果有TypeScript、less、vue等代码时,浏览器并不能直接识别;
npm install vite –g # 全局安装
npm install vite –D # 局部安装

通过vite来启动项目:

npx vite

# Vite对css的支持

  1. vite可以直接支持css的处理:直接导入css即可;
  2. vite可以直接支持css预处理器,比如less:
    • 直接导入less;
    • 之后安装less编译器;npm install less -D
  3. vite直接支持postcss的转换:只需要安装postcss,并且配置 postcss.config.js 的配置文件即可;npm install postcss postcss-preset-env -D
module.exports = {
  plugins: [
    require("postcss-preset-env")
  ]
}

# Vite对TypeScript的支持

vite对TypeScript是原生支持的,它会直接使用ESBuild来完成编译:只需要直接导入即可;

  1. 如果我们查看浏览器中的请求,会发现请求的依然是ts的代码:
    • 这是因为vite中的服务器Connect会对我们的请求进行转发;
    • 获取ts编译后的代码,给浏览器返回,浏览器可以直接进行解析;
  2. 注意:在vite2中,已经不再使用Koa了,而是使用Connect来搭建的服务器

# vite对vue提供第一优先级支持:

  • Vue 3 单文件组件支持:@vitejs/plugin-vue

  • Vue 3 JSX 支持:@vitejs/plugin-vue-jsx

  • Vue 2 支持:underfin/vite-plugin-vue2

  • 安装支持vue的插件:

cnpm install @vitejs/plugin-vue @vue/compiler-sfc -D

vite.config.js配置

const vue = require('@vitejs/plugin-vue')

module.exports = {
  plugins: [
    vue()
  ]
}

# vite打包

"scripts": {
    "serve": "vite",//本地服务
    "build": "vite build",//打包
    "preview": "vite preview"//打包预览
  },

vite基于ESBuild进行构建打包,速度非常快

为什么这么快 ?

  • js是单线程串行,esbuild是新开一个进程,然后多线程并行,充分发挥多核优势
  • esbuild是go开发的,go是纯机器码,肯定要比JIT快
  • 不使用 AST,优化了构建流程。

# vite脚手架

npm init @vitejs/app

<===>

npm install @vitejs/create-app -g
create-app

# vite预构建

  1. 不同的第三方包会有不同的导出格式,vite会通过esbuild处理转换
  2. 对路径的处理可以直接使用.vite/deps,方便路径重写
  3. 网络多包传输的性能问题(也是原生esmodule规范不敢支持node_modules的原因之一),有了依赖预构建以后无论有多少额外的export和import,vite都尽可能讲它们集成最后只生成一个或者几个模块
// a
export default function a(){}
// main.js
export {default as a} from './a.js'
//实际先import后导出
// vite发现main.js中用到了a,直接处理成function a,减少了import数量
function a(){}

# 初步搭建vite


// 这是增加vite代码提示的一种方案,vite非全局安装时生效
// /**
//  * @type {import('vite').UserConfig}
//  */
// const config = {
//     optimizeDeps:{
//         exclude:['lodash-es']
//     }
//   }
  
// export default config

// 这是增加vite代码提示的另外一种方案,vite非全局安装时生效
import {defineConfig} from 'vite'
import viteBaseConfig from './vite.base.config'
import viteDevConfig from './vite.dev.config'
import viteProdConfig from './vite.prod.config'

const envResolve = {
    'build':()=>{
        console.log('build')
        return {
            ...viteBaseConfig,
            ...viteProdConfig
        }
},
    'serve':()=>{
        console.log('dev')
        return Object.assign({},viteBaseConfig,viteDevConfig)
    }
}


export default defineConfig(({command})=>{
    console.log('command',command)
    return envResolve[command]()
})

// 参数不解构之前的数据
// {
//     mode: 'development',
//     command: 'serve',
//     isSsrBuild: false,
//     isPreview: false
//   }

# vite环境变量设置

Vite 使用了 dotenv 这个第三方的库来处理环境变量。

具体来说,dotenv 会自动读取 .env 这个文件,并解析这个文件中对应的环境变量,但 Vite 考虑到和其他配置的冲突问题,它不会直接将这些环境变量注入到 process 对象下。vite提供了loadEnv来手动确认env文件。

loadEnv(mode, root, prefix)
// process.cwd():用于返回 Node.js 进程当前工作目录的路径
const env = loadEnv(mode,process.cwd(),'SBXG_')

如果设置了前缀,那么符合的前缀会被添加loadEnv返回值中,不符合的被过滤掉

.env文件

SBXG_API_URL=https://api.example.com  
SBXG_APP_TITLE=My Superb App  
SBXG1_DEBUG=true #会被过滤掉

# vite客户端配置环境变量

使用import.meta.env去获取

为了安全,除了基本变量外,默认打印的是VITE_为前缀的变量,如果要修改,借助配置文件中envPrefix去设置

{
	SBXG_API_URL: 'https://api.example.com', 
	SBXG_APP_TITLE: 'My Superb App', 
	BASE_URL: '/', 
	MODE: 'development',
	DEV: true,}
import {defineConfig} from 'vite'

export default defineConfig({
    optimizeDeps:{
        
    },
    envPrefix:'SBXG_'//下划线非必须
})

# vite处理css

// /**
//  * @type {import('vite').UserConfig}
//  */
// const config = {
//     optimizeDeps:{
//         exclude:['lodash-es']
//     }
//   }
  
// export default config


import {defineConfig} from 'vite'
import postcssPresetEnv from 'postcss-preset-env'

export default defineConfig({
    optimizeDeps:{
        
    },
    css:{
        modules:{
            localsConvention:"camelCase",
            scopeBehaviour:"local",//如果设置成全局则都不按模块化解析
            generateScopedName:'[name]_[local]',// 生成的类名,可在这里配置
            // generateScopedName:(name,filename,css)=>{
            //     console.warn(`name`,name)
            //     console.warn(`filename`,filename)
            //     console.warn(`css`,css)
            //     return `sbxg_${name}`
            //     return 'sbxg_'
            // },
            hashPrefix:"hhhhh",
            globalModulePaths:['./c3.module.css']//排除c3模块,不按照模块化解析,仍按普通css解析
        },
        preprocessorOptions:{
            less:{
                math:"always",//处理某些计算处理
                globalVars:{
                    mainColor:"red"//设置全局变量不需要再依次引入
                }
            }
        },
        devSourcemap:true//开启css sourcemap,
        postcss:{ //也可以单独拎出去处理postcss.config.js,会自动读取这个文件
            plugins:[postcssPresetEnv] 
        }
    }
})

# vite配置resolve 别名

import {defineConfig} from 'vite'
import path from 'path'

export default defineConfig({
    resolve:{
        alias:{
            "@":path.resolve(__dirname,"./src"),
            "@assets":path.resolve(__dirname,"./src/assets"),
        }
    }
})

vite会帮助获取图片的路径,对json文件也会 直接转成对象 而不需要手动反序列化

import styleImg from '@assets/demo.png' //返回路径
// import styleImg from './src/assets/demo.png?raw' //返回buffer
import myJson,{name} from '@/json/demo.json' // json已经转成对象,还可以解构,方便tree-shaking
console.log(styleImg)
console.log(myJson)
console.log(typeof myJson)
console.log(name)

# vite生产环境使用

import {defineConfig} from 'vite'
export default defineConfig({
    build:{// 构建生产包时的一些配置策略
        rollupOptions:{// 配置rollup的一些基本构建策略
            output:{// 控制输出
                // 在rollup里,hash代表文件名和文件内容组合计算结果
                // 输出的是静态资源,所以打包出来的js不收约束
                assetFileNames:"[hash].[name].[ext]"
            }
        },
        // 配置静态资源是否行内的大小,默认小于4kb转base64
        assetsInlineLimit:4096,
        outDir:"myDist",//打包文件夹,默认dist
        assetsDir:"pubilc",//静态资源目录,默认assets
        emptyOutDir:true// 清空上一次打包的文件,默认true
    }
})
最后更新: 5/15/2024, 8:55:46 PM