使用Webpack提高Vue.js應用程序的4種方法(翻譯)

本文翻譯自,翻譯技巧不太好,不喜勿碰 :
4 Ways To Boost Your Vue.js App With Webpack
衆所周知,webpack 是 開發 vue.js 單頁面應用程序的必備工具,經過管理複雜的構建步驟,它可使您的開發工做流程更加簡單,而且能夠優化應用程序的大小和性能。
在本文中,我將解釋Webpack加強Vue應用程序的四種方法,包括:html

Single file components  單文件組件
Optimising the Vue build  
Browser cache management
Code splitting

關於 vue-cli

若是您使用模板從vue-cli構建應用程序,那麼將提供預製的Webpack配置。它們已通過優化,沒有任何改進建議!
可是,因爲它們開箱即用的效果很是好,您可能對它們的實際功能並不太瞭解,對嗎?
考慮一下本文,對vue-cli模板中使用的Webpack配置進行概述,由於它們包含了我在這裏討論的相同優化。vue

1. Single file components

Vue的特有功能之一是將HTML用於組件模板。可是,這些帶有一個固有的問題:要麼您的HTML標記須要使用笨拙的JavaScript字符串,要麼您的模板和組件定義必須位於單獨的文件中,從而使其難以使用。node

Vue有一個優雅的解決方案,稱爲「單個文件組件(SFC)」,該文件將模板,組件定義和CSS都包含在一個簡單的.vue文件中:webpack

<template>
  <div id="my-component">...</div>
</template>
<script>
  export default {...}
</script>
<style>
  #my-component {...}
</style>

vue-loader Webpack插件使SFC成爲可能。該加載器拆分SFC語言塊並將每一個管道經過管道傳輸到適當的加載器,例如腳本塊轉到babel-loader,而模板塊轉到Vue本身的vue-template-loader,後者將模板轉換爲JavaScript渲染函數。
vue-loader的最終輸出是一個JavaScript模塊,準備將其包含在Webpack捆綁包中。
vue-loader的典型配置以下:web

module: {
  rules: [
    {
      test: /\.vue$/,
      loader: 'vue-loader',
      options: {
        loaders: {
          // Override the default loaders
        }
      }
    },
  ]
}

2. Optimising the Vue build

若是僅在Vue應用程序*中使用渲染功能,而沒有HTML模板,則不須要Vue的模板編譯器。您能夠經過從Webpack構建中省略編譯器來減少捆綁包的大小。
請記住,單個文件組件模板已在開發中預編譯以呈現功能!
Vue.js庫只有運行時版本,其中包含Vue.js的全部功能,但模板編譯器稱爲vue.runtime.js。它比完整版本小20KB,所以若是能夠的話值得使用。vue-router

默認狀況下,僅使用運行時構建,所以,每次使用 import vue from 'vue' 時,都將使用它。在您的項目中,這就是您所獲得的。可是,您可使用alias 別名配置選項更改成其餘版本:vue-cli

resolve: {
  alias: {
    'vue$': 'vue/dist/vue.esm.js' // Use the full build
  }
},

Stripping out warnings and error messages in production

減少Vue.js構建大小的另外一種方法是刪除生產中的任何錯誤消息和警告。這些使用沒必要要的代碼使輸出包大小膨脹,而且還致使您最好避免運行時開銷瀏覽器

若是您檢查Vue源代碼,則會看到警告塊取決於環境變量process.env.NODE_ENV的值,例如:緩存

if (process.env.NODE_ENV !== 'production') {
  warn(("Error in " + info + ": \"" + (err.toString()) + "\""), vm);
}

若是將process.env.NODE_ENV設置爲生產,那麼在構建過程當中,minifier能夠自動將此類警告塊從代碼中剝離。服務器

您可使用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. Browser cache management

用戶的瀏覽器將緩存您網站的文件,以便僅在該瀏覽器尚無本地副本或本地副本已過時時才下載。

若是您全部的代碼都在一個文件中,那麼進行微小的更改就意味着須要從新下載整個文件。

理想狀況下,您但願用戶下載得儘量少,所以將應用程序不多更改的代碼與頻繁更改的代碼分開是明智的。

Vendor file

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>

Fingerprinting

當構建文件更改時,咱們如何破壞瀏覽器的緩存?
默認狀況下,僅當緩存的文件到期時,或者當用戶手動清除緩存時,瀏覽器纔會再次從服務器請求文件。
若是服務器指示文件已更改,則將從新下載該文件(不然服務器返回HTTP 304 Not Modified)。
爲了節省沒必要要的服務器請求,咱們能夠在每次文件內容更改時更改其名稱,以強制瀏覽器從新下載該文件。一個簡單的系統能夠經過在文件名後附加一個哈希來爲文件名添加「指紋」:
image.png
Common Chunks插件會發出「 chunkhash」,若是文件內容已更改,則將對其進行更新。 Webpack能夠在輸出文件名時將此哈希附加到文件名中:

output: {
  filename: '[name].[chunkhash].js'
},

執行此操做時,您將看到輸出的文件將具備相似app.3b80b7c17398c31e4705.js的名稱。

Auto inject build files

固然,若是添加哈希,則必須更新索引文件中對該文件的引用,不然瀏覽器將不知道該哈希:

<script src="app.3b80b7c17398c31e4705.js"></script>

手動完成這項工做很是繁瑣,所以請使用HTML Webpack插件爲您完成。該插件能夠在捆綁過程當中自動將對構建文件的引用注入到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插件添加到您的Webpack配置中:

new HtmlWebpackPlugin({
  filename: 'index.html'
  template: 'index.html',
  inject: true,
  chunksSortMode: 'dependency'
}),

如今,帶有哈希的構建文件將自動添加到索引文件中。另外,您的index.html文件如今將包含在捆綁輸出中,所以您可能須要告訴Web服務器其位置已更改

4. Code splitting

默認狀況下,Webpack會將全部應用程序代碼輸出到一個大捆綁包中。可是,若是您的應用有多個頁面,則拆分代碼會更有效,所以每一個單獨的頁面代碼都位於單獨的文件中,而且僅在須要時才加載
Webpack具備一項稱爲「代碼拆分」的功能。在Vue.js中實現此功能還須要異步組件,而且經過Vue Router變得更加容易。

Async components

異步組件沒有將定義對象做爲第二個參數,而是具備一個Promise函數來解析該定義對象,例如:

Vue.component('async-component', function (resolve, reject) {
  setTimeout(() => {
    resolve({
      // Component definition including props, methods etc.
    });
  }, 1000)
})

Vue僅在組件實際須要渲染時才調用該函數。它還會緩存結果以供未來從新渲染。
若是咱們設計應用程序,使每一個「頁面」都是一個組件,而且將定義存儲在服務器上,那麼咱們就完成了代碼拆分的一半。

require

要從服務器加載異步組件的代碼,請使用Webpack require語法
這將指示Webpack在構建時將async-component捆綁在一個單獨的bundle中,更好的是,Webpack將使用AJAX處理此bundle的加載,所以您的代碼能夠像這樣簡單:

Vue.component('async-component', function (resolve) {
  require(['./AsyncComponent.vue'], resolve)
});

Lazy loading

在Vue.js應用程序中,vue-router一般是您用於將SPA組織到多個頁面中的模塊。延遲加載是使用Vue和Webpack實現代碼拆分的一種形式化方法。

const HomePage = resolve => require(['./HomePage.vue'], resolve);

const rounter = new VueRouter({
  routes: [
    {
      path: '/',
      name: 'HomePage',
      component: HomePage
    }
  ]
})

翻譯到此爲止了,若是能夠歡迎點贊關注個人公主號
fdd33dbe-71c4-4003-a215-603e45e762a5_0.png

相關文章
相關標籤/搜索