vue項目優(yōu)化之 cdn引入依賴,減少打包體積。

webpack 對Externals的說明

外部擴展(Externals)

externals 配置選項提供了「從輸出的 bundle 中排除依賴」的方法。相反,所創(chuàng)建的 bundle 依賴于那些存在于用戶環(huán)境(consumer's environment)中的依賴。此功能通常對 library 開發(fā)人員來說是最有用的,然而也會有各種各樣的應用程序用到它。

externals

string [string] object function RegExp

防止將某些 import 的包(package)打包到 bundle 中,而是在運行時(runtime)再去從外部獲取這些擴展依賴(external dependencies)

例如,從 CDN 引入 jQuery,而不是把它打包:

index.html

<script
  src="https://code.jquery.com/jquery-3.1.0.js"
  integrity="sha256-slogkvB1K3VOkzAI8QITxV3VzpOnkeNVsKvtkYLMjfk="

  crossorigin="anonymous"
></script>

webpack.config.js

module.exports = {
  //...
  externals: {
    jquery: 'jQuery',
  },
};

這樣就剝離了那些不需要改動的依賴模塊,換句話,下面展示的代碼還可以正常運行:

import $ from 'jquery';

$('.my-element').animate(/* ... */);

具有外部依賴(external dependency)的 bundle 可以在各種模塊上下文(module context)中使用,例如 CommonJS, AMD, 全局變量和 ES2015 模塊。外部 library 可能是以下任何一種形式:

  • root:可以通過一個全局變量訪問 library(例如,通過 script 標簽)。
  • commonjs:可以將 library 作為一個 CommonJS 模塊訪問。
  • commonjs2:和上面的類似,但導出的是 module.exports.default.
  • amd:類似于 commonjs,但使用 AMD 模塊系統(tǒng)

好了說了那么多,總結來說就是

將不怎么需要更新的第三方庫脫離webpack打包,不被打入bundle中,從而減少打包時間,但又不影響運用第三方庫的方式,例如import方式等

在vue項目里面 vue.config怎么去配置呢?

每次都手動去在index.html里面手動引入外部依賴的cdn路徑的。肯定不是我們需要的,這太笨了。

需要解決的問題:

a. 不打包指定的外部依賴
b. 在index.html自動引入外部依賴

怎么運用externals:
例如:
在index.html中引入CDN的資源react全家桶之類的資源

<script src="https://lib.baomitu.com/react/16.4.0-alpha.7926752/cjs/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.2/cjs/react-dom-server.browser.development.js"></script>

webpack.config.js配置如下:

  module.exports = {
     ...
     output: {
       ...
     },
     externals : {
        xlsx: 'XLSX', 
        lodash: {
            commonjs: 'lodash',
            amd: 'lodash',
            root: '_', // 指向全局變量
        },
        redux:'redux',
      // 暫時注釋,此庫采用cdn引入,會導致報錯,cdn引入方式,是暴露了X6全局變量,Graph等屬性是掛載在X6全局變量里面,
      // 但是里面掛載的對象屬性都不一樣。暫未找到解決方案
      // '@antv/x6': 'X6',  
       'jquery':'jQuery'  // 由于@antv/x6依賴了jQuery,這里配置忽略,采用cdn方式引入
     }
   }

這樣的話在應用程序中依舊可以以import的方式(還支持其他方式)引用:

import XLSX from 'xlsx'
import { createStore, combineReducers, applyMiddleware } from 'redux';

XLSX就是暴露的全局變量,xlsx庫的名稱,例如: import XLSX from 'xlsx'

這樣不僅之前對第三方庫的用法方式不變,還把第三方庫剝離出webpack的打包中,從而加速webpack的打包速度。

完整的externals配置如下,我已經(jīng)將externals對象單獨導出一個文件

image.png

可以看到上面還有個cdn對象,這個對象是干嘛用的,下面我們就來介紹一下。上面我們已經(jīng)介紹了配置externals 來忽略打包了。但是我們不可能真的就每次都去手動引入cdn鏈接,這樣就太蠢了。
此時我們肯定是希望運行打包命令的時候自動加載到模板里面。此時我們就需要借助一個webpack的插件 html-webpack-plugin

html-webpack-plugin的使用

html-webpack-plugin是webpack的一個插件,可以動態(tài)的創(chuàng)建和編輯html內(nèi)容,在html中使用esj語法可以讀取到配置中的參數(shù),簡化了html文件的構建。(ejs知識點請自行百度,類似jsp跟asp的模板語法

最基礎的使用方式

new HtmlWebpackPlugin({
   // 其他默認配置
  cdn: externalConfig// cdn配置
})

定義好了配置則可以再模板里面使用ejs模板語法來讀取這個變量了。模板語法可以if、for等函數(shù)

index.html

<!DOCTYPE html>
<html lang="">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!--配置cdn 的css-->
    <% if(htmlWebpackPlugin.options.cdn){ htmlWebpackPlugin.options.cdn.css.forEach(function(item){%>
      <link href="<%=item%>" rel="prefetch" />
    <% }) }%>
  </head>
  <body>
    <noscript>
      <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
    <!--配置cdn 的js-->
    <% if(htmlWebpackPlugin.options.cdn){ htmlWebpackPlugin.options.cdn.js.forEach(function(item){%>
      <script src="<%=item%>"></script>
    <% }) }%>
  </body>
</html>

可以看到我先判斷有沒有cdn這個變量,然后再循環(huán)遍歷輸出。這樣就實現(xiàn)了編譯之后自動引入cdn外部依賴了。

在vue項目中。我們在vue.config中的 chainWebpack里面,其實我們不需要再去引入html-webpack-plugin這個庫了。因為已經(jīng)集成了的

chainWebpack: config => {
      config.plugin('html').tap((args) => {
        args[0].title = 'edge-compute-platform'

        // 配置cdn
        if (isProduction) {
            args[0].cdn = externalsConfig.cdn
        }
        return args
    })
}

看vue-cli源碼就知道config.plugin('html')就是html-webpack-plugin如果只是簡單定義一個變量而已就是上面這樣的用法。所以到這里引入cdn就完成了。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容