从0到1,带你搭建Vite+Vue3+Unocss+Pinia+Naive UI后台(二) - 配置篇(中)

16,178 阅读5分钟

预览地址:vue-naive-admin

前言

系列文章:

  1. 从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(一) - 前置篇 - 掘金 (juejin.cn)
  2. 从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(二) - 配置篇(上) - 掘金 (juejin.cn)
  3. 从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(二) - 配置篇(中) - 掘金 (juejin.cn)

配置篇

配置篇分上中下三部分,本篇主要介绍插件配置

  1. 环境配置 + vite配置
  2. 插件配置
  3. eslint+prettier配置

插件配置

本篇将介绍如何集成以下几个插件:

  1. vite-plugin-vue-setup-extend:扩展setup插件,支持在script标签中使用name属性
  2. rollup-plugin-visualizer:rollup打包分析插件
  3. vite-plugin-html:一个针对 index.html,提供压缩和基于 ejs 模板功能的 vite 插件
  4. unocss: 出自antfu的原子化css

在后续文章中也会按进度集成图标插件、组件库按需引入插件及mock插件

集成 vite-plugin-vue-setup-extend

第一步:安装vite-plugin-vue-setup-extend

pnpm i vite-plugin-vue-setup-extend -D

第二步:在build文件夹下创建plugin/index.js

build/plugin/index.js

import vue from '@vitejs/plugin-vue'

/**
 * * 扩展setup插件,支持在script标签中使用name属性
 * usage: <script setup name="MyComp"></script>
 */
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

export function createVitePlugins(viteEnv, isBuild) {
  const plugins = [
    vue(),
    VueSetupExtend(),
  ]

  return plugins
}

第三步: 修改vite.config.js

vite.config.js

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

import { wrapperEnv, createProxy  } from './build/utils'
import { createVitePlugins } from './build/plugin'

export default defineConfig(({ command, mode }) => {
  const isBuild = command === 'build'
  const env = loadEnv(mode, process.cwd())
  const viteEnv = wrapperEnv(env)
  const { VITE_PORT, VITE_PUBLIC_PATH, VITE_PROXY } = viteEnv
  
  return {
    plugins: createVitePlugins(viteEnv, isBuild),
    base: VITE_PUBLIC_PATH || '/',
    resolve: {
      // 设置别名
      alias: {
        '@': path.resolve(__dirname, 'src'),
      },
    },
    css: {
      preprocessorOptions: {
        //define global scss variable
        scss: {
          additionalData: `@import '@/styles/variables.scss';`,
        },
      },
    },
    server: {
      host: '0.0.0.0',  // 默认为'127.0.0.1',如果将此设置为 `0.0.0.0` 或者 `true` 将监听所有地址,包括局域网和公网地址
      port: VITE_PORT,  // 端口
      proxy: createProxy(VITE_PROXY), // 代理
    }
  }
})

文件修改处如下图所示:

image.png

集成rollup-plugin-visualizer

第一步:安装rollup-plugin-visualizer

pnpm i rollup-plugin-visualizer -D

第二步:修改build/plugin/index.js

build/plugin/index.js

import vue from '@vitejs/plugin-vue'

/**
 * * 扩展setup插件,支持在script标签中使用name属性
 * usage: <script setup name="MyComp"></script>
 */
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

// rollup打包分析插件
import visualizer from 'rollup-plugin-visualizer'

export function createVitePlugins(viteEnv, isBuild) {
  const plugins = [
    vue(),
    VueSetupExtend(),
  ]
  
  if (isBuild) {
    plugins.push(
      visualizer({
        open: true,
        gzipSize: true,
        brotliSize: true,
      })
    )
  }

  return plugins
}

第三步:打包验证下插件是否生效

pnpm run build

正常应该会在根目录产生一个stats.html文件,通过浏览器打开这个文件,会看到如下页面,由于目前还算是一个空项目,所有还没有太多的依赖项

image.png

第四步:将stats.html添加到git忽略项

.gitignore

...


stats.html

stats.html每次打包都会生成一个新的,无需通过git添加提交

集成vite-plugin-html

集成 vite-plugin-html 主要是为了对 index.html 进行压缩和注入动态数据,例如替换网站标题和cdn

第一步:安装vite-plugin-html

pnpm i vite-plugin-html@2 -D

第二步:创建build/plugin/html.js

build/plugin/html.js

import html from 'vite-plugin-html'

export function configHtmlPlugin(viteEnv, isBuild) {
  const { VITE_APP_TITLE } = viteEnv
  const htmlPlugin = html({
    minify: isBuild,
    inject: {
      data: {
        title: VITE_APP_TITLE,
      },
    },
  })
  return htmlPlugin
}

第三步:修改build/plugin/index.js

build/plugin/index.js

import vue from '@vitejs/plugin-vue'

/**
 * * 扩展setup插件,支持在script标签中使用name属性
 * usage: <script setup name="MyComp"></script>
 */
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

// rollup打包分析插件
import visualizer from 'rollup-plugin-visualizer'

import { configHtmlPlugin } from './html'

export function createVitePlugins(viteEnv, isBuild) {
  const plugins = [
    vue(),
    VueSetupExtend(),
    configHtmlPlugin(viteEnv, isBuild),
  ]
  
  if (isBuild) {
    plugins.push(
      visualizer({
        open: true,
        gzipSize: true,
        brotliSize: true,
      })
    )
  }

  return plugins
}

第四步:修改 index.html 的title,并重新启动,验证插件是否集成成功

<title><%= title %></title>

如无意外将看到页面的title已经被替换成我们配置好的title了

集成unocss

第一步:安装依赖

pnpm i unocss @unocss/preset-attributify @unocss/preset-icons @unocss/preset-uno -D

第二步:新建文件 build/plugin/unocss.js

build/plugin/unocss.js

import Unocss from 'unocss/vite'
import { presetUno, presetAttributify, presetIcons } from 'unocss'

export function unocss() {
  return Unocss({
    presets: [presetUno(), presetAttributify(), presetIcons()],
  })
}

第三步:修改文件 build/plugin/index.js

build/plugin/index.js

import vue from '@vitejs/plugin-vue'

/**
 * * 扩展setup插件,支持在script标签中使用name属性
 * usage: <script setup name="MyComp"></script>
 */
import VueSetupExtend from 'vite-plugin-vue-setup-extend'

// rollup打包分析插件
import visualizer from 'rollup-plugin-visualizer'

import { configHtmlPlugin } from './html'
import { unocss } from './unocss'

export function createVitePlugins(viteEnv, isBuild) {
  const plugins = [
    vue(),
    VueSetupExtend(),
    configHtmlPlugin(viteEnv, isBuild),
    unocss()
  ]
  
  if (isBuild) {
    plugins.push(
      visualizer({
        open: true,
        gzipSize: true,
        brotliSize: true,
      })
    )
  }

  return plugins
}

第四步:新建 styles/reset.scssstyles/public.scssstyles/index.scss

styles/reset.scss

html {
  box-sizing: border-box;
}

*,
::before,
::after {
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}

a {
  text-decoration: none;
  color: #333;
}

a:hover,
a:link,
a:visited,
a:active {
  text-decoration: none;
}

ol,
ul {
  list-style: none;
}

input,
textarea {
  outline: none;
  border: none;
  resize: none;
}

body {
  font-size: 14px;
  font-weight: 400;
}

styles/public.scss

html {
  font-size: 4px; // * 1rem = 4px  方便unocss计算:在unocss中 1字体单位 = 0.25rem,相当于 1等份 = 1px
}

html,
body {
  width: 100%;
  height: 100%;
  overflow: hidden;
  background-color: #f2f2f2;
  font-family: 'Encode Sans Condensed', sans-serif;
}

/* 滚动条样式 */
::-webkit-scrollbar {
  width: 8px;
  background-color: #eee;
}

::-webkit-scrollbar-thumb {
  background-color: #c1c1c1;

  &:hover {
    background-color: #a8a8a8;
  }
}

styles/index.scss

@import './reset.scss';
@import './public.scss';

第步:修改 src/main.js 引入uno.css

src/main.js

import '@/styles/index.scss'
import 'uno.css'

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

第五步:修改 src/App.vue ,使用unocss以验证unocss是否集成成功

src/App.vue

<template>
  <div p-24>
    <p>
      文档:<a hover-decoration-underline c-blue href="https://uno.antfu.me/" target="_blank">https://uno.antfu.me/</a>
    </p>
    <p>
      playground:
      <a c-blue hover-decoration-underline href="https://unocss.antfu.me/play/" target="_blank">
        https://unocss.antfu.me/play/
      </a>
    </p>

    <div flex mt-20>
      <div flex p-20 rounded-5 bg-white>
        <div text-20 font-600>Flex布局</div>
        <div flex w-360 flex-wrap justify-around ml-15 p-10>
          <div w-50 h-50 b-1 rounded-5 flex justify-center items-center p-10 m-20>
            <span w-6 h-6 rounded-3 bg-black></span>
          </div>
          <div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
            <span w-6 h-6 rounded-3 bg-black></span>
            <span w-6 h-6 rounded-3 bg-black self-end></span>
          </div>
          <div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
            <span w-6 h-6 rounded-3 bg-black></span>
            <span w-6 h-6 rounded-3 bg-black self-center></span>
            <span w-6 h-6 rounded-3 bg-black self-end></span>
          </div>
          <div w-50 h-50 b-1 rounded-5 flex justify-between p-10 m-20>
            <div flex flex-col justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
            <div flex flex-col justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
          </div>
          <div w-50 h-50 b-1 rounded-5 flex flex-col justify-between items-center p-10 m-20>
            <div flex w-full justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
            <span w-6 h-6 rounded-3 bg-black></span>
            <div flex w-full justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
          </div>
          <div w-50 h-50 b-1 rounded-5 flex flex-col justify-between p-10 m-20>
            <div flex w-full justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
            <div flex w-full justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
            <div flex w-full justify-between>
              <span w-6 h-6 rounded-3 bg-black></span>
              <span w-6 h-6 rounded-3 bg-black></span>
            </div>
          </div>
        </div>
      </div>

      <div flex ml-35 p-20 rounded-5 bg="#fff">
        <div text-20 font-600>字体:</div>
        <div ml-15 p-10 pl-30 pr-30 rounded-5>
          <p text-12>font-size: 12px</p>
          <p text-16>font-size: 16px</p>
          <p text-20>font-size: 20px</p>

          <p font-300 mt-10>font-weight: 300</p>
          <p font-600>font-weight: 600</p>
          <p font-bold>font-weight: bold</p>
        </div>
      </div>

      <div flex p-20 ml-35 rounded-5 bg-white>
        <div text-20 font-600>颜色:</div>
        <div ml-15 p-10 pl-30 pr-30 rounded-5>
          <p color="#881337">color: #881337</p>
          <p c-pink-500>color: #ec4899</p>

          <p bg="pink" mt-10>background: pink</p>
          <p bg="#2563eb" mt-10>background: #2563eb</p>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup></script>

重新启动看到以下页面就证明集成成功了,另外 src/components/HelloWorld.vue 文件可以直接删除了

image.png

插件篇暂时就介绍到这里,本篇内容较多,但除了unocss其他都相对简单,unocss的集成相对复杂,但集成后使用起来还是很爽的,重点是它足够轻

如有跟着一起做的朋友可以git提交一下代码,如有错误之处请在评论区提醒指正,下一篇再见~

总结

都看到这了,还请各位赏个赞和star再走呗,你的赞和star是我持续更新和维护的动力哦


源码-github:vue-naive-admin (github.com)

源码-gitee:vue-naive-admin (gitee.com)

下一篇: 从0到1,带你搭建Vite+Vue3+Pinia+Naive UI后台(二) - 配置篇(下) - 掘金 (juejin.cn)