https://github.com/wanglong/vue-element-admin.git
優化 Vue CLI 3 構建的前端項目模板(1)- 基礎項目模板介紹
一站式開源運維平台,分享給大家
平台介紹
CODO是一款為用戶提供企業多混合雲、自動化運維、完全開源的雲管理平台。
CODO前端基於Vue iview開發、為用戶提供友好的操作界面,增強用戶體驗。
CODO后端基於Python Tornado開發,其優勢為輕量、簡潔清晰、異步非阻塞。
CODO開源多雲管理平台將為用戶提供多功能:ITSM、基於RBAC權限系統、Web Terminnal登陸日志審計、錄像回放、強大的作業調度系統、CMDB、監控報警系統、DNS管理、配置中心等
產品架構

產品功能

模塊說明
-
項目前端:基於Vue + Iview-Admin實現的一套后台管理系統
-
管理后端:基於Tornado實現,提供Restful風格的API,提供基於RBAC的完善權限管理,可對所有用戶的操作進行審計
-
定時任務:基於Tornado實現,定時任務系統,完全兼容
Linux Crontab
語法,且支持到秒級 -
任務調度:基於Tornado實現,系統核心調度,可分布式擴展,自由編排任務,自由定義流程,支持多種觸發,支持審批審核,支持操作干預
-
資產管理:基於Tornado實現,資產管理系統,支持手動添加資產,同時也支持從AWS/阿里雲/騰訊雲自動獲取資產信息
-
配置中心:基於Tornado實現,可基於不同項目、環境管理配置,支持語法高亮、歷史版本差異對比、快速回滾,並提供Restful風格的API
-
域名管理:基於Tornado實現,支持多區域智能解析、可視化Bind操作、操作日志記錄
-
運維工具:基於Tornado實現,運維場景中常用的加密解密、事件、故障、項目記錄、提醒、報警等
在線體驗
CoDo提供了在線Demo供使用者體驗,Demo賬號只有部分權限
- 地址:http://demo.opendevops.cn
- 用戶:demo
- 密碼:2ZbFYNv9WibWcR7GB6kcEY

一、前言#
在上一章中,我們開始通過 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 的一些配置。
至此,我們對於模板項目的調整也就到一段路,最終我們修改完成后的項目分層如下圖所示,后續我也將在這個調整后的結構上進行搭建項目模板。