[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 一個極簡的後臺基礎模板)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章