Vue.js項目模板搭建

前言

從今年(2017年)年初起,咱們團隊開始引入「Vue.js」開發移動端的產品。做爲團隊的領頭人,個人首要任務就是設計 總體的架構 。一個良好的架構一定是具有豐富的開發經驗後才能搭建出來的。雖然我有多年的前端開發經驗,但就「Vue.js」來講,仍然是個新手。所幸「Vue.js」有一個配套工具「Vue-CLI」,它提供了一些比較成熟的項目模板,很大程度上下降了上手的難度。然而,不少具體的問題仍是要本身思考和解決的。css

項目劃分

咱們公司的H5產品大部分是嵌套在手機客戶端裏面的頁面。每一個項目的功能都比較獨立,並且規模不大。這樣一來,既可讓這些小項目各自爲政,也能夠把它們集中放到一個大項目中管理。各自的優缺點以下:html


項目模板考慮到咱們團隊剛開始使用「Vue.js」,須要逐步摸索出合適的架構。若是作成一個大項目,一旦架構要調整,極可能會傷筋動骨。因此最終的選擇是 劃分紅多個小項目 。前端

雖然劃分紅多個小項目了,可是這些小項目也要保持一致的架構和公共代碼。說白了,就是要根據業務狀況搭建本身的項目模板,全部具體的項目都在這個模板的基礎上開發。下面就介紹一下咱們團隊的項目模板的搭建過程。vue

初始化

項目模板自己也是一個項目,因此也經過「Vue-CLI」來初始化(項目名爲「webapp-public」):node

vue init webpack webapp-public

這裏選用的是「webpack」模板,由於功能比較齊全。初始化的過程當中要注意:webpack

  • 安裝「Vue-Router」以支持單頁應用;git

  • 安裝「ESLint」以統一編碼規範。web

SASS

安裝「SASS」的支持比較簡單,先經過命令行安裝相關依賴:vuex

npm install node-sass --save-devnpm install sass-loader --save-dev

裝好後,只要指定style標籤的「lang」屬性爲「scss」,就能夠用該語言來編寫樣式代碼了:npm

<style lang="scss" scoped></style><style src="style.scss" lang="scss"></style>

REM佈局

現在移動端的頁面爲了適應不一樣尺寸的手機屏幕,大多都在樣式代碼中使用rem做爲尺寸單位。然而,設計師給的設計稿仍是以px爲單位的。這就須要把px轉換爲rem,這個轉換能夠在腦子裏面轉,也能夠經過工具去轉,好比「PostCSS」的插件「 postcss-px2rem 」。

初始化項目的時候,「PostCSS」就已經裝上了,因此直接安裝「postcss-px2rem」便可:

npm install postcss-px2rem --save-dev

裝好後還要修改項目根目錄下的「.postcssrc.js」,增長「postcss-px2rem」的配置:

"plugins": { 
 "autoprefixer": {}, 
 "postcss-px2rem": { "remUnit": 100 }
}

「px值/remUnit」即爲轉換出來的rem值,能夠根據自身須要修改「remUnit」的值。

然而,有些特殊的px值是不須要轉換成rem值的,這時候能夠經過特殊註釋禁止「postcss-px2rem」去處理這個值。例如:

/* 不一樣dpr下的細線 */
.g-dpr-1 .g-border-1px { 
 border-width: 1px !important; /*no*/
 }
 .g-dpr-2 .g-border-1px { 
 border-width: 0.5px !important; /*no*/
 }

Vuex

在單頁應用開發中,負責管理狀態的「Vuex」也是必備的。安裝也很是簡單:

npm install vuex --save

然而,真正使用的時候,在一些 低版本系統的瀏覽器 中,可能會出現這樣的異常:

Error: [vuex] vuex requires a Promise polyfill in this browser.

這是由於瀏覽器不支持「Promise」,這時候就須要一個「polyfill」。咱們能夠直接用「babel-polyfill」:

npm install babel-polyfill --save

「babel-polyfill」會在 全局做用域 添加ES6新增的對象和方法,項目中的其餘代碼並不須要顯式地引入(import或者require)它,這就意味着「Webpack」不會把它識別爲項目的依賴。因此還要修改「/build/webpack.base.conf.js」,在打包入口處增長「babel-polyfill」:

entry: { 
 app: ['babel-polyfill', './src/main.js']
}

另外要提一下的是,使用「Vue-CLI」初始化項目的時候默認安裝了「 babel-plugin-transform-runtime 」,而它的做用跟「babel-polyfill」是重複的,因此能夠移除前者。修改根目錄下的「.babelrc」,移除這一行:

"plugins": ["transform-runtime"]

而後刪除依賴便可:

npm uninstall babel-plugin-transform-runtime --save-dev

訪問路徑

每一個小項目真正在服務器(不論是測試、預發佈仍是生產環境的服務器)上運行的時候,是經過一級子目錄去區分的。

這就意味着,項目中的全部路徑都要加上一層目錄(好比原訪問路徑爲「http://localhost:8080/home」,如今就得改爲「http://localhost:8080/project-a/home」)。千萬別覺得這是很簡單的事情,實際上要改的地方是不少的。

首先要改的是「Vue-Router」的 基路徑 配置:

new Router({ 
 base: '/project-a/', // 基路徑
 mode: 'history', 
 routes: [
 { path: '/', component: Home }
]
});

設置基路徑後,跟路由相關的全部路徑都是相對基路徑,而不是根目錄。

而後是開發服務器的 資源發佈路徑 (/config/index.js):

dev: { assetsPublicPath: '/project-a/' }

對應地還要修改「/build/dev-server.js」的兩處地方,否則訪問的時候就會404:

require('connect-history-api-fallback')({ 
 // 默認爲"/index.html",由於資源發佈路徑改了,因此這裏也要對應上
 index: '/project-a/index.html'
 })
// 運行項目後默認打開的頁面地址
var uri = 'http://localhost:' + port + '/project-a/'

最後還要修改 Webpack熱更新的檢測路徑 。先修改「/build/dev-server.js」:

require('webpack-hot-middleware')(compiler, { 
 log: false, 
 path: '/project-a/__webpack_hmr'
 })

而後修改「/build/dev-client.js」:

require('webpack-hot-middleware/client?path=__webpack_hmr&dynamicPublicPath=true&noInfo=true&reload=true')

順帶一提,上面的這堆參數徹底是用源代碼調試的結果,官網文檔並無詳細說明。

所有改完以後能夠發現,跟目錄有關的代碼有5處,具體項目使用的時候豈不是要改5次?很是麻煩。這種狀況下,把這部分邏輯寫成一個公共函數去調用是最好的選擇。新建文件「 /src/add-dirname.js 」:

const DIR_NAME = '/project-a/';
module.exports = function(path) { 
 return (DIR_NAME + path).replace(/\/{2,}/g, '/');
};

而後把剛纔涉及添加一級子目錄的代碼所有改爲調用該函數來實現:

這樣一來,若是要修改一級子目錄,只須要修改常量「DIR_NAME」的值就能夠了。

公共代碼

咱們的公共代碼分爲三種:

  • 通用性較強的庫 :包括團隊成員編寫的一些通用庫、沒法經過npm安裝的通用庫等,跟業務無關;

  • 業務邏輯庫 :跟業務有關,可是跟表現層無關的公共代碼;

  • 業務組件庫 :表現層的組件。

它們都位於「/src/public」:

在每一種公共代碼的文件夾內,具體某一個庫或者組件的目錄結構以下:

  • /src/public/components/img-box

  • img-box.vue

  • 1.1

這裏要特別提一下的是 版本號 這一層文件夾。若是對庫或者組件的修改會形成之前的調用代碼不兼容,就不該該修改原文件,而是新建一個版本號文件夾,把新的代碼以及其他的資源文件都放到這個新文件夾中。這樣作的好處是,具體的項目要更新公共代碼時,直接把項目模板的「/src/public」覆蓋過去就行,不用擔憂不兼容。

構建

「webpack」這個項目模板已經配置好構建的邏輯。經過一個命令就能夠執行構建:

npm run build

根據默認配置,代碼會被髮布到項目根目錄下的「dist」文件夾內。然而,這樣簡單粗暴的發佈方式並不能知足實際需求:

  • 資源文件(圖片、CSS、JS等)要發佈到 CDN服務器 ;

  • HTML中要經過完整的URL引用資源文件(由於資源文件在CDN的域上);

  • 不用的環境(測試、預發佈、生產)使用不一樣的域訪問。

先解決區分環境的問題,咱們在構建命令中新增一個參數以表示環境:

npm run build <test|pre|prod>

而後在根目錄下新建一個配置文件「conf.json」(簡單起見,只寫了兩種環境的配置):

文件內容表示的分別是不一樣環境下的HTML文件發佈路徑、資源發佈路徑以及資源訪問路徑。

接下來就要把這些配置接入到「Webpack」的打包配置中。修改「/config/index.js」,先在開頭加上:

var env = process.argv[2]; // 環境參數(從0開始的第二個)
var conf = require('../conf');
// 找出對應環境的配置conf.indexRoot = conf.indexRoots[env];
conf.assetsRoot = conf.assetsRoots[env];
conf.assetsPublicPath = conf.assetsPublicPaths[env];

而後修改構建部分的代碼:

build: { 
 index: path.resolve(__dirname, conf.indexRoot + 'index.html'),
 assetsRoot: path.resolve(__dirname, conf.assetsRoot),
 assetsPublicPath: conf.assetsPublicPath
}

此時運行構建命令,就能夠把項目發佈到「conf.json」指定的路徑中。

小結

至此,項目模板搭建完畢。其實最重要的一點就是 可配置化 ,不然,開發具體項目的人初始化一個項目還要改十幾個地方,效率就很低了。

項目模板的使用

項目模板已經搭建好了,可是怎麼用呢?有兩種經常使用場景:

  • 初始化新項目 :克隆或拉取項目模板項目,複製該項目的全部文件(除了「.git」文件夾)到新項目的文件夾,修改配置後進行後續開發。

  • 更新公共代碼 :克隆或拉取項目模板項目,複製要更新的代碼到目標項目的對應路徑。

兩種場景都離不開「克隆或拉取」、「複製和粘貼」,這種作法一是麻煩,二是逼格過低。因此後來我用Node.js寫了一個命令行工具「webapp-cli」來完成這兩項工做。

初始化項目的命令爲:

webapp init [projectPath]

例如:

webapp init test

更新特定文件的命令爲:

webapp update <fileGlobs> [projectPath]

例如:

webapp update /src/public/** test

這個工具並無改變操做方式,只是由人工操做變成程序代勞。

 

 

>

學習前端的同窗注意了!!!

學習過程當中遇到什麼問題或者想獲取學習資源的話,歡迎加入前端學習交流羣461593224,咱們一塊兒學前端!

相關文章
相關標籤/搜索