sroxck

sroxck

記錄一下 vite-wide 專案搭建經驗

搭建一個包含 admin 後台管理系統和 web 前端展示系統,各自獨立使用 Vite 構建,僅共享公共組件和方法。項目支持在全局配置之外單獨設置各自的 Vite 配置和插件,各項目會單獨打包,Vite 會根據引入依賴與公共資源按需構建。

需求整理#

需求就是在一個項目中管理 admin 後台管理系統和 web 前端展示系統,他們各自獨立,可以使用 shared 包中的內容,打包的時候各自打包,並且支持 tree shaking。

Why Not?#

為什麼不使用 pages 方案?#

  1. 構建臃腫pages 方案通常會將所有頁面和組件以及依賴項都打包在一起,如 admin 和 web 最終都會打包成一個 bundle, 導致最終構建的文件體積較大,影響加載速度。

    這個項目通過 Tree Shaking 的方式,確保各自項目只引入實際使用的資源和依賴,優化了打包體積。

  2. 靈活性不足:使用 pages 方案時,項目結構與配置往往固定,只能使用統一的配置,難以靈活調整。

    這個項目支持獨立的配置和插件管理,開發者可以根據需求自由調整項目結構和構建配置。每個模塊都是一個單獨的 Vite 項目。

  3. 運維複雜性pages 方案需要額外的運維配合。

    這個項目僅僅是單獨根據變更文件的目錄觸發部署而已。

為什麼不使用 Monorepo 方案?#

  1. 項目複雜性:Monorepo 方案適合大型項目,但對於小型或中型項目來說,管理多個包的複雜性可能會導致開發效率下降。

    這個項目提供了獨立的模塊管理,避免了不必要的複雜性。

  2. 構建時間:在 Monorepo 中,可能需要每次都構建整個倉庫,即使只修改了一個模塊。這會導致構建時間增加。

    這個項目支持按需構建,能夠快速響應開發需求。

  3. 依賴管理:Monorepo 方案需要精細管理各個模塊之間的依賴關係,可能會增加維護成本。

    這個項目通過共享目錄和獨立配置,簡化了依賴管理。

項目搭建#

項目目錄如下
dir

tsconfig 如下

// [tsconfig.json]
{
  "files": [],
  "compilerOptions": {
    "module": "NodeNext"
  },
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ]
}
// [tsconfig.node.json]
{
  "extends": "@tsconfig/node20/tsconfig.json",
  "include": [
    "vite.config.*",
    "vitest.config.*",
    "cypress.config.*",
    "nightwatch.conf.*",
    "playwright.config.*"
  ],
  "compilerOptions": {
    "composite": true,
    "noEmit": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",

    "module": "ESNext",
    "moduleResolution": "Bundler",
    "types": ["node"]
  }
}
// [tsconfig.app.json]
{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "include": [
    "env.d.ts",
    "packages/**/*",
    "packages/**/*.vue",
    "packages/**/*.tsx",
    "./config.global.ts"
  ],
  "exclude": ["packages/**/__tests__/*"],
  "compilerOptions": {
    "allowImportingTsExtensions": true,
    "composite": true,
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "baseUrl": ".",
    "paths": {
      "@shared/*": ["./packages/shared/*"]
    }
  }
}

config 如下

// [config.global.ts]
import path from "path";
import { plugins } from "./plugins";
export const sharedConfig = {
  commonPlugins: [...plugins],
  resolve: {
    alias: {
      "@shared": path.resolve(__dirname, "./packages/shared"),
    },
  },
};
// [plugins/index.ts]
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import vue from "@vitejs/plugin-vue";
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
import { PluginOption } from "vite";
import vueJsx from "@vitejs/plugin-vue-jsx";
export const plugins: PluginOption[] = [
  vue(),
  vueJsx(),
  AutoImport({
    resolvers: [ElementPlusResolver()],
  }),
  Components({
    resolvers: [ElementPlusResolver()],
  }),
];
// [web/vite.config.ts]
import { defineConfig } from "vite";
import path from "path";
import { sharedConfig } from "../../config.global.ts";
const { commonPlugins, ...commonConfig } = sharedConfig;
export default defineConfig({
  plugins: [...commonPlugins],
  root: path.resolve(__dirname),
  ...commonConfig,
});
// [admin/vite.config.ts]
import { defineConfig } from "vite";
import path from "path";
import { sharedConfig } from "../../config.global.ts";
const { commonPlugins, ...commonConfig } = sharedConfig;
export default defineConfig({
  plugins: [...commonPlugins],
  root: path.resolve(__dirname),
  ...commonConfig,
});

類型支持#

統一配置,多模塊使用,項目提供完整且結構清晰的類型支持,包括 tsx,vine,macros 的類型支持,任意模塊中的 sfc 組件,純函數組件以及 tsx 組件都會得到完全的類型支持,包含自動的 props 和 emits 的類型強校驗以及 ref 實例類型支持。

問題彙總#

  1. 配置問題
    解決方案是 各自擁有各自的 vite 配置,然後根目錄配置統一的 vite 配置,各自可以設置各自獨立的配置。

  2. ts 類型問題
    解決方案是 使用統一的 tsconfig, 將各自的 tsconfig 刪除,使用 create-vue 的 tsconfig (直接拿過來,依賴按照 create-vue 的 package 安裝)。

  3. tsx 支持
    在 create vue 中使用 tsx 默認就支持了 需要注意的是 在 tsconfig 中的 include 將 admin 和 web 都包裹,不過最佳解決方案是 創建一個 packages 目錄 將 admin 和 web 和 shared 都放到 packages 目錄下,include 字段只包含這個目錄就可以了,不過要把統一的 vite 配置文件包裹。

  4. 公共組件類型問題
    在 tsconfig 中配置 paths 字段 在 compilerOptions 中配置 paths 如下

 "paths": {
      "@shared/*": ["./packages/shared/*"]
  }

目錄結構#

packages 目錄#

packages 為項目模塊目錄,包含以下內容:

  • admin:後台管理系統,使用 Vite 構建。

  • web:前端展示系統,使用 Vite 構建。

  • shared:公共目錄,存放共享的組件、方法,供 adminweb 系統使用。

plugins 目錄#

plugins 為集中管理 Vite 插件的目錄。自定義插件與第三方插件通過統一的入口文件 index.ts 導出 plugins 對象,方便統一管理和使用。

自定義插件規範

  1. 插件命名:使用小寫字母,單詞間用短橫線分隔(例如:my-custom-plugin)。
  2. 插件結構:每個插件應包含 install 方法,用於在 Vite 中註冊插件。
  3. 文檔說明:每個插件應附帶使用示例和配置說明,以便其他開發者理解和使用。

scripts 目錄#

scripts 目錄包含項目構建腳本和其他任務腳本,主要用於自動化構建、測試和部署等任務。具體腳本可以根據需要添加。

types 目錄#

types 目錄用於存放 TypeScript 類型聲明文件 .d.ts。可以在此目錄中添加全局類型模塊聲明,以供整個項目使用。

config 目錄#

config 目錄存放項目的全局配置文件,包含 Vite 配置、環境變量和其他相關設置。可根據不同的環境(開發、測試、生成)進行相應的配置。

此文由 Mix Space 同步更新至 xLog 原始鏈接為 http://www.sroxck.top/posts/note/wide

載入中......
此文章數據所有權由區塊鏈加密技術和智能合約保障僅歸創作者所有。