前端項目目錄結構演變

在工做過程當中隨着咱們的業務愈來愈龐大,對於項目的管理和維護帶來必定的難度,特別是團隊中的人員存在異常變更的時候,就會出現一些問題,項目中的問題就會出現浮現出來,可能其餘人寫的代碼在添加需求或者更改需求的時候須要調整的時候,不知道該從哪裏開始入手。javascript

其實對於一個團隊來講一個良好的項目結構和編程習慣不管對於團隊仍是我的來講都是一個很大的成長。這裏就簡單的說在公司工做進三年的時間公司項目的目錄結構是如何不斷迭代的。其中也作了很大的改變。html

咱們公司不管前端仍是後端都是使用的是微服務進行架構的,爲了減低項目與項目之間的依賴性。在團隊建立初期公司已經有了目錄結構的雛形,畢竟團隊剛剛成立沒有多久。前端部分主要採用的是先在較爲流行的Vue,本文對於目錄結構的演變一樣也是針對Vue項目進行延申的。前端

目錄結構雛形

在最開始建立項目初期作項目的時候整個項目狀況仍是很糟糕的,數據請求都是寫在**.vue文件中去請求,項目總體沒有統一的規劃,致使項目一旦某些內容發生改變的時候,頗有可能致使牽一髮而動全身。對於項目的維護來講簡直能夠用一塌糊塗來形容。vue

然而爲了解決這些問題,因此對目錄結構進行了第一次規劃,其實此次對於目錄規劃主要參考了Vuex官網中的推薦的目錄結構。java

├─src               //  項目目錄
│  ├─api                //  數據請求
│  ├─assets             //  資源
│  │  ├─baseData            //  靜態數據
│  │  └─images              //  較小圖片資源
│  ├─components         //  組件
│  │    ├─base              //  基礎組件
│  │    └─business          //  業務組件
│  ├─routes             //  路由
│  ├─mixins             //  混入
│  ├─store              //  狀態管理
│  ├─style              //  樣式
│  ├─views              //  頁面
│  ├─utils              //  工具
│  └─main.js            //  入口文件
└─static            //  靜態資源

這種項目結構來講算是單頁面中比較中規中矩的了,每一個文件夾中都本身作了本身的事情,對於總體項目的維護也相對來講變得容易了一些。es6

  1. api:主要負責提供數據請求的方法
  2. assets:提供業務中所須要的數據資源以及較小的圖片資源,vue-cli會把較小的圖片編譯成base64
  3. components:承載了業務中全部須要用到的組件,使用basebusiness對基礎組件進一步劃分
  4. routes:編寫路由結構
  5. mixins:公用代碼的混入
  6. store:頁面中的狀態管理
  7. style:頁面和組件樣式
  8. views:存放頁面
  9. utils:頁面或組件中所須要用到的工具,以及對於其餘第三方工具的二次封裝
  10. main.js:程序的入口文件
  11. static:較大的靜態資源文件

image

雖然經過上面的對於項目進行了調整可是隨着業務的發展項目仍是會越亂,亂的地方出如今哪裏?web

  • 第一點,全部頁面的業務組件全都存放在了一塊兒,查找起來不是特別的方便
  • 第二點,全部頁面都存放在了views中,好比用戶管理可能會有用戶詳情,修改,新增,然而這些又和其餘的業務頁面存放在了一塊兒
  • 第三點,就是router裏面的內容業務越多,業務就越龐大,這對於項目來講也是一個很大的負擔

其實對於上述問題都不是什麼特別大的問題,均可以使用文件或者文件夾來進行拆分使每一部分業務都作到相對的獨立。vue-cli

改進

在進行以前作了很大的考慮,首先就是各個模塊之間的存放問題,雖然使用文件夾進行劃分能夠解決這部分問題,可是隨之帶來的是,就是資源加載問題,好比A模塊中不須要用的router,可是須要用store,可是B模塊又須要用到router,不須要用到store,然而這就在加載頁面資源的時候相對的會加載一些不須要的資源。通過反覆的嘗試,最後使用多頁面與單頁面相結合的形式。只在須要用到的某些資源的時候纔會在vue實例中使用其對應的資源。編程

├─src                   //  項目目錄
│  ├─api                    //  數據請求
│  ├─assets                 //  靜態資源
│  │  ├─baseData                //  靜態數據
│  │  └─images                  //  較小圖片資源
│  ├─component              //  業務組件
│  ├─domain                 //  業務頁面
│  ├─mixins                 //  混入
│  ├─instance               //  頁面實例
│  ├─middleware             //  中間件
│  ├─publicComponents       //  公用組件
│  │    ├─base                  //  公用基礎組件
│  │    └─business              //  公用業務組件
│  ├─routes                 //  路由
│  ├─views                  //  頁面
│  ├─store                  //  狀態管理
│  ├─styles                 //  樣式
│  └─utils                  //  工具
└─static                //  靜態資源

經過上面的目錄結構的調整,整個項目中的內容變得更加的清晰了。加入domain主要是想要達到頁面的表現和業務的邏輯相互分開,對於業務的處理放到domain中進行處理。後端

爲了節約篇幅只說明改動文件做用

  1. component:只存放頁面中所依賴的業務組件,文件夾內部使用文件夾對頁面與頁面的劃分
  2. domain:用於處理業務部分,好比數據提交前的處理,數據請求前的數據處理
  3. instance:頁面的實例,多頁面全部,內部使用文件夾對頁面進行劃分
  4. middleware:Vue實例中通用的中間件,內部使用兩個文件夾進行拆分,分別是middleware.style.jsmiddleware.javascript.js
  5. publicComponents:全部頁面公用的組件,文件夾內部分爲basebusiness對業務組件和基礎組件進一步劃分

這裏有一點須要注意的是,對於instanceroutes的理解和認知,instance是以業務模塊爲單位,然而routes是一模塊功能爲單位的。舉個栗子,instance中所劃分的是業務A的相關內容,可是這部分業務不多,只有一個頁面,那麼這個時候就不須要用到routes業務B內容則不少那麼就須要使用routes對其中的內容進一步的劃分。

說白了instance的做用就是,對業務與業務之間的劃分,使兩個業務雖然在同一個項目中也作了劃分處理。然而routes則是在業務的基礎上進行了二次劃分。本該屬於該業務的只在該業務模塊所管轄範圍內進行處理。

image

在系統的開發過程當中隨着項目中的內容日益的增多,會廣泛的帶來一個很大的問題,當views中的文件業務特別多的時候就須要在頁面中定義不少不少的方法,以及對於業務的處理。當去修改代碼的使用,那感受簡直不要太爽,一個文件上前行代碼,並且方法相互之間的依賴性誰都離不開誰,哈哈哈,這感受太香了。並且在開發過程當中,寫個函數須要頻繁的上下滾動。爲了解決這個問題最後考慮到頁面中的內容較多的問題,爲了實現,結構和行爲相脫離使用混入的形式。

在混入文件中添加對頁面業務的混入,views文件中JavaScript根據頁面中的業務放到對應的***.js文件中,減小頁面中的業務處理的js代碼。在調整以後須要在miaxins中去引入domain文件了。

最終版本

爲了實現結構與表現的分離,上面雖然使用混入間接的解決了這個問題,可是違背了混入的最初的用意,長此以往這也不是什麼長久之計,仍是須要對內部進行調整,在沒有出現domain以前,所有都是寫在***.vue中,那麼可不能夠直接提取這部份內容直接注入到頁面中呢?通過嘗試是能夠的,那麼抽離的這部分也就是JavaScript仍然仍是很臃腫。

其實domain不但控制了頁面仍是控制了行爲,對domain的內容進行分解分爲controllerservice頁面表現所有都放入controller統一處理和管理,service則負責單個業務的處理和頁面數據的管理。

這裏對Vue腳手架進行了升級,使用了Vue3.0腳手架。

├─api                   //  數據請求
├─assets                //  靜態資源
├─components            //  組件
├─controllers           //  控制層
├─instance              //  頁面實例
├─middleware            //  中間件
├─mixins                //  混入
├─publicComponents      //  公共組件
│  ├─base                   //  基礎組件
│  └─basic                  //  業務組件
├─routers               //  路由
├─services              //  業務處理
├─style                 //  樣式
└─views                 //  頁面結構

前端同窗應該都知道前端經過結構(HTML),表現(Style),行爲(JavaScript)來完成整個頁面的,然而此次的調整是對原有domain的二次劃分,使整個頁面結構、樣式、行爲脫離。

image

可能有的同窗會問,那麼servicecontrollerview他們之間是如何關聯在一塊兒的呢?其實這裏使用的es6class在頁面建立的時候把controller和相關service引入到頁面中,在頁面建立時,同時建立controller,在controller實例化的時候把service以參數的形式注入到controller中。

爲何要這樣設計,當某一部分業務須要暫時調整的時候就能夠直接再建立一個新的類注入進去便可,不須要更改原有代碼,當業務須要變動回來的時候,直接要更換一下注入進去的service便可。

test.vue

<template>
    <div>
        <p>{{controller.pageService.page}}</p>
        <p>{{controller.pageService.size}}</p>
    </div>
</template>

<script>
import TestController from "@/controllers/test/view/TestController";
import TestService from '@/services/test/view/TestService';

export default {
    data:() => ({
        controller: new TestController(
            new TestService();
        )
    })
}
</script>

TestController.js

export default class TestController {
    constructor(pageService){
      this.pageService = pageService;
    }
}

TestService.js

export default class TestService {
    constructor(){
        this.page = 1;
        this.size = 20;
    }
}

經過對domain的拆分以後項目總體來講不管是對頁面的調整仍是拓展都變得更加的容易的了,不管業務怎麼變動,即便是換套業務邏輯也不須要更改原來的代碼只須要調整注入進去的實例便可。目前來講仍是蠻香滴。

總結

本文記錄一下對於項目結構的總體調整以及考慮,主要目的爲了達到總體結構、表現、行爲的相對脫離。經過對目錄結構的調整,對於總體項目的維護與拓展有了更高的可控性。

文章略有潦草,如有什麼問題請在文章下面留言。針對其業務單獨寫了腳手架qj-web-cli歡迎你們下載。

相關文章
相關標籤/搜索