在上一章中,咱們開始經過 Vue CLI 去搭建屬於本身的前端 Vue 項目模板,就像咱們 .NET 程序員在使用 asp.net core 時同樣,咱們更多的會在框架基礎上按照本身的開發習慣進行調整。所以在後面幾章的學習中,我將會在整個項目基礎上,按照本身的需求進行修改設定。javascript
PS:由於畢竟本身仍是傳統意義上的後端開發,因此這裏最終搭建完成的前端項目模板,實際上是按照 PanJiaChen 開源的 vue-admin-template 模板進行修改仿寫,因此你能夠把這個系列後續的文章當成是對於 vue-admin-template 模板的使用資料補充。css
系列目錄地址:http://www.javashuo.com/article/p-bzzucmub-ba.htmlhtml
倉儲地址:https://github.com/Lanesra712/ingos-web前端
在調整項目模板前,咱們首先仍是先來了解下咱們經過 Vue CLI 3 所搭建的這個基於 Element UI 的項目模板,整個模板的文件結構及相關解釋說明以下所示。vue
|-- 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.一、webpack 的基礎概念java
由於不少這個系列的讀者童鞋可能和我同樣,就是傳統意義上的後端開發,在以前徹底沒有接觸過這種進行前端工程化的開發模式,因此這裏我會針對項目的基礎模板進行一個簡單的說明,若是存在不對的地方,歡迎在評論區指出。node
整個項目雖然是經過 Vue CLI 進行搭建的,可是由於 Vue CLI 其實也是基於 webpack 進行構建的,因此這個項目的本質上實際上是個 vue.js + webpack 項目,所以在後面的使用中會涉及到不少 webpack 的相關知識點。做爲目前最主流的前端構建工具,webpack 自己的知識點會不少,因此這裏只是對使用到的相關知識點進行一個簡單的概述,不會詳細的介紹,後續若是有使用到的時候也會進行補充。webpack
在前端項目開發中,咱們可能會引入不少的 css、js、fonts、imgs 或是其它的靜態文件到頁面中,當一個頁面引入了不少的靜態文件時,爲了加載這些靜態資源,網頁會發起不少個二次請求,從而致使頁面的加載變慢。同時,咱們在使用前端框架時,常常會存在不少的依賴關係,而且因爲 javascript 是一個弱類型的語言,沒法在代碼編寫時很快速的定位到框架間的依賴問題。ios
webpack 則能夠很好的幫咱們解決這些問題。git
webpack 是一個前端應用程序的靜態模塊打包工具,它是基於 node.js 進行開發的,因此在使用前咱們須要安裝 node.js。它能夠幫咱們實現對於網站所引用的靜態資源進行打包、壓縮、混淆;幫咱們解決 js、css 中可能存在的依賴關係;將同類型的靜態資源打包合併成一個文件,並對生成的代碼進行混淆,以增長線上代碼的安全性。
1.二、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.三、對於 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.四、對於 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.五、對於 router.js 的解釋
這個文件定義了咱們整個項目的前端路由信息,由於若是將整個項目中全部的路由都配置到這一個 js 文件中,這個文件確定會變得很龐大和很差維護,因此在後面我會添加一個 routers 文件夾去專門存放咱們的前端路由信息,而原有的 router.js 文件則會起到一個導出前端路由的做用。
1.六、對於 store.js 的解釋
由於在使用 Vue CLI 建立項目時,咱們添加了在 Vue 中專門針對狀態管理的插件 Vuex,因此這個 js 文件就是針對 Vuex 的一些配置,這裏我也會在後面專門添加一個 stores 文件夾去存放項目中使用到的狀態相關數據。
基礎項目的 src 文件夾下就是上面提到的這些內容,接下來我會按照本身的需求去添加一些文件夾去分類存放咱們在後續項目開發中可能會使用到的東西。
2.一、項目基礎調整
在上面有提到,我會建立一個 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.二、瀏覽器兼容性調整
在作 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.三、代碼風格的設定
在前端項目開發中,由於對於編輯器或是使用的操做系統不會有太嚴格的限定,例如這裏我是使用 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.四、環境變量的設置
正常狀況下,咱們的線上版本、開發版本、測試版本一些對應的請求地址是不同的,若是咱們直接把請求地址寫到代碼中,在後期的修改就會變得很麻煩,所以這裏咱們就須要對咱們的項目進行環境設定。默認狀況下,一個經過 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.五、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.六、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 的一些配置。
至此,咱們對於模板項目的調整也就到一段路,最終咱們修改完成後的項目分層以下圖所示,後續我也將在這個調整後的結構上進行搭建項目模板。