---
# System prepended metadata

title: Vite+Vue3+ts 打包全攻略
tags: [Vue-cli, Vue3]

---

# Vite+Vue3+ts 打包全攻略
###### tags: `Vue-cli`、`Vue3`
先看一下 vite.config.ts 的基本架構
```typescript=
export default defineConfig((init) => {
    return{
        define: {},
        plugins: [],
        base:'',
        resolve: {},
        css: {},
        server:{},
        build: {}
    }
})
```
* ### define
define 這一塊最主要是要定義全域參數的值，定義後即可在程式內直接使用，方法如下：
```typescript=
define:{
    NODE_ENV: JSON.stringify(process.env.NODE_ENV)
}
```
這邊需要注意的是，**一定要有值** 且 **一定要轉成字串**

註：若這邊不是以vite原生打包方式，而是使用webpack，在全域參數這部分需要使用 vite-plugin-environment 套件來做轉換才可使用
* ### plugins
此為擴充套件引入的地方，以下列出幾個比較常用的套件
1. #### @vitejs/plugin-vue
vite 中使用 Vue3 所需套件

2. #### vite-plugin-restart
本地開發時，雖然 config 內自帶有 hmr 的模式，但是若遇到需要預處理 (Ex:Pug) 後才能看到異動的語言，單純透過 hmr 就無法即時看到變化，此套件可設定監聽異動檔案的範圍，儲存後即可立即重啟專案並重新編譯。

3. #### @vitejs/plugin-legacy
用以兼容低版本的套件，此套件引用了 @babel/preset-env  的功能，並將程式最後編譯為 SystemJs ，套件可設定預支持的最低版本以及透過 polyfill 可以額外引入需要擴展與轉編譯的 modules 。

4. #### vite-plugin-html
此套件可將預在 index.html 使用的參數傳入，並在打包時自動替換上對應資料。

* ### base
此為打包時入口檔基本路徑，若不設定預設為/，設定之後會自動於打包時寫入 index.html 的入口檔路徑

* ### resolve
此設定為編譯方式的設定，較常用的參數為alias與extensions
1. #### alias
專責設定別名短路徑，可供 import 時不用寫整條路徑，並使用相對路徑讓在不同機器均可使用，設定方法如下：
```typescript=
      alias: {
        "@": path.resolve(__dirname, "src")
      }
```
2. #### extensions
設定後，import 時可省略輸入副檔名，但自定義檔案不建議使用，不一定會支持，設定方法如下：
```typescript=
extensions: [".js", ".ts", ".jsx", ".tsx", ".json"]
```

* ### css
此為針對全css的配置，可設定css全域參數或是兼容版本，常用參數有 postcss、preprocessorOptions，介紹如下：
1. #### postcss
此處可以針對css使用一些外掛套件，比如瀏覽器兼容、布局配置等來做不同裝置的兼容，以瀏覽器兼容來說有 postcss-preset-env 與 autoprefixer，但 postcss-preset-env 本身就包含了 autoprefixer 的功能，此套件功能為：將最新的 CSS 語法轉換為大多瀏覽器可閱讀的寫法，並自動獲取 "Can I use" 內的瀏覽器版本支援度，並自動補上前綴 (Ex：--webkit)。
布局配置的話，可使用 postcss-px-to-viewport ，此套件可以自動將 px 轉換為 vw 或是 vh ，設定上可以依據你所參照的視窗大小來設定轉換比率。

2. #### preprocessorOptions
這是 css 的預處理器，可根據使用的 css 框架設定不同的預處理，最常使用的為設定全域參數，設定方式如下：
```typescript=
      preprocessorOptions: {
        scss: {
          additionalData: `key:"value";
        }
      }
```
註：除了可設定單一參數以外，還能直接讀取整包文件

* ### server
此為架構本地 server 設定，共可做到設定 port 號、hmr 熱更新、http/https 設定、轉 proxy、跨域設定等，設定方式如下：
```typescript=
server: {
  port: 8080, //port 號
  strictPort: true,  //是否單一port號，若為false可自動開啟別的port
  open: false, //啟動後是否自動開啟頁面
  hmr: true, // 是否開啟熱更新
  https: false, //是否是https
  cors: true, // 允许跨域
  proxy: {
    "api路徑": {
      target: 後端domain + "/api",
      changeOrigin: true, //是否自動轉換
      ws: false, //是否開啟webSocket
      rewrite: (path) => path.replace(預取代的api路徑, "")
    }
  }
}
```

* ### build
設定打包規則與壓縮方式，打包方式的切檔規則會影響到網頁讀取速度，寫法如下：
```typescript=
    build: {
      target: "es2015", //打包檔案的瀏覽器兼容目標
      minify: "terser", // 是否進行壓縮,boolean | 'terser' | 'esbuild',默认使用terser
      manifest: false, // 是否產出maifest.json
      sourcemap: false, // 是否產出soucemap.json
      outDir: "dist", // 資料夾名稱
      assetsDir: "static", //js css資料夾名稱
      terserOptions: {
        ie8: true  //是否支援ie8
      },
      rollupOptions: {
        input: { //index頁
          index: resolve(__dirname, "index.html")
        },
        output: {
          manualChunks: (id) => {
              //此處將 node_modules 內的套件與主程式切開打包
            if (id.includes("node_modules")) {
              return id.toString().split("node_modules/")[1].split("/")[0].toString();
            }
          },
          chunkFileNames: (chunkInfo) => {
            let modules = [
                //套件名稱
            ];
            if (modules.some((m) => m === chunkInfo.name)) {
                //將對應到的套件轉名稱
              return "static/js/vendor-[hash].js";
            } else {
              return "static/js/[name]-[hash].js";
            }
          },
              //js 入口檔案
          entryFileNames: `static/js/[name]-${indexRandom}.js`,
              //js、css 編譯檔名規則
          assetFileNames: "static/[ext]/[name]-[hash].[ext]"
        }
      }
    }
```
打包設定檔撰寫並不難，但卻影響深遠，寫的好可避免許多額外的麻煩，並可以讓開發上快速許多。