搭建一個包含 admin 後台管理系統和 web 前端展示系統,各自獨立使用 Vite 構建,僅共享公共組件和方法。項目支持在全局配置之外單獨設置各自的 Vite 配置和插件,各項目會單獨打包,Vite 會根據引入依賴與公共資源按需構建。
需求整理#
需求就是在一個項目中管理 admin 後台管理系統和 web 前端展示系統,他們各自獨立,可以使用 shared 包中的內容,打包的時候各自打包,並且支持 tree shaking。
Why Not?#
為什麼不使用 pages
方案?#
-
構建臃腫:
pages
方案通常會將所有頁面和組件以及依賴項都打包在一起,如 admin 和 web 最終都會打包成一個 bundle, 導致最終構建的文件體積較大,影響加載速度。這個項目通過 Tree Shaking 的方式,確保各自項目只引入實際使用的資源和依賴,優化了打包體積。
-
靈活性不足:使用
pages
方案時,項目結構與配置往往固定,只能使用統一的配置,難以靈活調整。這個項目支持獨立的配置和插件管理,開發者可以根據需求自由調整項目結構和構建配置。每個模塊都是一個單獨的 Vite 項目。
-
運維複雜性:
pages
方案需要額外的運維配合。這個項目僅僅是單獨根據變更文件的目錄觸發部署而已。
為什麼不使用 Monorepo 方案?#
-
項目複雜性:Monorepo 方案適合大型項目,但對於小型或中型項目來說,管理多個包的複雜性可能會導致開發效率下降。
這個項目提供了獨立的模塊管理,避免了不必要的複雜性。
-
構建時間:在 Monorepo 中,可能需要每次都構建整個倉庫,即使只修改了一個模塊。這會導致構建時間增加。
這個項目支持按需構建,能夠快速響應開發需求。
-
依賴管理:Monorepo 方案需要精細管理各個模塊之間的依賴關係,可能會增加維護成本。
這個項目通過共享目錄和獨立配置,簡化了依賴管理。
項目搭建#
項目目錄如下
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 實例類型支持。
問題彙總#
-
配置問題
解決方案是 各自擁有各自的 vite 配置,然後根目錄配置統一的 vite 配置,各自可以設置各自獨立的配置。 -
ts 類型問題
解決方案是 使用統一的 tsconfig, 將各自的 tsconfig 刪除,使用 create-vue 的 tsconfig (直接拿過來,依賴按照 create-vue 的 package 安裝)。 -
tsx 支持
在 create vue 中使用 tsx 默認就支持了 需要注意的是 在 tsconfig 中的 include 將 admin 和 web 都包裹,不過最佳解決方案是 創建一個 packages 目錄 將 admin 和 web 和 shared 都放到 packages 目錄下,include 字段只包含這個目錄就可以了,不過要把統一的 vite 配置文件包裹。 -
公共組件類型問題
在 tsconfig 中配置 paths 字段 在 compilerOptions 中配置 paths 如下
"paths": {
"@shared/*": ["./packages/shared/*"]
}
目錄結構#
packages 目錄#
packages
為項目模塊目錄,包含以下內容:
-
admin:後台管理系統,使用 Vite 構建。
-
web:前端展示系統,使用 Vite 構建。
-
shared:公共目錄,存放共享的組件、方法,供
admin
和web
系統使用。
plugins 目錄#
plugins
為集中管理 Vite 插件的目錄。自定義插件與第三方插件通過統一的入口文件 index.ts
導出 plugins
對象,方便統一管理和使用。
自定義插件規範
- 插件命名:使用小寫字母,單詞間用短橫線分隔(例如:
my-custom-plugin
)。 - 插件結構:每個插件應包含
install
方法,用於在 Vite 中註冊插件。 - 文檔說明:每個插件應附帶使用示例和配置說明,以便其他開發者理解和使用。
scripts 目錄#
scripts
目錄包含項目構建腳本和其他任務腳本,主要用於自動化構建、測試和部署等任務。具體腳本可以根據需要添加。
types 目錄#
types
目錄用於存放 TypeScript 類型聲明文件 .d.ts
。可以在此目錄中添加全局類型模塊聲明,以供整個項目使用。
config 目錄#
config
目錄存放項目的全局配置文件,包含 Vite 配置、環境變量和其他相關設置。可根據不同的環境(開發、測試、生成)進行相應的配置。
此文由 Mix Space 同步更新至 xLog 原始鏈接為 http://www.sroxck.top/posts/note/wide