當前位置:
首頁 > 科技 > 4種使用webpack提升vue應用的方式

4種使用webpack提升vue應用的方式

前言

今日早讀文章由美團金融前端團隊@孫輝翻譯投稿分享。

正文從這開始~

譯者註:本篇文章所提到的幾個措施大家可能都曾經在項目里用過,但是就如作者所言:你只是在用,並不知道為什麼用,本文最大的價值在於提供了系統的優化方案並解釋了原因

webpack是開發Vue單頁應用必不可少的工具,它能管理複雜的構建步驟,並且優化你的應用大小和性能, 使你的開發工作流更加簡單。

在這篇文章中,我將解釋使用webpack提升你的Vue應用的4種方式,包括:

單文件組件

優化Vue構建過程

瀏覽器緩存管理

代碼分離

關於vue-cli

如果你在使用 vue-cli 提供的模板來構建你的應用,那麼webpack的相關配置已經提供好了,這些配置已經經過很好地優化,我也給不了你其他的優化建議了。

不過因為配置是開箱即用的,所以你很有可能並不知道這些配置真正在做什麼,由於 vue-cli 里提供了我將要討論的優化措施,所以,你可以把這篇文章當做模板里webpack配置的概述。

1.單文件組件

Vue的特點之一就是使用了基於HTML的模板組件,這帶來了一個本質問題:要麼HTML標記使用醜陋的JavaScript字元串,要麼將模板內容和組件定義寫在不同的文件中。這帶來了一些困難。

Vue提供了一種叫做Single File Components(SFCs)的方式來解決這個問題,將模板、組件定義、CSS寫在一個 .vue 文件里。

MyComponent.vue

Vue-loader 使得 SFCs成為可能,這個 webpack loader 將SFCs分隔成不同語言塊,然後輸出到合適的loader,例如 script塊 輸出到babel-loader, 模板塊輸出到Vue自己的vue-template-loader,該loader能夠將模板轉換成JavaScript的render函數。

vue-loader的最終輸出是一個將要包含在 Webpack bundle 中的JavaScript模塊。

典型的vue-loader配置如下所示:

loader: vue-loader ,options:{loaders:{// Override the default loaders}}},]}:{

:[

{

:/.vue$/,

: vue-loader ,

:{

:{

// Override the default loaders

}

}

},

]

}

2.優化Vue構建

運行時構建

如果在你的應用中僅僅使用 render函數,不需要HTML模板,那你不需要使用Vue的模板編譯器,通過去掉模板編譯器,可以讓你在Webpack構建過程中,減少bundle 的體積。

記住單文件組件在開發模式中使用了預編譯

默認情況下使用的是運行時構建版本,所以當你使用 import vue from vue 來引用Vue的時候,你得到的是運行時構建版本,不過你能通過 alias 配置項來改變。

譯者註:在Vue模塊中包含8個文件,各文件的區別可以參考:官方文檔,在需要使用完整版時使用了運行時版本會報warn:

You are using the runtime-only build of Vue where the template option is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

production環境中去掉 warn 和 error 信息

另外一個減少Vue構建體積的方式是在 production環境中去掉所有 error 和 warn信息,這些不必要的代碼導致你打包後的體積膨脹,而且增加了運行時耗時,你最好避免這些消耗。

如果你調試Vue的源代碼,你會發現這些提示信息都是通過環境變數 process.env.NODE_ENV 的值來判斷的,例如:

if(process.env.NODE_ENV!== production ){

warn(("Error in "+info+": ""+(err.toString())+"""),vm);

}

如果 process.env.NODE_ENV 的值設置成 production ,那麼提示信息在構架過程中就會自動被剔出去。

可以通過使用 DefinePlugin 去設置 process.env.NODE_ENV 的值,同時使用 UglifyJsPlugin 去減小代碼體積並且去掉不需要的代碼塊。

譯者註:實際項目中使用的更多的方式是 production環境 和 其他環境 使用不同的webpack配置文件.

3.瀏覽器緩存管理

瀏覽器能夠緩存你的站點文件,只有在你本地沒有副本時或者副本已經過期時才會重新下載。

如果你所有的代碼都在一個文件里,那一個微小的改動也會導致整個文件的下載,理想情況下,你想要你的用戶儘可能少的下載文件,所以將頻繁改動的代碼和不怎麼改動的代碼分開是非常明智的。

Vendor file

Common Chunks插件能把你的Vendor代碼(例如Vue.js這些不會經常改動的依賴包)和應用代碼(每次開發過程中都會改動的代碼)分離開。

你能配置插件檢查一個依賴是否來自於node_modules,如果是,那就打包到vendor.js 文件。

這麼做之後,在構建後的輸出文件中,將有兩個獨立的文件,能夠分別被瀏覽器緩存。

指紋

當構建後的文件改動了,我們該怎麼丟棄緩存呢?

默認情況下,只有當一個緩存文件過期,或者用戶手動清除緩存,瀏覽器才會重新從伺服器請求文件,如果伺服器提示文件已經改動,那文件才會重新被下載(如果返回304則不會)。

為了避免不必要的請求,我們可以在每次文件內容改動時,改變文件的名字,從而強制瀏覽器重新下載,通過在文件名稱後面添加一個"指紋":hash,我們可以非常容易達到這個目的。

Common Chunks插件生成"chunkhash",能隨著文件的改動而更新,Webpack能在輸出時,將這個hash值添加到文件名稱末尾。

output:{

filename: [name].[chunkhash].js

},

這樣做的話,你會發現輸出的文件名稱類似於app.3b80b7c17398c31e4705.js。

譯者註:chunkhash並不需要Common Chunks生成,而是webpack自動生成的,而且據官方文檔,Common Chunks是無法生成chunkhash的,作者在這裡這麼寫讓我摸不著頭腦, 另外,還有一種添加hash值的方式是使用

output:{

filename: [name].[hash].js

},

其中的區別主要在於chunkhash是基於內容生成的hash值,而hash值是基於模塊標識(webpack打包時每個模塊都有一個唯一標識),hash值的主要問題在於任何一個文件更新之後都會更新hash值,導致那些內容沒有更新的文件的文件名也更新了,需要重新下載。具體區別可參考:webpack配置:緩存。

自動插入構建文件

當然了,增加了hash值之後,你就必須要在index文件里更新你的引用,否則瀏覽器是不會知道的。

手動去做這件事將是一件非常沉悶無聊的事情,可以使用HTML Webpack Plugin來做這件事。這個插件能在構建過程中自動在你的HTML文件里插入對構建文件的引用。

先來把構建文件中的引用去掉

index.html

然後在Webpack配置里增加HTML Webpack Plugin 的配置。

newHtmlWebpackPlugin({

filename: index.html

template: index.html ,

inject:true,

chunksSortMode: dependency

})

現在帶有hash值的構建文件將會自動增加到index文件,同時,你的index.html文件也會被包含在輸出文件里,所以你可能需要將這一點告訴伺服器。

4.代碼分離

默認情況下,Webpack將把你的所有應用代碼輸出到一個大的構建文件中,但是如果你有多個頁面,分隔代碼將每個獨立的頁面輸出到不同的文件中,只有在需要的時候才去載入。

Webpack有個功能 "code splitting",可以用來做這件事,在Vue.js中需要使用async components,配合Vue Router使用更簡單。

Async componets

相比以一個定義對象作為第二個參數,Async components第二個參數是一個Promise函數,該函數將一個對象resolve,例如:

Vue.component( async-component ,function(resolve, methods etc.});},1000)}).component( async-component ,function(,){

setTimeout(()=>{

resolve({

// Component definition including props, methods etc.

});

},1000)

})

Vue只有在這個組件需要被渲染時,才會調用這個函數,同時也會為以後的預渲染緩存返回結果。

如果我們將每個頁面都當做一個組件,並且將定義對象放在伺服器端,那在代碼分離的路上,我們已經走了一半了。

require

為了從伺服器上載入你的非同步組件代碼。使用Webpack的require語法,這將通知Webpack將async-component打包到一個分隔的bundle,更妙的是,Webpack將使用AJAX處理bundle的載入,所以你的代碼可以像下面這樣簡單:

懶載入

在Vue.js應用中,vue-router是一個典型模塊,你可以用它來將SPA轉換成多頁應用,懶載入是利用Vue和Webpack實現代碼分離的官方推薦方式。

constresolve);constrounter=newVueRouter({routes:[{path: / ,name: HomePage ,component:HomePage}]})==>require([ ./HomePage.vue ],);

const=newVueRouter({

:[

{

: / ,

: HomePage ,

:

}

]

})

關於本文

譯者:@孫輝

作者:@ANTHONY GORE

點擊展開全文

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端早讀課 的精彩文章:

前端處理大數據的無限可能
redux-react實踐總結
【第994期】字型大小與行高
總是一知半解的Event Loop
美團金融大前端團隊招各級別前端工程師

TAG:前端早讀課 |

您可能感興趣

Tokenvator:使用Windows Token提升許可權的工具
Semtech和KernelSphere攜手在印度提升公用設施性能
微軟收購Semantic Machines,Cortana對話式AI能力將進一步提升
Google Chrome通過改進Cookie處理來提升用戶隱私
回顧 | 脊柱健康提升運動表現 St. Michael Spine Health Online Workshop
Win10版Microsoft To-Do應用更新:提升搜索性能
新一代 Apple Watch Series 4 將提升解析度
Intel 10nm IceLake努力提升普通核顯性能
Adobe發布Lightroom Classic 7.2 速度再次提升
Microsoft Launcher 發布 提升性能 修復崩潰問題
Kotlin和Swift語言在Redmonk榜上排名大幅提升
提升趣味性,iOS 12在FaceTime新增Animoji功能
Genesis Markets和LMAX Digital達成合作 提升客戶加密交易服務
除了屏幕面積提升,Apple Watch Series 4 還有哪些重大升級?
iPhoneXs Max對比iPhoneX,拍照卻提升了很多
CMMI Cybermaturity Platform提升董事會和高管人員對於網
Canonical 表示,Ubuntu 18.04 LTS 啟動速度將會提升
外媒透露 Apple Watch Series 4 細節:全面屏設計,續航提升
AMD即將推出Threadripper新模式:性能提升47%
數據科學家效率提升必備技巧之Jupyter Notebook篇