vue2開發過程問題總結

本文首發于我的博客

前言

慢慢地也用vue2+webpack2重構了一整個項目,期間自己踩過的坑和思考記錄下來,既讓自己復盤一遍也方便以后查找相關的問題

項目構建

因為vue-cli實在是太友好了,并且也是打算做單頁應用,所以直接用vue-cli構建基于webpack2的模板。

整體技術棧使用vue2+webpack2+vuex+Axios+vue-router

項目總體結構↓


|-- build                            // 項目構建webpack相關代碼
|-- config                           // 項目開發環境配置
|-- node-moudles                     //node依賴包(自動生成的)
|-- src                              // 源碼目錄(此文件內基本就是開發者主要編寫代碼存放資源的地方)
     |--router                            //路由文件
     |--vuex                              //vuex文件
     |--style                             //公共樣式文件
     |--assets                            //靜態資源(大多都是放一些樣式類文件,如css、scss等,不知道為啥,當時我沒有用)
     |--components                        //組件文件
|-- static                           // 靜態文件,比如一些圖片,json數據等(打包成生產環境時,會將這個文件直接打包進去)
|-- .babelrc                         // ES6語法編譯配置
|-- .editorconfig                    // 定義代碼格式
|-- .gitignore                       // git上傳需要忽略的文件格式
|-- README.md                        // 項目說明
|-- favicon.ico                      // 頁面標簽顯示的logo
|-- index.html                       // 入口頁面
|-- package.json                     // 項目基本信息

build文件夾


|-- build                            // 項目構建webpack相關代碼
     |--build.js                          //生產環境構建
     |--check-version.js                  //版本檢查
     |--dev-client.js                     //開發服務器熱重載
     |--dev-server.js                     //構建本地服務器
     |--utils                             //構建相關工具
     |--vue-loader.conf.js                //CSS加載器配置
     |--webpack.base.conf.js              //webpack基礎配置
     |--webpack.dev.conf.js                //webpack開發環境配置
     |--webpack.prod.conf.js               //webpack生產環境配置
     |--webpack.test.conf.js               //webpack測試環境配置

build主要是用于webpack的一些相關配置,比如內部含有的啟動文件dev-server.js.當我們運行npm run dev命令時node就會根據
package.json中的"dev": "node build/dev-server.js",來尋找此文件,這些都是默認設置。無需要修改

  "scripts": {
    "dev": "node build/dev-server.js",
    "start": "node build/dev-server.js",
    "build": "node build/build.js",
    "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
    "e2e": "node test/e2e/runner.js",
    "test": "npm run unit && npm run e2e"
  },

config文件夾

config主要就是項目的相關配置,比如自定義修改監聽端口,打包輸出的路徑及其輸出文件的命名


|-- config                           // 項目構建webpack相關代碼
     |--dev.env.js                      //項目開發環境配置
     |--index.js                        //項目主要的配置(監聽端口,打包路徑啥的都在這里寫)
     |--prod.env.js                     //項目生產環境配置
     |--test.env.js                     //項目測試環境配置

上述三個文件做簡單介紹是因為最后我們在打包優化主要是對于webpack的配置文件進行修改,所以先做簡單介紹。

編碼過程問題總結

路由標簽自定義

用到vue2框架的時候不可避免會用到路由插件,一般配合vue2的官方路由插件是vue-router2

其中有個路由跳轉標簽為router-link

例子如下

<router-link to="/foo">foo</router-link>
<!-- 渲染結果 -->
<a href="/foo">foo</a>

但是由于樣式的原因。有時候我們不希望他被渲染成<a href=""></a>

那我們可以利用router-link中的tag屬性改變渲染過后的標簽

例子如下

<router-link to="/foo" tag="li">foo</router-link>
<!-- 渲染結果 -->
<li>foo</li>

自定義路徑別名(@,~)

在vue2過程導入組件或者css時可能會有這種語法

import Index from '@/components/Index'

這種@是什么東西?
在配置文件中這是webpack的配置項之一:路徑別名

我們可以在基礎配置文件中自定義自己的路徑別名,比如設置~src/components:

// build/webpack.base.js

{
  resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
      'vue$': 'vue/dist/vue.esm.js',
      '@': resolve('src'),
      '~': resolve('src/components')
    }
  }
}

然后導入組件就可以直接這樣寫

//import YourComponent from 'src/components/YourComponent

import YourComponent from '~/YourComponent'

這樣就解決了路徑過長與相對路徑的煩惱,方便多了吧

CSS作用域與模塊

在組件化開發過程中本著分離的原則,CSS也應該進行獨立分離,這樣更方便以后維護。

我們可以通過添加scoped屬性來使style中的樣式只作用于當前組件

<style lang="less" scoped>
  @import 'other.less';
  .main{
    color:#fff
  }
</style>

注意:

在有scoped屬性的style標簽內導入其他樣式,同樣會被限制于該作用域,變為組件內的樣式。這樣再每次打包之后會大大增加CSS體積,所以復用程度較高的樣式不建議這樣使用
,第一次我就出了這個問題

另外,在組件內樣式中應該避免使用元素選擇器,原因在于元素選擇器與屬性選擇器進行查詢時性能會大大降低

好像這條不止于在vue中,而是css本來就存在的

v-for的使用

v-for指令真是無比便捷,他讓我們大大減少了HTML代碼的編碼量,并且讓模板更加與數據契合。
不僅可以遍歷數組,對象,甚至可以遍歷字符串與數字

我們經常會遇到一些比如,上下移動行啊什么的需求。這些需求基本都繞不過索引
在使用v-for時候我們可以直接
<li v-for="(item,index) of items" :index="index" :key="index"></li>
這樣直接可以利用li標簽的index屬性就可以拿到當前這行的index。tr同理
但是在便利數字時候需要特別注意,數字是從1開始的

項目路徑配置

vue-cli提供的 npm run build打包出的dist文件是默認把index.html當做根目錄引用的,然而我們有時候是需要部署到服務中的子目錄下

那么我們可以修改config/index.js中來改變相對路徑:

build.assetsSubDirectory: 'static'
build.assetsPublicPath: '/'

dev.assetsSubDirectory: 'static'
dev.assetsPublicPath: '/'

assetsSubDirectory指的是靜態資源文件夾,也就是打包后的js、css、img等文件所放置的文件夾。這個一般都不需要修改
assetsPublicPath而這個屬性就是指index中引用靜態資源的路徑,默認為/。如果我們需要做特殊配置修改這里的路徑就好。路徑修改為最后你的index.html到這個靜態資源的相對路徑

開發環境配置

何為開發環境:在開發時,不可避免會產生大量debug又或是測試的代碼,這些代碼不應出現在生產環境中(也即不應提供給用戶)。

開啟webpack的cache

webpack.base.conf.js中,在module.exports內加入cache: true這個屬性

配置加載器loader中的include與exclude

加載器loader中的include屬性代表需要編譯的文件,而反之exclude就是不需要編譯的文件。

大多數情況下我們幾乎都不需要對node_modules下的js文件進行編譯,我們只需要對我們項目目錄下自己編寫的js進行編輯就好,所以我們通過配置這兩個選項,大大提升我們的構建速度

webpack.base.conf.js

// ... 其他配置
module: {
  rules: [
    {
      test: /\.js$/,
      loader: ['babel-loader?cacheDirectory=true'],
      include: [resolve('src')], // src是項目開發的目錄
      exclude: [path.resolve('../../node_modules')] // 不需要編譯node_modules下的js 
    },
    // ... 其他loader
  ]
}

開啟babel-loader插件的cache

開啟babel-loader的編譯緩存,以后編譯就只會編譯修改過的地方,重用的地方就不會重新編譯,大大節約構建速度。

此代碼在webpack.base.conf.js

module:{
      rules: [
    {
      test: /\.js$/,
      loader: ['babel-loader?cacheDirectory=true']  //修改這里即可
    },
  ]
}

使用HappyPack加快編譯速度

雖然我們有webpack的熱更新,但每次初始化啟動項目時發現總是需要等待很長的時間才能完成編譯。

那么我們就可以利用HappyPack插件開啟多線程,大大加快代碼構建速度。

主要核心技術有兩點:

  1. 利用Loader的并發可行性完成多線程
  2. 在每次編譯時候都會針對對應文件存入一個時間戳并且將編譯結果緩存 ,下次編譯時,就會先讀取這個時間戳。利用這個做key去對比,如果沒有變那么就直接讀取緩存。

例子代碼如下:


//先引入happypack與相關模塊
let HappyPack = require('happypack');
let os = require('os');
let happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });

module:{
 rules: [{
      test: /\.vue$/,
      loader: 'vue-loader',
      // options: vueLoaderConfig
      options: {
        loaders: {
          js: 'happypack/loader?id=js' // 將loader換成happypack
        }
      }
    },
    {
      test: /\.js$/,
      // loader: 'babel-loader',
      // loader: ['babel-loader?cacheDirectory=true'],
      loader: ['happypack/loader?id=js'], // 將loader換成happypack
      include: [resolve('src'), resolve('test')],
      exclude: [path.resolve('../../node_modules')] // 不需要編譯node_modules下的js 
    },
    ...
}

plugins:[
    new HappyPack({
      id: 'vue',
      threadPool: happyThreadPool,
      cache: true,
      verbose: true,
      loaders: ['vue-loader'],
    }),

    new HappyPack({
      id: 'js',
      threadPool: happyThreadPool,
      cache: true,
      verbose: true,
      loaders: ['babel-loader'],
    }),
]

生產環境配置

何為生產環境配置:頁面部署到服務器時,為了追求性能加大用戶體驗,所以我們會對代碼進行各種各樣的優化,比如說混淆、壓縮,這些手段往往會徹底破壞代碼本身的可讀性,不利于我們進行debug等工作。

利用CommonsChuncksPlugin解決重復引用

我們在開發過程中為了方便代碼維護,可能會抽出一些公關的模塊,這里不止于vue的共用組件,如果用了css預編譯器,那更是會有@mixin這種宏(scss是這樣,其他可能不是這個名詞但是也會有)。

那么在打包過程中將會把引入的模塊重復打包,這樣大大增加了最后的文件體積,這樣是肯定不可取的。

而webpack有個插件叫CommonsChuncksPlugin

就是專門把重復打包的模塊給抽取出來單獨打包的插件。這個能夠顯著降低最后打包的體積,也能提升一些打包速度。

使用也很方便,就是在webpack.base.conf.js中的plugins添加相關的配置代碼,如下

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    async: 'shared-module',
    minChunks: (module, count) => (
      count >= 2    // 當一個模塊被重復引用2次或以上的時候單獨打包起來。 
    )
  }),
  //...
]
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,048評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,414評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,169評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,722評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,465評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,823評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,813評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,000評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,554評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,295評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,513評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,722評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,125評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,430評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,237評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,482評論 2 379

推薦閱讀更多精彩內容