vite常用配置


import {defineConfig} from 'vite'
import vue from '@vitejs/plugin-vue'
import vitePluginImp from 'vite-plugin-imp'
import path from 'path'

const isProduction = process.env.NODE_ENV === 'production'

// https://vitejs.dev/config/
export default defineConfig({
  // 項目根目錄
  root: process.cwd(),
  // 在生產中服務時的基本公共路徑
  base: isProduction ? './' : '',
  // 配置中指明將會把 serve 和 build 時的模式都覆蓋掉,serve 時默認 'development',build 時默認 'production'
  mode: 'development',
  // 在開發時會被定義為全局變量,而在構建時則是靜態替換
  define: '',
  // 靜態資源服務的文件夾
  publicDir: 'assets',
  resolve: {
    // 目錄別名
    alias: {
      '@': path.resolve(__dirname, '/src'),
    },

  },
// CSS 預處理器
  css: {
    preprocessorOptions: {
      scss: {
        // additionalData: `$injectedColor: orange;`
        additionalData: "@import './src/assets/style/mixin.scss';"
      }
      ,
      less: {
        javascriptEnabled: true
      }
    },
    postcss: {
      plugins: [
        require('autoprefixer')
      ]
    }
  },
//
  server: {
    // 是否自動打開瀏覽器
    open: true,
    // 服務器主機名,如果允許外部訪問,可設置為"0.0.0.0"
    host: '0.0.0.0',
    // 服務器端口號
    port: 56438,
    // 設為 true ,若端口已被占用則會直接退出,而不是嘗試下一個可用端口
    strictPort: false,
    // 為開發服務器配置 CORS
    cors: true,
    // 設置為 true 強制使依賴預構建
    force: true,
// 代理
    proxy: {
      '/api':
        {
          target: 'http://xxx.xxx.xx',
          changeOrigin: true,
          rewrite:
            (path) => path.replace(/^\/api/, '')
        }
    }
    ,
  }
  ,
// build
  build: {
    // 壓縮
    minify: "esbuild",
    assetsDir: "",
    outDir: `./dist/${process.env.VITE_ENV}`,
    // 進行壓縮計算
    brotliSize: false
  },
  ssr: false,
  // 將要用到的插件數組
  plugins:
    [
      vue(),
      vitePluginImp({
        libList: [
          {
            libName: 'vant',
            style(name) {
              if (/CompWithoutStyleFile/i.test(name)) {
// This will not import any style file
                return false
              }
              return `vant/es/${name}/style/index.js`
            }
          },
          {
            libName: 'element-plus',
            style: (name) => {
              return `element-plus/lib/theme-chalk/${name}.css`
            }
          }
        ]
      }),
      require('autoprefixer')
    ]

})
  

  https://cn.vitejs.dev/config/#resolve-conditions

Vite插件是什么

使用Vite插件可以擴展Vite能力,比如解析用戶自定義的文件輸入,在打包代碼前轉譯代碼,或者查找第三方模塊。

Vite插件的形式

Vite插件擴展自Rollup插件接口,只是額外多了一些Vite特有選項。

Vite插件是一個擁有名稱、創建鈎子(build hook)或生成鈎子(output generate hook)的對象。

如果需要配置插件,它的形式應該是一個接收插件選項,返回插件對象的函數。

范例:加載一個不存在的虛擬模塊

創建vite-plugin-my-example.js

export default function myExample () {
  return {
    name: 'my-example', // 名稱用於警告和錯誤展示
    resolveId ( source ) {
      if (source === 'virtual-module') {
        return source; // 返回source表明命中,vite不再詢問其他插件處理該id請求
      }
      return null; // 返回null表明是其他id要繼續處理
    },
    load ( id ) {
      if (id === 'virtual-module') {
        return 'export default "This is virtual!"'; // 返回"virtual-module"模塊源碼
      }
      return null; // 其他id繼續處理
    }
  };
}

  

插件鈎子

通用鈎子

開發時,Vite dev server創建一個插件容器按照Rollup調用創建鈎子的規則請求各個鈎子函數。

下面鈎子會在服務器啟動時調用一次:

下面鈎子每次有模塊請求時都會被調用:

  • resolveId 創建自定義確認函數,常用語定位第三方依賴
  • load 創建自定義加載函數,可用於返回自定義的內容
  • transform 可用於轉換已加載的模塊內容

下面鈎子會在服務器關閉時調用一次:

Vite特有鈎子

  • config: 修改Vite配置
  • configResolved:Vite配置確認
  • configureServer:用於配置dev server
  • transformIndexHtml:用於轉換宿主頁
  • handleHotUpdate:自定義HMR更新時調用

范例:鈎子調用順序測試

export default function myExample () {
  // 返回的是插件對象
  return {
    name: 'hooks-order', 
    // 初始化hooks,只走一次
    options(opts) {
      console.log('options', opts);
    },
    buildStart() {
      console.log('buildStart');
    },
    // vite特有鈎子
    config(config) {
      console.log('config', config);
      return {}
    },
    configResolved(resolvedCofnig) {
      console.log('configResolved');
    },
    configureServer(server) {
      console.log('configureServer');
      // server.app.use((req, res, next) => {
      //   // custom handle request...
      // })
    },
    transformIndexHtml(html) {
      console.log('transformIndexHtml');
      return html
      // return html.replace(
      //   /<title>(.*?)<\/title>/,
      //   `<title>Title replaced!</title>`
      // )
    },
    // 通用鈎子
    resolveId ( source ) {
      if (source === 'virtual-module') {
        console.log('resolvedId', source);
        return source; 
      }
      return null; 
    },
    load ( id ) {
      if (id === 'virtual-module') {
        console.log('load');
        return 'export default "This is virtual!"';
      }
      return null;
    },
    transform(code, id) {
      if (id === 'virtual-module') {
        console.log('transform');
      }
      return code
    },
  };
}

  

鈎子調用順序

插件順序

  • 別名處理Alias
  • 用戶插件設置enforce: 'pre'
  • Vite核心插件
  • 用戶插件未設置enforce
  • Vite構建插件
  • 用戶插件設置enforce: 'post'
  • Vite構建后置插件(minify, manifest, reporting)

插件編寫實操

實現一個mock服務器vite-plugin-mock

實現思路是給開發服務器實例(connect)配一個中間件,該中間件可以存儲用戶配置接口映射信息,並提前處理輸入請求,如果請求的url和路由表匹配則接管,按用戶配置的handler返回結果。

創建plugins/vite-plugin-mock.js

import path from 'path'

let mockRouteMap = {};

function matchRoute(req) {
  let url = req.url;
  let method = req.method.toLowerCase();
  let routeList = mockRouteMap[method];

  return routeList && routeList.find((item) => item.path === url);
}

function createRoute(mockConfList) {
  mockConfList.forEach((mockConf) => {
    let method = mockConf.type || 'get';
    let path = mockConf.url;
    let handler = mockConf.response;
    let route = { path, method: method.toLowerCase(), handler };
    if (!mockRouteMap[method]) {
      mockRouteMap[method] = [];
    }
    console.log('create mock api: ', route.method, route.path);
    mockRouteMap[method].push(route);
  });
}

function send(body) {
  let chunk = JSON.stringify(body);
  // Content-Length
  if (chunk) {
    chunk = Buffer.from(chunk, 'utf-8');
    this.setHeader('Content-Length', chunk.length);
  }
  // content-type
  this.setHeader('Content-Type', 'application/json');
  // status
  this.statusCode = 200;
  // respond
  this.end(chunk, 'utf8');
}
export default function (options = {}) {
  options.entry = options.entry || './mock/index.js';


  if (!path.isAbsolute(options.entry)) {
    options.entry = path.resolve(process.cwd(), options.entry);
  }

  return {
    configureServer: function ({ app }) {
      const mockObj = require(options.entry);
      createRoute(mockObj);

      const middleware = (req, res, next) => {
        let route = matchRoute(req);

        if (route) {
          console.log('mock request', route.method, route.path);
          res.send = send;
          route.handler(req, res);
        } else {
          next();
        }
      };
      app.use(middleware);
    },
  };
}

  

export default function vitePlugin () {
  // 定義vite插件唯一id
  const virtualFileId = '@my-virtual-plugin'
  // 返回插件對象
  return {
    // 必須的,將會顯示在 warning 和 error 中
    name: 'vite-plugin',

    // *以下鈎子函數按照實際執行順序排列*

    /**
     * config 可以在被解析之前修改 Vite 配置
     * Vite獨有鈎子
     * https://cn.vitejs.dev/guide/api-plugin.html#config
     * @param config vite配置信息
     * @param env 描述配置環境的變量
     */
    config: (config, env) => ({}),

    /**
     * configResolved 解析 Vite 配置后調用,使用這個鈎子讀取和存儲最終解析的配置
     * Vite獨有鈎子
     * https://cn.vitejs.dev/guide/api-plugin.html#configresolved
     * @param config vite配置信息
     */
    configResolved: config => ({}),

    /**
     * options 替換或操作傳遞給rollup.rollup()的選項
     * 通用鈎子
     * https://rollupjs.org/guide/en/#options
     * @param options rollup配置信息
     */
    options: options => ({}),

    /**
     * configureServer 用於配置開發服務器
     * Vite獨有鈎子
     * https://cn.vitejs.dev/guide/api-plugin.html#configureserver
     * @param server ViteDevServer配置信息
     * https://cn.vitejs.dev/guide/api-javascript.html#vitedevserver
     */
    configureServer: server => ({}),

    /**
     * buildStart 在每個rollup.rollup()構建時被調用
     * 通用鈎子
     * https://rollupjs.org/guide/en/#buildstart
     * @param options rollup配置信息
     */
    buildStart: options => ({}),

    /**
     * 此時 Vite dev server is running
     */

    /**
     * transformIndexHtml 轉換 index.html 的專用鈎子
     * Vite獨有鈎子
     * https://cn.vitejs.dev/guide/api-plugin.html#transformindexhtml
     * @param html html字符串
     * @param ctx 轉換上下文; 在開發期間會額外暴露ViteDevServer實例; 在構建期間會額外暴露Rollup輸出的包
     */
    transformIndexHtml: (html, ctx) => ({}),

    /**
     * resolveId 用戶自定義解析器
     * 通用鈎子 會在每個傳入模塊請求時被調用
     * https://rollupjs.org/guide/en/#resolveid
     * @param source 源導入者 例子: import { foo } from '../bar.js', '../bar.js' 為source
     * @param importer 導入者所在文件絕對路徑
     */
    resolveId: (source, importer) => ({}),

    /**
     * load 用戶自定義加載器
     * 通用鈎子 會在每個傳入模塊請求時被調用
     * https://rollupjs.org/guide/en/#load
     * @param id 同resolveId source
     */
    load: id => ({}),

    /**
     * transform 可以用來轉換單個模塊
     * 通用鈎子 會在每個傳入模塊請求時被調用
     * https://rollupjs.org/guide/en/#transform
     * @param code 模塊代碼
     * @param id 同resolveId source
     */
    transform: (code, id) => ({})

  }
}

  下一集:手寫vite


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM