jiangwei小站
636 字
3 分钟
搭建vite2.0+vue3.0+ts+多页面打包+多环境+gzip+图片压缩框架
2022-07-01

首先安装 vite#

npm init @vitejs/app
yarn create @vitejs/app

使用预设模板创建框架#

yarn create @vitejs/app my-vue-app --template vue

支持的模板预设包括:

vanilla vue vue-ts react react-ts preact preact-ts lit-element lit-element-ts

使用 scss#

npm i --save-d sass
<style lang="scss"> 即可

使用@路径#

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": resolve("./src")
    }
  }
});

环境区分#

  1. 新增 .env.dev .env.test .env.prod 三个文件
VITE_PROJECT_ENV = 'prod'

(必须 VITE 开头) 在 ts 中可使用 import.meta.env.VITE_PROJECT_ENV 区分

  1. package.json
"build": "vue-tsc --noEmit && VITE_PROJECT_ENV=prod vite build"

在 vite.config.ts 中使用 process.env.VITE_PROJECT_ENV === “prod”

多页面打包#

const pageEntry = {};

(function () {
  // 遍历文件夹中含有main.ts的文件夹路径
  const allEntry = glob.sync("./src/views/**/main.ts");
  // 获取模板
  const temp = fs.readFileSync("./index.html");
  // 创建pages文件夹存放多页面模板
  if (!fs.existsSync("./pages")) {
    fs.mkdirSync("./pages");
  }
  // 创建多页面模板
  allEntry.forEach((entry: string) => {
    const pathArr = entry.split("/");
    const name = pathArr[pathArr.length - 2];
    // 判断文件是否存在
    try {
      fs.accessSync(`./pages/${name}.html`);
    } catch (err) {
      console.log(`创建${name}.html文件`);
      const index = temp.toString().indexOf("</body>");
      const content =
        temp.toString().slice(0, index) +
        `<script type="module" src=".${entry}"></script>` +
        temp.toString().slice(index);
      fs.writeFile(`./pages/${name}.html`, content, err => {
        if (err) console.log(err);
      });
    }
    // input中的配置
    pageEntry[name] = path.resolve(__dirname, `/pages/${name}.html`);
  });
})();
//views文件夹中添加文件即可,会获取里面的文件夹名在pages中生产模板

build: {
    outDir: isProd ? "dist" : "pre",
    rollupOptions: {
      input: pageEntry
    }
  }

gzip#

import viteCompression from 'vite-plugin-compression';
plugins: [vue(), viteCompression()],

图片压缩#

import viteImagemin from "vite-plugin-imagemin";
plugins: [vue(), viteImagemin()],

改良:

  1. tsconfig.json 新增:
"baseUrl": ".",
"paths": {
  "@/*": ["src/*"]
}

使页面引入 ts 不报错 import api from ”@/api”;

  1. 打包新增判断,pages 已经有对应 html 的时候不进行创建文件

完整配置#

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import path from "path";
import glob from "glob";
import fs from "fs";
import viteCompression from "vite-plugin-compression";
import viteImagemin from "vite-plugin-imagemin";
const isProd = process.env.VITE_PROJECT_ENV === "prod";
const pageEntry = {};

(function () {
  // 遍历文件夹中含有main.ts的文件夹路径
  const allEntry = glob.sync("./src/views/**/main.ts");
  // 获取模板
  const temp = fs.readFileSync("./index.html");
  // 创建pages文件夹存放多页面模板
  if (!fs.existsSync("./pages")) {
    fs.mkdirSync("./pages");
  }
  // 创建多页面模板
  allEntry.forEach((entry: string) => {
    const pathArr = entry.split("/");
    const name = pathArr[pathArr.length - 2];
    // 判断文件是否存在
    try {
      fs.accessSync(`./pages/${name}.html`);
    } catch (err) {
      console.log(`创建${name}.html文件`);
      const index = temp.toString().indexOf("</body>");
      const content =
        temp.toString().slice(0, index) +
        `<script type="module" src=".${entry}"></script>` +
        temp.toString().slice(index);
      fs.writeFile(`./pages/${name}.html`, content, err => {
        if (err) console.log(err);
      });
    }
    // input中的配置
    pageEntry[name] = path.resolve(__dirname, `/pages/${name}.html`);
  });
})();

export default defineConfig({
  server: {
    fs: {
      strict: false
    }
  },
  plugins: [
    vue(),
    viteCompression({
      ext: ".gz",
      algorithm: "gzip",
      deleteOriginFile: false
    }),
    viteImagemin({
      gifsicle: {
        optimizationLevel: 7,
        interlaced: false
      },
      optipng: {
        optimizationLevel: 7
      },
      mozjpeg: {
        quality: 20
      },
      pngquant: {
        quality: [0.8, 0.9],
        speed: 4
      },
      svgo: {
        plugins: [
          {
            name: "removeViewBox"
          },
          {
            name: "removeEmptyAttrs",
            active: false
          }
        ]
      }
    })
  ],
  resolve: {
    alias: {
      "@": path.join(__dirname, "./src")
    }
  },
  build: {
    outDir: isProd ? "dist" : "pre",
    rollupOptions: {
      input: pageEntry
    }
  }
});

项目地址#

https://github.com/jwnoal/vite_vue3