1. 程式人生 > >[Vue 牛刀小試]:第十七章 - 優化 Vue CLI 3 構建的前端專案模板(1)- 基礎專案模板介紹

[Vue 牛刀小試]:第十七章 - 優化 Vue CLI 3 構建的前端專案模板(1)- 基礎專案模板介紹

 一、前言

  在上一章中,我們開始通過 Vue CLI 去搭建屬於自己的前端 Vue 專案模板,就像我們 .NET 程式設計師在使用 asp.net core 時一樣,我們更多的會在框架基礎上按照自己的開發習慣進行調整。因此在後面幾章的學習中,我將會在整個專案基礎上,按照自己的需求進行修改設定。

  PS:因為畢竟自己還是傳統意義上的後端開發,所以這裡最終搭建完成的前端專案模板,其實是按照 PanJiaChen 開源的 vue-admin-template 模板進行修改仿寫,所以你可以把這個系列後續的文章當成是對於 vue-admin-template 模板的使用資料補充。

  系列目錄地址:https://www.cnblogs.com/danvic712/p/9549100.html

  倉儲地址:https://github.com/Lanesra712/ingos-web

 二、乾貨合集

  在調整專案模板前,我們首先還是先來了解下我們通過 Vue CLI 3 所搭建的這個基於 Element UI 的專案模板,整個模板的檔案結構及相關解釋說明如下所示。

|-- ingos.web
  |-- node_modules          	// 專案所引用的前端元件包
  |-- public                	// 專案釋出後打包後的目錄地址
    |-- favicon.ico       	
    |-- index.html        	
    |-- src                   	// 專案原始檔路徑
      |-- assets            	// 靜態存放路徑
        |-- logo.png      	
      |-- components        	// 專案中定義的元件存放路徑
        |-- HelloWorld.vue	
      |-- plugins               // 專案中引用到的第三方 Vue CLI 外掛所在路徑
        |-- element.js	
      |-- views             	// 專案中檢視所在路徑
        |-- About.vue
        |-- Home.vue
      |-- App.vue           	// 專案的主元件,專案中的頁面都是在此進行路由切換
      |-- main.js           	// 主入口檔案,初始化 Vue 例項並使用載入專案中需要使用的外掛
      |-- router.js         	// 專案中所有的路由定義
      |-- store.js  
    |-- tests                   // 單元測試檔案路徑
      |-- units                 // 存放單元測試用例
        |-- .eslintrc.js      	
        |-- example.spec.js
  |-- .browserslistrc           // 指定專案的目標瀏覽器的範圍
  |-- .editorconfig             // 針對不同的編輯器和 IDE 之間對於程式碼風格的設定
  |-- .eslintrc.js              // eslint 的配置檔案
  |-- .gitignore                // git 忽略新增的檔案
  |-- babel.config.js           // Babel 規則配置檔案
  |-- package-lock.json         // 記錄安裝包的具體版本號
  |-- package.json              // 專案載入的元件包
  |-- postcss.config.js         // 針對 postcss 的配置
  |-- README.md                 // 專案 readme 檔案

  1、原始程式碼結構瞭解

  1.1、webpack 的基礎概念

  因為很多這個系列的讀者童鞋可能和我一樣,就是傳統意義上的後端開發,在之前完全沒有接觸過這種進行前端工程化的開發模式,所以這裡我會針對專案的基礎模板進行一個簡單的說明,如果存在不對的地方,歡迎在評論區指出。

  整個專案雖然是通過 Vue CLI 進行搭建的,但是因為 Vue CLI 其實也是基於 webpack 進行構建的,所以這個專案的本質上其實是個 vue.js + webpack 專案,因此在後面的使用中會涉及到很多 webpack 的相關知識點。作為目前最主流的前端構建工具,webpack 本身的知識點會很多,所以這裡只是對使用到的相關知識點進行一個簡單的概述,不會詳細的介紹,後續如果有使用到的時候也會進行補充。

  在前端專案開發中,我們可能會引入很多的 css、js、fonts、imgs 或是其它的靜態檔案到頁面中,當一個頁面引入了很多的靜態檔案時,為了載入這些靜態資源,網頁會發起很多個二次請求,從而導致頁面的載入變慢。同時,我們在使用前端框架時,經常會存在很多的依賴關係,並且由於 javascript 是一個弱型別的語言,無法在程式碼編寫時很快速的定位到框架間的依賴問題。

  webpack 則可以很好的幫我們解決這些問題。

  webpack 是一個前端應用程式的靜態模組打包工具,它是基於 node.js 進行開發的,所以在使用前我們需要安裝 node.js。它可以幫我們實現對於網站所引用的靜態資源進行打包、壓縮、混淆;幫我們解決 js、css 中可能存在的依賴關係;將同類型的靜態資源打包合併成一個檔案,並對生成的程式碼進行混淆,以增加線上程式碼的安全性。

  1.2、Vue 的單檔案元件

  當我們簡單瞭解了專案的框架基礎後,我們可以從一些之前我們沒有接觸過的檔案去入手,去逐漸瞭解整個前端專案。在專案檔案中我們可以看到一些以 .vue 結尾的檔案,一個基礎的 vue 檔案包含了下面所示的三部分。

<template>
  <p>{{ greeting }} World!</p>
</template>

<script>
module.exports = {
  data: function () {
    return {
      greeting: 'Hello'
    }
  }
}
</script>

<style scoped>
p {
  font-size: 2em;
  text-align: center;
}
</style>

  可以看到,與我們 .NET 程式設計師使用的 asp.net core mvc 框架中的檢視對應的 cshtml 檔案很相似,它們都是在 html 檔案的基礎上進行了擴充套件。就像在 razor 頁面上(.cshtml)我們可以將 C# 程式碼嵌入到 html 程式碼中,並且可以得到 IDE 的程式碼提示一樣,在 .vue 檔案中,我們也可以將很多 Vue 的特性新增到 html 程式碼中,並可以得到很好的語法支援和程式碼高亮。、

  在 Vue 專案中,我們一般將一個 .vue 檔案作為一個元件。當然,瀏覽器是不能直接解析 cshtml、vue 這類特殊字尾的檔案的,所以這裡我們在使用 Vue CLI 建立專案時,腳手架已經幫我們安裝了 Vue Loader 這個 webpack loader,從而幫助我們將 .vue 檔案轉換成瀏覽器能直接識別的 html、css、javascript 檔案。

  webpack 的 loader 可以在我們 import 或載入模組時進行檔案的預處理,完成對引入模組的原始碼進行指定格式的轉換。例如像這個專案一樣,我們需要把 sass 檔案轉變成 css 檔案,所以這裡我們就需要在專案中新增對於 sass-loader 的引用。

  亦或者,你可能在前端專案開發中會使用到 typescript,而到專案最終執行時,我們需要將 typescript 程式碼轉換成 javascript 程式碼,這時,我們就需要在專案中新增 ts-loader 從而讓 webpack 自動幫我們完成從 typescript 程式碼到 javascript 的轉換。

  從專案資料夾的檔案分層結構可以看出,src 是專案原始碼的存放路徑,路徑下已經存在的 assets、components、plugins、views 這幾個資料夾,我們還是按照模板的原意存放對應的檔案。對於單獨的檔案,我們來一個個的解釋具體的作用。而 tests 資料夾下存放的是單元測試的測試用例,這裡就不具體解釋了。

  1.3、對於 App.Vue 的解釋

  App.vue:專案的入口元件,這裡我們會對程式碼進行一個簡單的調整,最終整個專案中編寫的 Vue 元件我們都會通過 vue router 匯出到這個元件上,修改後的程式碼如下所示。

<template>
  <div id="app">
    <router-view />
  </div>
</template>

<script>
export default {
  name: 'App',
};

</script>

<style>
  body {
    height: 100%;
    font-size: 14px;
    -moz-osx-font-smoothing: grayscale;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    font-family: Helvetica Neue, Helvetica, PingFang SC,
      Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif;
  }

  * {
    margin: 0;
    padding: 0;
  }

</style>

  1.4、對於 main.js 的解釋

  從名字上就可以看出,就像是 asp.net core 專案中的入口函式,這個 js 是整個 vue 專案的入口。我們在上面調整 App.vue 時有介紹到,最後編寫好的 Vue 程式碼都會匯出到 App.vue 檔案上進行顯示。在使用 Vue 時,我們是需要將構造好的 Vue 例項掛載到 dom 元素上的,從下面的程式碼中就可以看出,將 Vue 例項掛載到 dom 元素上的操作其實就是在這個檔案中進行的。在程式碼中,通過引用 Element UI、Vue Router、Vuex,並將這些元件掛載到 Vue 例項上,並最終渲染到繫結的頁面 dom 元素上。

import Vue from 'vue';
import App from './App.vue';
import router from './routers/router';
import store from './stores/store';
import './plugins/element';

Vue.config.productionTip = false;

new Vue({
  router,
  store,
  render: h => h(App),
}).$mount('#app');

  可能你會有疑問,這裡最終掛載的 dom 元素是在什麼地方定義的呢?對於單頁面應用來說,因為整個專案中其實只會有唯一的一個 html 頁面,所以我們直接在專案中去尋找 html 頁面就可以了。對於通過 Vue CLI 構建出來的專案,我們最終是將 Vue 掛載到 public 資料夾下面的 index.html 上。

  1.5、對於 router.js 的解釋

  這個檔案定義了我們整個專案的前端路由資訊,因為如果將整個專案中所有的路由都配置到這一個 js 檔案中,這個檔案肯定會變得很龐大和不好維護,所以在後面我會新增一個 routers 資料夾去專門存放我們的前端路由資訊,而原有的 router.js 檔案則會起到一個匯出前端路由的作用。

  1.6、對於 store.js 的解釋

  因為在使用 Vue CLI 建立專案時,我們添加了在 Vue 中專門針對狀態管理的外掛 Vuex,所以這個 js 檔案就是針對 Vuex 的一些配置,這裡我也會在後面專門新增一個 stores 資料夾去存放專案中使用到的狀態相關資料。

  基礎專案的 src 資料夾下就是上面提到的這些內容,接下來我會按照自己的需求去新增一些資料夾去分類存放我們在後續專案開發中可能會使用到的東西。

  2、自定義調整

  2.1、專案基礎調整

  在上面有提到,我會建立一個 routers 資料夾去專門儲存專案的前端路由資訊,因為作為一個需要進行前後端資料互動的專案,所以這裡我建立了一個 apis 資料夾去專門存放檢視元件中需要進行後端資料訪問的 js 程式碼。

  對於 apis、routers 這兩個資料夾的結構,這裡與存放檢視的 views 下的結構大體是保持一致的,例如這裡 views 下面有個 home 去存放網站首頁相關的檢視元件,對應的路由資訊就會放在 routers 下的 home 資料夾中;同時,因為我們需要和後端進行資料互動,所以這裡一些請求後端的方法會按照檢視的結構存放在對應的 apis 資料夾下,分層後的程式碼結構如下圖所示。

  在這個專案中,對於專案中的檢視元件我會存放到 views 資料夾下,不過對於專案網站佈局的檢視元件,這裡我建立了一個 layouts 資料夾,去專門存放網站佈局相關的檢視元件檔案。

  同樣的,對於一些我們自定義的樣式檔案,這裡我會建立一個 styles 資料夾去存放這些樣式檔案;同時,對於一些基礎的通用方法,這裡我會放在新建的 utils 資料夾下,例如這裡會存放我們基於 axios 進行封裝的 http 請求方法。

  在某些時候,我們的網站可能會存在一些的全域性設定,例如設定側邊欄是否固定,是否顯示 logo 等等,對於這些基礎的設定項屬性,這裡我都會存放在 setting.js 檔案中,一些簡單的設定項如下所示。

module.exports = {
  /**
   * @type {string}
   * @description 網站預設的 title 資訊
   */
  title: 'ingos web template',

  /**
     * @type {boolean} true or false
     * @description 是否固定網站的 header 
     */
  fixedHeader: false,

  /**
   * @type {boolean} true or false
   * @description 是否顯示側邊欄的 logo
   */
  sidebarLogo: false,
};

  2.2、瀏覽器相容性調整

  在做 web 專案時,如何做到對於主流瀏覽器的支援,是一個龐大的工作量,如果此時還需要相容某些上古時代的瀏覽器,更是災難,嗯,說的就是你,IE6。因為需要針對一些不同的瀏覽器確定需要轉譯的 JavaScript 特性和新增對應的 CSS 瀏覽器字首,如果我們還是採取手動的方式進行編寫,工作量勢必會很大。

  而在通過 Vue CLI 構建的專案中,我們可以通過 .browserslist 檔案來指明當前這個專案的目標瀏覽器範圍,然後這個值會被通過 webpack 載入的 @babel/preset-env 和 Autoprefixer 用來確定需要那些 js 程式碼是需要進行轉譯的以及需要新增那些 CSS 瀏覽器字首。

  例如在這個專案中,我們宣告專案的目標瀏覽器範圍是全球使用率大於 1% 的瀏覽器的最新兩個版本,具體的宣告語法這裡就不詳細介紹了,你可以通過點選這個連結去了解如何指定瀏覽器範圍(電梯直達),這裡我們可以直接在工程目錄下執行下面的命令來檢視符合我們配置的條件而篩選出的瀏覽器版本範圍。

npx browserslist

  確定了目標瀏覽器後,我們就需要對使用的 js 程式碼和 css 程式碼進行一個設定,從而使支援的瀏覽器可以正常顯示出。有些時候,我們寫的某些 js 程式碼可能是符合 ES6 語法的,對於某些瀏覽器來說可能是不支援的,這時我們就可以通過 Babel 和 browserslist 進行結合,將我們使用到的 ECMAScript 2015+ 版本的程式碼轉換為向後相容的 JavaScript 語法,以便能夠執行在當前和舊版本的瀏覽器或其他環境中。

module.exports = {
  presets: [
    '@vue/app',
  ],
};

  針對 js 程式碼的轉換可以使用到 Babel,那麼對於同樣可能出現瀏覽器不相容的 css 樣式,這裡我們就可以通過使用 postcss + Autoprefixer + browserslist 識別出需要指定支援的瀏覽器型別和版本,自動新增所需的帶字首的屬性宣告。

  PostCSS 本身是一個功能比較單一的工具,它一般會和 webpack、gulp 這種前端構建工具進行結合使用,通過使用 postcss 可以支援變數和混入(mixin),增加瀏覽器相關的宣告字首,或是把使用將來的 CSS 規範的樣式規則轉譯(transpile)成當前的 CSS 規範支援的格式。

#content {
 display: flex;
}

  而 Autoprefixer 的作用就是為 CSS 中的屬性新增瀏覽器特定的字首,例如上面的程式碼,使用了 flex 的佈局模式,在經過 Autoprefixer 處理之後得到的 CSS 程式碼則如下所示。

#content {
 display: -webkit-box;
 display: -webkit-flex;
 display: -ms-flexbox;
 display: flex;
} 

  2.3、程式碼風格的設定

  在前端專案開發中,因為對於編輯器或是使用的作業系統不會有太嚴格的限定,例如這裡我是使用 VS Code 在 Windows 10 上進行開發的,你完全可以選擇 Atom + MacOS 或是 VS Code + Ubuntu 等等組合去開啟我的這個專案,然後去進行開發,而不同的編輯器和作業系統對程式碼的展示會有些許的差異,所以這裡我們就需要對專案的程式碼規範進行一個設定。

  針對不同編輯器的風格設定,這裡使用的是 editorconfig,我們可以在 .editorconfig 檔案中去設定專案規範,編輯器通過載入 editorconfig 外掛之後,就可以通過讀取這個配置檔案,來覆蓋編輯器自帶的程式碼規範,從而達到整個專案程式碼風格統一的效果。

# 是否為最頂層的配置檔案
root = true

# 匹配檔案規則
[*.{js,jsx,ts,tsx,vue}]

# 程式碼縮排方式
indent_style = space

# 縮排的空格數
indent_size = 2

# 定義換行符
end_of_line = lf

# 是否去處行首行尾的空白字元
trim_trailing_whitespace = true

# 檔案是否以空白行結尾
insert_final_newline = true

# 每行程式碼的最大長度
max_line_length = 100

  當我們指定風格之後,需要有一個工具去輔助我們進行校驗,通常我們會使用 ESLint 去對我們的程式碼進行檢查,在我們通過 Vue CLI 去建立專案時其實已經載入了 ESLint 外掛並選擇了程式碼風格。這裡我是使用的 airbnb 的 vue 程式碼風格和 eslint 強烈推薦的規則,你可以按照你自己的喜好去修改這塊的設定。

module.exports = {
  root: true,

  env: {
    node: true,
  },

  extends: [
    'plugin:vue/strongly-recommended',
    '@vue/airbnb',
  ],

  rules: {
    'no-console': 'off',
    'no-debugger': 'off',
  },

  parserOptions: {
    parser: 'babel-eslint',
  },
};

  2.4、環境變數的設定

  正常情況下,我們的線上版本、開發版本、測試版本一些對應的請求地址是不一樣的,如果我們直接把請求地址寫到程式碼中,在後期的修改就會變得很麻煩,因此這裡我們就需要對我們的專案進行環境設定。預設情況下,一個通過 Vue CLI 構建的專案會有三個環境變數,分別為 development、production、test,其實這裡的 3 個環境變數就對應了我們的 package.json 中的 已經定義了的 npm 命令。

  首先,我們新增 3 個環境變數檔案 .env.development(開發環境)、.env.production(生產環境)、.env.staging(預釋出環境) 分別對應於不同的環境的一些引數資訊。因為預設是沒有 staging 這個環境的,所以我們需要在 package.json 檔案中去新增 staging 指令碼,從而去構建出 staging 環境。

"stage": "vue-cli-service build --mode staging"

  staging 環境的示例如下所示,不過,這裡需要注意,因為只有以 VUE_APP_ 開頭的變數會被 webpack.DefinePlugin 靜態嵌入到客戶端中,因此,如果我們想要在程式碼中獲取到這裡定義的變數值,我們只能以 VUE_APP_ 開頭去定義環境變數中會使用到的引數。  

# Node ENV 變數值
NODE_ENV = production

# staging 環境標識
ENV = 'staging'

# 後端 API 地址
VUE_APP_BASE_API_URL = 'http://127.0.0.1/stage-api' 

  2.5、package.json & package-lock.json

  在專案開發中,因為我們是使用 npm 去載入前端的元件,所以會存在 package.json 這個配置檔案。在這個 json 檔案中定義了這個專案所需要的各種前端模組,以及專案的配置資訊(比如名稱、版本、許可證等等)。當我們從別處拷貝這個專案後,通過執行 npm install 命令,就會根據這個配置檔案,自動下載專案中所需要引用的前端元件包。

  在 package.json 這個 json 檔案中存在著兩個看起來很相似的節點:devDependencies 和 dependencies。devDependencies 裡面的外掛只適用於開發環境,不用於生產環境,而 dependencies 中引用的則是需要釋出到生產環境中的。我們可以在使用 npm install 命令載入元件時通過新增 –save 修飾,表示需要將該元件新增到 dependencies 節點下面;如果你需要將引用到的 package 安裝到 devDependencies 節點下,則需要使用 –save-dev 進行修飾。

  因為我們在 npm 上下載的包遵循了大版本.次要版本.小版本的版本定義,而在安裝外掛包的時候,package.json 一般指定的是包的範圍,即只對外掛包的大版本進行限定。因此,當別人拷貝了你的程式碼,準備還原引用的包時,如果恰好在元件包更新中移除了你使用的一些特性,毫無疑問,整個專案程式碼就會報錯。而 package-lock.json 這個檔案,則可以記錄實際安裝的各個 package 的具體來源和版本號,此時,當別人拷貝了程式碼,準備還原時,就可以準確的載入到你開發時使用的元件版本。

  2.6、webpack 配置

  在上面我們有提到,Vue CLI 本質上也是基於 webpack 去構建的 Vue 專案,如果你有使用過 Vue CLI 2 去建立專案,你會發現原本對於 webpack 配置的 webpack.base.config.js、webpack.dev.config.js 、webpack.prod.config.js 這些配置檔案已經沒有了。那麼這裡如何去按照自己的習慣去對 webpack 進行一個調整呢?

  原來,因為 Vue CLI 3 的設計思想是 0 配置,所以通過 Vue CLI 3 構建的 Vue 專案已經幫開發者已經解決絕大部分情形下的 webpack 配置,如果你有需要做一些自定義的設定,則可以去建立一個 vue.config.js 去進行自定義的配置。這裡就不對配置的內容進行介紹了,我會放到下一章中去介紹這個專案對於 webpack 的一些配置。

  至此,我們對於模板專案的調整也就到一段路,最終我們修改完成後的專案分層如下圖所示,後續我也將在這個調整後的結構上進行搭建專案模板。

 四、參考

  1、從0到1搭建Element的後臺框架

  2、vue-cli3 專案從搭建優化到docker部署

  3、一張圖教你快速玩轉vue-cli3

  4、手摸手,帶你用vue擼後臺 系列四(vueAdmin 一個極簡的後臺基礎模