部門最近的一個新項目啓動,很幸運由我來主導整個前端部分的技術選型和總體架構,項目工做量很大,可是卻沒有足夠的人手,只有三個連CSS都不太會的實習生跟着我一塊兒作,壓力山大。兩個月以來,雖然碰見了不少問題,可是最終順利的解決了,項目基本完成,果斷寫一篇總結,畢竟是第一個真正意義上全權本身負責的大項目 。javascript
1、技術選型。css
若是沒有接觸過新的知識,我可能會像以前的部門的全部項目同樣,循序漸進的使用Jquery + bootstrap + sea.js/require.js 進行開發,可是我說了NO。前端
首先,此次項目初步估計有近百個功能點和幾十個頁面,若是仍用jquery的方法,光是臃腫的dom操做代碼就把人寫的筋疲力盡了,並且我本身本人也是在是厭倦了重複而乏味DOM操做。因此我選擇了Vue, 至於爲何不是react和anglar, 相對於他們Vue我以爲對於新手來講是很容易上手的,相對於react一些相關的技術棧,Vue對於實習生更容易掌握。使用Vue我只須要把項目共用的模塊封裝成共用組件,讓他們去調用就能夠了,這一點保證了他們不多去寫CSS樣式,也爲項目快速的開發完成起到了必定的決定因素。vue
最終使用的技術以下:java
基礎JS框架: Vue, 基礎樣式和組件框架: iView ,國際化插件: vue-i18n,表單驗證插件:vee-validatereact
項目打包工具:webpack + babeljquery
代碼規範性檢查: eslintwebpack
2、項目過程當中碰見的問題。nginx
這部分實際上是我寫這篇博客的主要目的,好多問題,畢竟總結更多的是去記錄過去碰見的問題和走過的彎路。web
一、舊的JS代碼的兼容。
因爲項目中有一部分的代碼是以前的項目組使用的seajs封裝的模塊,並且這部分代碼內部的邏輯比較複雜,重寫基本是不可能的,沒時間何精力去研究,只有經過引入到咱們的webpak工程中,如何把這部分代碼挪過來而且不多改動就成了一個大問題。很幸運,webpack直接支持AMD或CMD的代碼,我用的vue-cli初始化的項目,因此更改了一些webpack.base.config裏的一些配置,可是忍讓須要修改一些配置讓原來js裏的require可以找到原來的模塊並執行。
新建了一個oldModuleConfig.js,
const path = require('path') function resolve (dir) { return path.join(__dirname, '..', dir) } const oldModuleConfig = { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'), /* Switch EWeb */ 'oldModule1': resolve('src/oldModule1'), 'oldModule2': resolve('src/oldModule2'), 'oldModule3': resolve('src/oldModule3'), 'oldModule4': resolve('src/oldModule4'), } module.exports = oldModuleConfig
而後修改了webpack.base.config.js
resolve: { extensions: ['.js', '.vue', '.json', '.less'], /** alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src') } **/ // 將原來的這部分改爲這樣 alias: oldModuleConfig }
這樣原來的module1裏面若是寫了require就能夠直接使用了
var module2 = require('module2') //這行代碼若是沒有配置直接引入就找不到module2這個模塊,而配置alias以後就能夠運行了
這是本人本身想到的略low的方法,若是有高人指出能夠在webpack裏引入舊的seajs/requirejs代碼其餘方法,歡迎指出。
二、原有代碼沒法經過eslint語法檢查
原來的代碼雖然引進來了,可是卻沒法經過eslint的檢查,這個問題我是直接選擇忽視原有文件的檢查,若是你是用了vue-cli構建的項目,能夠修改.eslintignore
build/*.js config/*.js src/oldCodeFolder //舊代碼的文件夾
三、Vue-router 頁面刷新
若是用過vue-router的應該知道,若是點擊的連接就是如今的頁面,那麼當前頁面組件是不會刷新的,實際過程當中可能但願再次點擊頁面是刷新一下。解決辦法是使用一箇中轉頁面bus,全部的頁面跳轉到這個bus.vue,而後由這個頁面再調回原來的頁面,這樣就達到了刷新的效果。
<!-- 這是一箇中轉的頁面,自己不具備任何內容,爲何要設置這個中轉頁面呢? 由於vue-router點擊當前頁面的連接時並不會刷新組件,爲了保持再次點擊刷新, 經過設置這個bus中轉頁面便可實現 --> <template> <div> </div> </template> <script> export default { data () { return {} }, methods: { jumpToPage () { let path = this.$route.params.path if (path) { this.$router.replace(path) } } }, mounted: function () { this.jumpToPage() } } </script>
而後router-view裏傳入下一個即將跳轉的頁面路徑便可
<router-link :to="{ name: 'bus', params: { path: nextPath }}":key="link.en"> {{ link.en }} </router-link>
四、iView封裝帶分頁的表格組件
iView提供了Table和Page兩個組件,可是很蛋疼,沒有提供帶分頁的表格組件,因此須要本身進行組合實現。這裏提供示例代碼,
<template> <div class="clear"> <Table :columns='columns' :data='showData' :ref="refLabel" :loading="loading" stripe :no-data-text="'<span class=\'no-data-text \' > <i class=\'icon-no-data\'></i> ' + $t('message.nodata')+ '</span>'"></Table> <Page :total='dataCount' :page-size='pageSize' :show-total='isShowTotal' :current.sync="current" class='paging' @on-change='changepage'></Page> </div> </template> <style scoped> .paging{ float:right; margin-top:20px; } </style> <script> export default { data () { return { ajaxHistoryData: [], // 初始化信息總條數 dataCount: 0, // 每頁顯示多少條 showData: [], current: 1 } }, props: { pageSize: { type: Number, default: 10 }, columns: { type: Array }, isShowTotal: { type: Boolean, default: true }, tableData: { type: Array }, refLabel: { type: String }, loading: { type: Boolean, default: false } }, methods: { // 獲取歷史記錄信息 handleShowData () { if (this.tableData && this.tableData.length) { // 保存取到的全部數據 this.dataCount = this.tableData.length // 初始化顯示,小於每頁顯示條數,全顯,大於每頁顯示條數,取前每頁條數顯示 if (this.tableData.length < this.pageSize) { this.showData = this.tableData } else { this.showData = this.tableData.slice(0, this.pageSize) } } else { this.showData = [] this.dataCount = 0 } this.current = 1 }, currentChange (value) { }, changepage (index) { var _start = (index - 1) * this.pageSize var _end = index * this.pageSize this.showData = this.tableData.slice(_start, _end) } }, created () { this.handleShowData() }, watch: { tableData (oldVal, newVal) { this.handleShowData()
// 表格刷新了,當前頁標識須要回到第一頁的位置 this.current = 1 } } } </script>
這裏沒有寫異步獲取數據的方法,因此具體使用時須要解渴本身的業務邏輯進行修改。
五、webpack打包體積過大,減小打包體積
說出來大家可能不信,咱們的代碼最終放在的服務器智能放下60M左右的文件,我也是很無奈,因此減小webpack打包體積就成了一個必須的問題。解決方法以下:
a、首先最直觀的,將生產環境的sourceMap設爲false ,這裏設置完以後,打包後的文件就沒有了.map文件,這一步基本減小了一大半的代碼體積。
b、使用webpack-bundle-analyzer 優化你的代碼
若是vue-cli構建的項目,只須要在package.json的scripts里加入:
"analyz": "set NODE_ENV=production && set npm_config_report=true && npm run build"
而後運行npm run analyz, 打包成功後瀏覽器會自動打開相似下面的頁面,找出其中共用寫入Vendors, 而後使用webpack.optimize.CommonsChunkPlugin 進行優化
c、若是大家有CDN的話,儘可能把基礎代碼如: vue , vue-router 放在CDN上面
d、tree shaking 去除無用的代碼
六、其餘
其實還有許多大大小小的問題,好比Vue的路由攔截,webpack多頁面,DDL優化打包速度,覆蓋iVIew組件,nginx代理,組件scoped樣式覆蓋不了iView默認樣式等等許多,每個解決完了都有滿滿的成就感。
3、項目構建問題回顧
一、代碼初期沒有架構合理,致使後期存在一些維護上的問題。
好比,代碼引入了SASS,開始沒有設置一個主題的公共文件,致使後面設計變更總體主題跟着發生了一些改變,雖然iView支持更改主題,可是本身寫的一些組件因爲沒有共用的主題文件,致使後期修改比較麻煩。
二、代碼沒有review
雖然代碼總體風格使用了eslint去規範了,可是其實真正開發的時候發現三個兄弟的代碼很不規範,畢竟工做經驗不足,包括變量的大小寫,css類命名,甚至在頁面裏使用了Jquery等問題,一開始沒有review, 後期仔細閱讀他們的代碼的時候才發現這些問題,而後才進行修改。其實這些問題在項目開始我就應該說明的。
三、其餘
後續補充。。。
4、項目收穫
整個項目在代碼架構上仍是得到了其餘同事的承認,至少推進了部門前端向前走了一步,我算是部門第一個吃螃蟹的人,勇於把新技術果斷使用到新的項目裏,第一次將webpack + vue的技術棧總體運用了一遍,雖然不能說精通,可是應該也是熟練掌握了,總以爲本身平日所學沒有白費,實踐應用了一遍滿滿的收穫。
2018 繼續前行。
喜歡的話能夠點個推薦或者關注哦!
注:本文出自博客園 https://home.cnblogs.com/u/mdengcc/ ,轉載請註明出處。