Vue3 H5 项目尝试(三)

400 阅读1分钟

vite.config.ts 配置

官网

plugins

import type { Plugin } from 'vite';

import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';

import { configHtmlPlugin } from './html';
import { configCompressPlugin } from './compress';
import { configStyleImportPlugin } from './styleImport';
import AutoImport from 'unplugin-auto-import/vite';
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers';
import Components from 'unplugin-vue-components/vite';
import OptimizationPersist from 'vite-plugin-optimize-persist';
import PkgConfig from 'vite-plugin-package-config';

export function createVitePlugins(viteEnv: ViteEnv, isBuild: boolean) {
  const { VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE } = viteEnv;

  const vitePlugins: (Plugin | Plugin[])[] = [
    // have to
    vue(),
    // have to
    vueJsx(),

    PkgConfig(),

    OptimizationPersist(),

    configStyleImportPlugin(isBuild),

    AutoImport({
      // Auto import functions from Vue, e.g. ref, reactive, toRef...
      // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
      imports: ['vue'],

      // Auto import functions from Element Plus, e.  g. ElMessage, ElMessageBox... (with style)
      // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式)
      resolvers: [ElementPlusResolver()],
    }),

    Components({
      resolvers: [ElementPlusResolver()],
    }),
  ];

  // vite-plugin-html
  vitePlugins.push(configHtmlPlugin(viteEnv, isBuild));

  if (isBuild) {
    // rollup-plugin-gzip
    vitePlugins.push(
      configCompressPlugin(VITE_BUILD_COMPRESS, VITE_BUILD_COMPRESS_DELETE_ORIGIN_FILE)
    );
  }

  return vitePlugins;
}

html.ts

import type { Plugin } from 'vite';

import html from 'vite-plugin-html';

import pkg from '../../package.json';
import { GLOB_CONFIG_FILE_NAME } from '../constant';

export function configHtmlPlugin(env: ViteEnv, isBuild: boolean) {
  const { VITE_GLOB_APP_TITLE, VITE_PUBLIC_PATH } = env;

  const path = VITE_PUBLIC_PATH.endsWith('/') ? VITE_PUBLIC_PATH : `${VITE_PUBLIC_PATH}/`;

  const getAppConfigSrc = () => {
    return `${path || '/'}${GLOB_CONFIG_FILE_NAME}?v=${pkg.version}-${new Date().getTime()}`;
  };

  const htmlPlugin: Plugin[] = html({
    minify: isBuild,
    inject: {
      // Inject data into ejs template
      injectData: {
        title: VITE_GLOB_APP_TITLE,
      },
    },
  });
  return htmlPlugin;
}

compress.ts基本上没用

/**
 * Used to package and output gzip. Note that this does not work properly in Vite, the specific reason is still being investigated
 * https://github.com/anncwb/vite-plugin-compression
 */
import type { Plugin } from 'vite';

import compressPlugin from 'vite-plugin-compression';

export function configCompressPlugin(
  compress: 'gzip' | 'brotli' | 'none',
  deleteOriginFile = false
): Plugin | Plugin[] {
  const compressList = compress.split(',');

  const plugins: Plugin[] = [];

  if (compressList.includes('gzip')) {
    plugins.push(
      compressPlugin({
        ext: '.gz',
        deleteOriginFile,
      })
    );
  }
  if (compressList.includes('brotli')) {
    plugins.push(
      compressPlugin({
        ext: '.br',
        algorithm: 'brotliCompress',
        deleteOriginFile,
      })
    );
  }
  return plugins;
}

styleImport.ts

/**
 *  Introduces component library styles on demand.
 * https://github.com/anncwb/vite-plugin-style-import
 */

import styleImport, { VantResolve, ElementPlusResolve } from 'vite-plugin-style-import';

export function configStyleImportPlugin(isBuild: boolean) {
  if (!isBuild) return [];
  const styleImportPlugin = styleImport({
    resolves: [VantResolve(), ElementPlusResolve()],
  });
  return styleImportPlugin;
}

build

build: {
  target: 'es2015',
  terserOptions: {
    compress: {
      keep_infinity: true,
      drop_console: VITE_DROP_CONSOLE,
      drop_debugger: true,
    },
  },
  brotliSize: false,
  chunkSizeWarningLimit: 2000,
  rollupOptions: {
    input: {
      index: resolve(__dirname, 'index.html'),
      mobile: resolve(__dirname, 'mobile.html'),
    },
    // external: ['element-plus']
  },
  outDir: VITE_H5_DEBUGGER ? DEBUGGER_OUTPUT_DIR : OUTPUT_DIR,
},

rollupOptions 用来标志两个端的入口,打包才能把两边都打进去

css

css: {
  preprocessorOptions: {
    less: {
      modifyVars: {},
      javascriptEnabled: true,
      additionalData: [`@import "src/assets/theme/var.less";`],
    },
  },
},

resolve

resolve: {
  alias: [
    {
      find: /\/#\//,
      replacement: pathResolve('types') + '/',
    },
    {
      find: '@',
      replacement: pathResolve('src') + '/',
    },
  ],
  dedupe: ['vue'],
},

server

server: {
  host: true,
  port: VITE_PORT,
  proxy: createProxy(process.env.MOCK_TYPE === 'YAPI' ? VITE_YAPI_PROXY : VITE_PROXY),
},

proxy.ts

import type { ProxyOptions } from 'vite';

type ProxyItem = [string, string];

type ProxyList = ProxyItem[];

type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>;

const httpsRE = /^https:\/\//;

/**
 * Generate proxy
 * @param list
 */
export function createProxy(list: ProxyList = []) {
  const ret: ProxyTargetList = {};
  for (const [prefix, target] of list) {
    const isHttps = httpsRE.test(target);

    // https://github.com/http-party/node-http-proxy#options
    ret[prefix] = {
      target: target,
      changeOrigin: true,
      ws: true,
      rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
      // https is require secure=false
      ...(isHttps ? { secure: false } : {}),
    };
  }
  return ret;
}