Vite快速入门教程

2022-06-02 15:30:36
2024-05-19 05:39:53

完整配置(vite.config.js)

import { ConfigEnv, loadEnv, UserConfig } from "vite";
import { resolve } from "path";
import vue from "@vitejs/plugin-vue";
// import vitePluginAliOss from 'vite-plugin-ali-oss';

//自动导入组件
import Components from "unplugin-vue-components/vite";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import AutoImport from "unplugin-auto-import/vite";
//按需引入ElementPlus组件
import { createStyleImportPlugin, ElementPlusResolve } from "vite-plugin-style-import";

//提供压缩和基于 ejs 模板功能的 vite 插件
import { createHtmlPlugin } from "vite-plugin-html";

import { visualizer } from "rollup-plugin-visualizer";
import { webUpdateNotice } from "@plugin-web-update-notification/vite";
import viteCompression from "vite-plugin-compression";
import importToCDN from "vite-plugin-cdn-import";

function pathResolve(dir: string) {
  return resolve(process.cwd(), ".", dir);
}

export default ({ mode }: ConfigEnv): UserConfig => {
  // 获取 .env 环境配置文件
  const env = loadEnv(mode, process.cwd());

  const plugins = [
    vue(),

    webUpdateNotice({
      logVersion: true,
      notificationProps: {
        title: "更新通知",
        description: "网站内容有更新,请刷新页面,获取最新内容",
        buttonText: "刷新",
        dismissButtonText: "忽略"
      }
    }),
    visualizer(),
    //导入自定义组件
    Components({
      // 指定组件位置,默认是src/components
      dirs: ["src/components"],
      extensions: ["vue"],
      // 配置文件生成位置
      dts: "src/components.d.ts",
      // ui库解析器,也可以自定义
      resolvers: [ElementPlusResolver()]
    }),

    //导入vue函数
    AutoImport({
      imports: ["vue", "vue-router", "pinia"],
      // 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
      dts: "src/auto-import.d.ts",
      // eslint报错解决
      eslintrc: {
        enabled: true, // Default `false`
        filepath: "./.eslintrc-auto-import.json", // Default `./.eslintrc-auto-import.json`
        globalsPropValue: true // Default `true`, (true | false | 'readonly' | 'readable' | 'writable' | 'writeable')
      }
    }),

    //按需引入vant组件样式
    createStyleImportPlugin({
      resolves: [ElementPlusResolve()]
    }),

    //ejs变量注入
    createHtmlPlugin({
      minify: true,
      // entry: "src/main.ts",
      // template: "index.html",
      inject: {
        data: {
          title: env.VITE_APP_TITLE,
          isProd: mode === "production"
        }
      }
    }),

    //oss
    // vitePluginAliOss({
    //   region: env.VITE_OSS_REGION,
    //   accessKeyId: env.VITE_OSS_ACCESSKEYID,
    //   accessKeySecret: env.VITE_OSS_ACCESSKEYSECRET,
    //   bucket: env.VITE_OSS_BUCKET,
    // }),

    // 打包压缩,主要是本地gzip,如果服务器配置压缩也可以
    viteCompression(),

    importToCDN({
      modules: [
        {
          name: "videojs",
          var: "videojs",
          path: "https://cdn.bootcdn.net/ajax/libs/video.js/8.2.0/video.min.js",
          css: "https://cdn.bootcdn.net/ajax/libs/video.js/8.2.0/video-js.min.css"
        }
      ]
    })
  ]; // 可将其他插件放入该数组

  return {
    //开发或生产环境服务的公共基础路径
    // base: mode === 'production' ? env.VITE_OSS_URL : './',
    base: "./",
    resolve: {
      alias: [
        {
          find: /@\//,
          replacement: pathResolve("src") + "/"
        }
      ]
    },
    css: {
      preprocessorOptions: {
        //配置全局样式
        // scss: {
        //   //设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
        //   charset: false,
        //   additionalData: ['@use "@/assets/css/globalstyle.scss" as *;'],
        // },
      }
    },
    server: {
      host: "0.0.0.0",
      port: Number(env.VITE_APP_PORT),
      open: false, // 设置服务启动时是否自动打开浏览器
      cors: true, // 允许跨域
      proxy: {
        [env.VITE_APP_BASE_API]: {
          target: env.VITE_APP_BASE_API_URL,
          changeOrigin: true,
          secure: false,
          //删除/api
          rewrite: path => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), "")
        }
      }
    },
    plugins: plugins,

    build: {
      minify: "terser",
      //限制的大小将500kb改成600kb
      chunkSizeWarningLimit: 600,

      terserOptions: {
        compress: {
          //生产环境时移除console
          drop_console: true,
          drop_debugger: true
        },
        output: {
          // 去掉注释内容
          comments: true
        }
      },

      //指定生成静态资源的存放路径
      assetsDir: "/",

      rollupOptions: {
        //打包目录区分优化
        output: {
          // manualChunks(id) {
          //   // if (id.includes('node_modules')) {
          //   //   return id.toString().split('node_modules/')[1].split('/')[0].toString();
          //   // }
          // },

          //把echarts单独打包(按需引入分离出去)
          manualChunks: {
            echarts: ["echarts"]
          },
          chunkFileNames: "static/[name]-[hash].js",
          entryFileNames: "static/[name]-[hash].js",
          assetFileNames: "static/[name]-[hash].[ext]"
        }
      }
    }
  };
};

自动导入组件、hooks、样式

插件 作用
unplugin-vue-components 组件自动引入
unplugin-auto-import/vite vue3等插件 hooks 自动引入
vite-plugin-style-import 样式自动引入
vue-global-api eslint插件

1.1 自动导入ui库,该插件内置了大多数流行库解析器

npm install unplugin-vue-components -D
// vite.config.js,插件会生成一个ui库组件以及指令路径components.d.ts文件
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'
import {
  ElementPlusResolver,
  AntDesignVueResolver,
  VantResolver,
  HeadlessUiResolver,
  ElementUiResolver
} from 'unplugin-vue-components/resolvers'

export default defineConfig({
  plugins: [
    Components({
      // ui库解析器,也可以自定义
      resolvers: [
        ElementPlusResolver(),
        AntDesignVueResolver(),
        VantResolver(),
        HeadlessUiResolver(),
        ElementUiResolver()
      ]
    })
  ]
})

1.2 自动导入自己的组件

// vite.config.js,插件会生成一个自己组件路径的components.d.ts文件
import { defineConfig } from 'vite'
import Components from 'unplugin-vue-components/vite'

export default defineConfig({
  plugins: [
    Components({
      // 指定组件位置,默认是src/components
      dirs: ['src/components'],
      // ui库解析器
      // resolvers: [ElementPlusResolver()],
      extensions: ['vue'],
      // 配置文件生成位置
      dts: 'src/components.d.ts'
    })
  ]
})

2. unplugin-auto-import/vite

支持vue, vue-router, vue-i18n, @vueuse/head, @vueuse/core等自动引入

// 引入前
import { ref, computed } from 'vue'
const count = ref(0)
const doubled = computed(() => count.value * 2)

//引入后
const count = ref(0)
const doubled = computed(() => count.value * 2)


// 引入前
import { useState } from 'react'
export function Counter() {
  const [count, setCount] = useState(0)
  return <div>{ count }</div>
}

//引入后
export function Counter() {
  const [count, setCount] = useState(0)
  return <div>{ count }</div>
}

安装

npm i -D unplugin-auto-import
// vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'

export default defineConfig({
  plugins: [
    AutoImport({
      imports: ['vue', 'vue-router', 'vue-i18n', '@vueuse/head', '@vueuse/core'],
      // 可以选择auto-import.d.ts生成的位置,使用ts建议设置为'src/auto-import.d.ts'
      // dts: 'src/auto-import.d.ts'
    })
  ]
})

原理: 安装的时候会自动生成auto-imports.d文件(默认是在根目录)

3.vue-global-api解决eslint报错

在页面没有引入的情况下,使用unplugin-auto-import/vite来自动引入hooks,在项目中肯定会报错的,这时候需要在eslintrc.js中的extends引入vue-global-api,这个插件是vue3hooks的,其他自己找找,找不到的话可以手动配置一下globals

安装

npm i vue-global-api -D
// .eslintrc.js
module.exports = {
  extends: [
    'vue-global-api'
  ]
};

它还为细粒度控制提供了相同的集合和单个 API 选项。

// .eslintrc.js
module.exports = {
  extends: [
    // collections
    'vue-global-api/reactivity',
    'vue-global-api/lifecycle',
    'vue-global-api/component',
    // single apis
    'vue-global-api/ref',
    'vue-global-api/toRef',
  ]
};

4.vite-plugin-style-import

当你使用unplugin-vue-components来引入ui库的时候

message, notification 等引入样式不生效 安装vite-plugin-style-import即可

这里以一些流行库为例

// vite.config.js
import { defineConfig } from 'vite'
import styleImport, {
  AndDesignVueResolve,
  VantResolve,
  ElementPlusResolve,
  NutuiResolve,
  AntdResolve
} from 'vite-plugin-style-import'

export default defineConfig({
  plugins: [
    styleImport({
      resolves: [
        AndDesignVueResolve(),
        VantResolve(),
        ElementPlusResolve(),
        NutuiResolve(),
        AntdResolve()
      ],
      // 自定义规则
      libs: [
        {
          libraryName: 'ant-design-vue',
          esModule: true,
          resolveStyle: (name) => {
            return `ant-design-vue/es/${name}/style/index`
          }
        }
      ]
    })
  ],
  // 引用使用less的库要配置一下
  css: {
    preprocessorOptions: {
      less: {
        javascriptEnabled: true
      }
    }
  }
})

5. 注意点

1. element-plus默认是英文

方案: 在app.vue加上ElConfigProvider

<template>
  <div id="app">
    <el-config-provider :locale="locale">
      <router-view></router-view>
    </el-config-provider>
  </div>
</template>
<script setup>
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
const locale = zhCn
</script>

日期相关组件设置中文:

<script setup>
// 日历等与dayjs相关的组件,不想显示中文可以不加
// 第一种方法 使用中国时区weekStart默认为1
import 'dayjs/locale/zh-cn'

// 第二种方法 使用 weekStart可配置(只能是0或者1)
import dayjs from 'dayjs'
// 引入英文即为英文
import cn from 'dayjs/locale/zh-cn'
dayjs.locale({
  ...cn,
  weekStart: 1
})


const locale = zhCn
</script>

vite-plugin-ali-oss

打包自动上传打包文件到oss

import vitePluginAliOss from 'vite-plugin-ali-oss';
  // 获取 .env 环境配置文件
const env = loadEnv(mode, process.cwd());

    //oss  plugins数组
vitePluginAliOss({
            region: env.VITE_OSS_REGION,
            accessKeyId: env.VITE_OSS_ACCESSKEYID,
            accessKeySecret: env.VITE_OSS_ACCESSKEYSECRET,
            bucket: env.VITE_OSS_BUCKET
    })

vite使用cdn

vite-plugin-cdn-import

import importToCDN from 'vite-plugin-cdn-import';
importToCDN({
    modules: [
        {
            name: 'vue',
            var: 'Vue',
            path: 'https://cdn.jsdelivr.net/npm/vue@3.2.25/dist/vue.global.prod.js'
        },
        {
            name: 'vue-i18n',
            var: 'VueI18n',
            path: 'https://cdn.bootcdn.net/ajax/libs/vue-i18n/9.1.10/vue-i18n.global.prod.min.js'
        },
        {
            name: 'vue-router',
            var: 'VueRouter',
            path: 'https://unpkg.com/vue-router@4.0.16/dist/vue-router.global.prod.js'
        },

        {
            name: 'element-plus',
            var: 'ElementPlus',
            path: `https://unpkg.com/element-plus@2.2.6/dist/index.full.js`,
            css: 'https://unpkg.com/element-plus/dist/index.css'
        },
        {
            name: 'vue-demi',
            var: 'VueDemi',
            path: 'https://cdn.bootcdn.net/ajax/libs/vue-demi/0.13.1/index.iife.js'
        },
        {
            name: 'pinia',
            var: 'Pinia',
            path: 'https://cdn.bootcdn.net/ajax/libs/pinia/2.0.14/pinia.iife.prod.min.js'
        },
        {
            name: '@smallwei/avue',
            var: 'AVUE',
            path: 'https://cdn.jsdelivr.net/npm/@smallwei/avue@3.0.17'
        }
    ]
}),
这上面的都有引用关系所以都需要通过cdn的方式引入
VueDemi这个是pinia用来判断是vue2还是vue3所需要的,要额外引入一下

第二种方案(通过rollup-plugin-external-globals)这个方式需要单独在index.html中引入cdn资源

import externalGlobals from 'rollup-plugin-external-globals';
let globals = externalGlobals({
    vue: 'Vue',
    'vue-i18n': 'VueI18n',
    'vue-router': 'VueRouter',
    'element-plus': 'ElementPlus',
    pinia: 'Pinia',
    '@smallwei/avue': 'AVUE'
});

//vite.config.ts(注意plugins的位置是在build下)

build:{
    rollupOptions:{
        // 忽略打包
        external: ['vue', 'vue-i18n', 'pinia', 'vue-router', 'element-plus','@smallwei/avue'],
    },
    plugins: [globals],
}

// index.html

<script src="https://cdn.jsdelivr.net/npm/vue@3.2.25/dist/vue.global.prod.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-i18n/9.1.10/vue-i18n.global.prod.min.js"></script>
<script src="https://unpkg.com/vue-router@4.0.16/dist/vue-router.global.prod.js"></script>
<script src="https://unpkg.com/element-plus@2.2.6/dist/index.full.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/vue-demi/0.13.1/index.iife.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/pinia/2.0.14/pinia.iife.prod.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@smallwei/avue@3.0.17"></script>

网页重新部署,通知用户-最佳实践

安装插件

pnpm add @plugin-web-update-notification/vite -D

原理

以 git commit hash (也支持 package.json version、build timestamp、custom) 为版本号,打包时将版本号写入 json 文件。客户端轮询服务器上的版本号(浏览器窗口的 visibilitychange、focus 事件辅助),和本地作比较,如果不相同则通知用户刷新页面。

vite.config.ts

import { webUpdateNotice } from '@plugin-web-update-notification/vite'


export default defineConfig({
  plugins: [
    vue(),
    webUpdateNotice({
      notificationProps: {
        title: '更新通知',
        description: '网站内容有更新,请刷新页面,获取最新内容',
        buttonText: '刷新',
        dismissButtonText: '忽略'
      },
    }),
  ]
})
目录
暂无评论,欢迎留下你的评论

运营需要亿点资金维持,您的支持,是小白龙创作的动力!!!

昵称
留言
赞赏金额