Webpack是開發Vue.js單頁應用程序的重要工具。 經過管理複雜的構建步驟,你能夠更輕鬆地開發工做流程,並優化應用程序的大小和性能。css
其中介紹下面四種方式:html
1.單個文件組件 vue
Vue的特殊功能之一是使用HTML做爲組件模板。 儘管如此,它們還有一個內在的問題:你的HTML標記須要是一個尷尬的JavaScript字符串,node
不然你的模板和組件定義將須要在單獨的文件中,使其難以使用。 webpack
Vue有一個優雅的解決方案,稱爲單文件組件(SFC),其中包括模板,組件定義和CSS所有在一個整齊的.vue文件中:web
以下模塊mycomponent.vue(html +js +css)瀏覽器
<template> <div id="my-component">...</div> </template> <script> export default {...} </script> <style> #my-component {...} </style>
SFC經過vue-loader Webpack插件實現。 這個裝載器將SFC的語言塊和管道分紅一個適當的裝載器,例如 腳本塊轉到babel-loader,而模板塊轉到Vue本身的vue-template-loader,緩存
將模板轉換爲JavaScript渲染功能。服務器
vue-loader的最終輸出是一個能夠包含在Webpack包中的JavaScript模塊。babel
vue-loader的典型配置以下:(webpack.base.conf.js)
module: { rules: [ { test: /\.vue$/, loader: 'vue-loader', options: { loaders: { // Override the default loaders } } }, ] }
2. 優化Vue構建--運行時版本構建
若是你僅在Vue應用程序*中使用渲染功能,而且沒有HTML模板,則不須要Vue的模板編譯器。 你能夠經過從Webpack構建中省略編譯器來減小捆綁包大小。
*記住,單個文件組件模板是在開發中預編譯的,以渲染功能!
Vue.js庫中只有一個運行時版本的構建,其中包含Vue.js除了模板編譯器(稱爲vue.runtime.js)以外的全部功能。 它比完整版小約20KB,因此值得使用,若是能夠的話。
默認狀況下使用運行時版本,所以每次使用「vue」的import vue 來引入須要的文件;
經過起別名來簡化文件中繁瑣的路徑引用:(webpack.base.conf.js)
resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js' // Use the full build } },
剝離生產中的警告和錯誤消息
減小Vue.js構建大小的另外一種方法是刪除生產中的任何錯誤消息和警告。 去掉沒必要要的代碼減小輸出捆綁包大小
咱們能夠這樣設置:只在生產環境中添加這些警告
if (process.env.NODE_ENV !== 'production') { warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm); }
若是process.env.NODE_ENV設置爲生產,那麼在構建過程當中,這些警告塊能夠經過分解器自動從代碼中刪除。
你可使用DefinePlugin設置process.env.NODE_ENV的值,並使用UglifyJsPlugin來縮小代碼並將未使用的塊刪除:
if (process.env.NODE_ENV === 'production') { module.exports.plugins = (module.exports.plugins || []).concat([ new webpack.DefinePlugin({ 'process.env': { NODE_ENV: '"production"' } }), new webpack.optimize.UglifyJsPlugin() ]) }
3. 瀏覽器緩存管理
用戶的瀏覽器將緩存你的站點的文件
若是全部的代碼都在一個文件中,那麼一個微小的變化將意味着整個文件將須要從新下載。
理想狀況下,你但願用戶儘量少的下載,所以在你的應用程序中將不多更改的代碼和頻繁更改的代碼分開處理會更好
3.1 Vendor 文件
這個Common Chunks插件能夠從你的應用程序代碼(可能在每一個部署中更改的代碼)解耦你的vendor 代碼(例如,Vue.js庫)。
你能夠查看依賴項是否來自node_modules文件夾,若是是,則將其輸出到單獨的文件vendor.js中:
new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function (module) { return module.context && module.context.indexOf('node_modules') !== -1; } })
最後在構建輸出中有兩個單獨的文件,這些文件將由瀏覽器獨立緩存:
<script src="vendor.js" charset="utf-8"></script> <script src="app.js" charset="utf-8"></script>
3.2 Fingerprinting
構建文件發生變化時,咱們如何修改瀏覽器的緩存?
默認狀況下,只有當緩存文件過時時,或者當用戶手動清除緩存時,瀏覽器將再次從服務器請求該文件。 若是服務器指示文件已更改,則文件將被從新下載(不然服務器返回HTTP 304未修改)。
爲了保存沒必要要的服務器請求,咱們能夠在每次內容更改時更改文件的名稱,以強制瀏覽器從新下載。 這樣作的一個簡單系統是經過附加一個哈希來爲文件名添加一個「fingerprint」,例如:
Common Chunks插件發出一個「chunkhash」,若是文件的內容已經更改,它將被更新。 當它們輸出時,Webpack能夠將這個哈希追加到文件名中:
output: { filename: '[name].[chunkhash].js' },
當你這樣作時,你會看到你輸出的文件將具備像app.3b80b7c17398c31e4705.js這樣的名稱。
3.3 自動注入構建文件
固然,若是你添加一個哈希,你必須更新索引文件中的文件的引用,不然瀏覽器將不會知道它:
<script src="app.3b80b7c17398c31e4705.js"></script>
這將是一個很是繁瑣的工做,手動執行,因此使用HTML Webpack插件爲你作。 該插件能夠在捆綁過程當中自動將構建文件的引用注入到HTML文件中。
首先刪除對構建文件的引用:(index.html)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>test-6</title> </head> <body> <div id="app"></div> <!-- built files should go here, but will be auto injected --> </body> </html>
並將HTML Webpack Plugin添加到Webpack config中:
new HtmlWebpackPlugin({ filename: 'index.html' template: 'index.html', inject: true, chunksSortMode: 'dependency' }),
這樣配置完成以後在index.html中就會自動引用構建的文件
4.代碼分割
默認狀況下,Webpack會將你的全部應用程序代碼輸出爲一個大捆綁文件。 可是,若是你的應用程序有多個頁面,則使用分割代碼將更有效,
每一個單獨的頁面代碼都在單獨的文件中,而且僅在須要時加載是更好的選擇。
Webpack有一個名爲「代碼分割」的功能,正是這樣。 在Vue.js中實現這一點也須要異步組件,而且經過Vue Router變得更加容易。
4.1 異步組件
異步組件不是將定義對象做爲其第二個參數,而是具備解析定義對象的Promise函數,例如:
Vue.component('async-component', function (resolve, reject) { setTimeout(() => { resolve({ // Component definition including props, methods etc. }); }, 1000) })
當組件實際須要呈現時,Vue將只調用該函數。 它還將緩存將來從新渲染的結果。
若是咱們構建咱們的應用程序,所以每一個「頁面」都是一個組件,而且咱們將定義存儲在咱們的服務器上,那麼咱們就是中斷實現代碼分割的途徑。
4.2 require要求
要從服務器加載異步組件的代碼,請使用Webpack require語法。 這將指示Webpack在構建時將單獨的軟件包中的async組件捆綁在一塊兒,
並且更好的是,Webpack將使用AJAX處理此捆綁包的加載,所以你的代碼能夠簡單以下:
Vue.component('async-component', function (resolve) { require(['./AsyncComponent.vue'], resolve) });
4.3 懶加載 (router.js)
在路由配置文件中通常的都是直接導入好比
import HomePage from './HomePage '
若是想路由頁面只在用到時候加載能夠修改以下
const HomePage = resolve => require(['./HomePage.vue'], resolve); const rounter = new VueRouter({ routes: [ { path: '/', name: 'HomePage', component: HomePage } ] })