使用Webpack優化你的第三方庫

本文翻譯自GoogleChromeLabsreact

在webpack項目中使用了第三方庫?使用這些方法能夠縮小bundle!webpack

async

async是一組用於處理異步函數的實用程序。git

一般,您應該使用async-es。它隨ES模塊一塊兒提供,而且更適合webpack打包。github

儘管如此,即便更喜歡使用async,對於優化列表,請參閱async-es部分。web

async-es

async-es是一組用於處理異步函數的實用程序。它與async相同,但它更適合webpack打包。npm

使用babel-plugin-lodash刪除未使用的方法

若是你使用async-es做爲單個導入,你將整個庫打包到應用程序中 —— 即便你只使用它的幾個方法:json

// 您只使用`async.map`,但整個庫被打包
import async from 'async-es';

async.map(['file1', 'file2', 'file3'], fs.stat, function(err, results) {
  console.log(results);
});
複製代碼

使用babel-plugin-lodash只選擇你須要的async-es方法:bootstrap

// 應用Babel以前
import async from 'async-es';

async.map(['file1', 'file2', 'file3'], fs.stat, function(err, results) {
  console.log(results);
});
複製代碼

瀏覽器

// 應用Babel以後
import _map from 'async-es/map';

_map(['file1', 'file2', 'file3'], fs.stat, function(err, results) {
  console.log(results);
});
複製代碼

啓用此插件,以下所示:babel

// .babelrc
{
  "plugins": [["lodash", { "id": ["async-es"] }]],
}
複製代碼

babel-polyfill

babel-polyfill是一個Babel的包,它加載了core-js和一個自定義的再生器運行時。

有關優化列表,請參閱core-js部分。

core-js

core-js是一套用於ES5和ES2015+的polyfill。

使用babel-preset-env刪除沒必要要的polyfill

若是使用Babel和babel-preset-env編譯代碼,請添加useBuiltIns: true選項。此選項將Babel配置爲僅包含目標瀏覽器所必需的polyfill。例如,若是您將應用程序定位爲支持Internet Explorer 11:

// .babelrc
{
  "presets": [
    [
      "env",
      {
        "targets": {
          "browsers": ["last 2 versions", "ie >= 11"]
        }
      }
    ]
  ]
}
複製代碼

啓用useBuiltIns: true將刪除Internet Explorer 11已支持的全部功能(例如Object.createObject.keys等)的polyfill。

將非轉換代碼發送到現代瀏覽器

全部支持<script type ="module">的瀏覽器也支持現代JS功能,如async/await,箭頭函數和類。使用此功能構建bundle的兩個版本,並使現代瀏覽器僅加載現代代碼。有關指南,請參閱Philip Walton的文章

date-fns

date-fns是一個日期實用程序庫。

啓用babel-plugin-date-fns

babel-plugin-date-fns使用特定日期函數函數的導入替換date-fns的完整導入:

import { format } from 'date-fns';
format(new Date(2014, 1, 11), 'MM/DD/YYYY');
複製代碼

import _format from 'date-fns/format';
_format(new Date(2014, 1, 11), 'MM/DD/YYYY');
複製代碼

lodash

Lodash是一個實用程序庫。

啓用babel-plugin-lodash

babel-plugin-lodash經過導入特定的Lodash功能取代了完整的Lodash導入:

import _ from 'lodash';
_.map([1, 2, 3], i => i + 1);
複製代碼

import _map from 'lodash/map';
_map([1, 2, 3], i => i + 1);
複製代碼

注意:該插件不適用於方法鏈 - 好比這樣的代碼不會被優化。

_([1, 2, 3]).map(i => i + 1).value();
複製代碼

lodash-es別名爲lodash

一些依賴項可能使用lodash-es而不是lodash。若是是這樣的話,Lodash將打包兩次。

爲避免這種狀況,請將lodash-es包別名爲lodash

// webpack.config.js
module.exports = {
  resolve: {
    alias: {
      'lodash-es': 'lodash',
    },
  },
};
複製代碼

啓用lodash-webpack-plugin

lodash-webpack-plugin剝離了你不須要的Lodash功能部分。例如,若是您使用_.get()但不須要深層路徑支持,則此插件能夠刪除它。將其添加到您的webpack配置中以使打包更小。

請謹慎使用該插件。 默認設置會刪除許多功能,您的應用可能會使用其中一些功能。

lodash-es

lodash-es是Lodash的ES模塊。

有關優化列表,請參閱lodash部分⤴。

moment

Moment.js是一個處理日期的庫。

使用moment-locales-webpack-plugin刪除未使用的語言

默認狀況下,Moment.js附帶160多KB壓縮後的本地化文件。若是您的應用程序僅提供幾種語言,則不須要全部這些文件。使用moment-locales-webpack-plugin刪除未使用的語言。

請謹慎使用該插件。 默認設置刪除全部區域設置;若是您使用其中一些,這可能會破壞您的應用。

react

React是一個用於構建用戶界面的庫。

刪除生產中的propTypes聲明

React不會在生產中執行propTypes檢查,但propTypes聲明仍然佔用了bundle的一部分。 使用babel-plugin-transform-react-remove-prop-types從構建過程當中刪除它們。

遷移到另外一個相似React的庫

React的替代品具備相似的API,具備更小的尺寸或更高的性能,但缺乏一些功能(例如,Fragments, Portals或合成事件)。

  • Preact | 最小的React替代方案(preact@8.3.1 + preact-compat@3.18.3 7.6 kB gzipped; react@16.4.0 + react-dom@16.4.0 31.4 kB gzipped)| 沒有合成事件| IE8支持polyfill

  • Nerv | 比React小,比Preact大(nervjs@1.3.3 9.8 kB gzipped,不須要compat; react@16.4.0 + react-dom@16.4.0 31.4 kB gzipped)| Nerv的目標是100%使用相同的API(沒有Fiber和Suspense),詳見NervJS/nerv#10 | IE8支持

  • Inferno | 比React小,大於Preact和Nerv(inferno@5.4.2 + inferno-compat@5.4.2 11.3 kB gzipped; react@16.4.0 + react-dom@16.4.0 31.4 kB gzipped)| 比React更高的運行時性能,是全部React替代品中性能最高的,提供了手動優化的可能性 部分合成事件| IE8原生不受支持

謹慎遷移到替代品。 一些替代品沒有合成事件或缺乏一些React 16功能(Preact issue, Inferno issue, Nerv issue)。 可是,許多項目仍然能夠在沒有任何代碼庫更改的狀況下進行遷移。 請參閱遷移指南:Preact, Inferno, Nerv

reactstrap

Reactstrap是基於Bootstrap 4的React庫。

使用babel-plugin-transform-imports刪除未使用的模塊

從Reactstrap導入模塊時:

import { Alert } from 'reactstrap';
複製代碼

其餘Reactstrap模塊也打包到應用程序中並使其更大。

使用babel-plugin-transform-imports去除未使用的模塊:

// .babelrc
{
  "plugins": [
    ["transform-imports", {
      "reactstrap": {
        "transform": "reactstrap/lib/${member}",
        "preventFullImport": true
      }
    }]
  ]
}
複製代碼

要了解它是如何工做的,請查看babel-plugin-transform-imports部分。

react-bootstrap

react-bootstrap是基於React的Bootstrap 3庫。

使用babel-plugin-transform-imports刪除未使用的模塊

react-bootstrap導入模塊時:

import { Alert } from 'react-bootstrap';
複製代碼

其餘react-bootstrap模塊也會打包到應用程序中並使其更大。

使用babel-plugin-transform-imports去除未使用的模塊:

// .babelrc
{
  "plugins": [
    ["transform-imports", {
      "react-bootstrap": {
        "transform": "react-bootstrap/es/${member}",
        "preventFullImport": true
      }
    }]
  ]
}
複製代碼

要了解它是如何工做的,請查看babel-plugin-transform-imports部分

react-router

React Router是React的流行路由器解決方案。

使用babel-plugin-transform-imports刪除未使用的模塊

從React Router導入模塊時:

import { withRouter } from 'react-router';
複製代碼

其餘React Router模塊也會打包到應用程序中並使其更大。

使用babel-plugin-transform-imports去除未使用的模塊:

// .babelrc
{
  "plugins": [
    ["transform-imports", {
      "react-router": {
        "transform": "react-router/${member}",
        "preventFullImport": true
      }
    }]
  ]
}
複製代碼

(這是使用React Router v4測試的。)

要了解它是如何工做的,請查看babel-plugin-transform-imports部分。

styled-components

styled-components是一個CSS-in-JS庫。

使用babel-plugin-styled-components壓縮代碼

babel-plugin-styled-components插件能夠壓縮用styled-components編寫的CSS代碼。請參閱相關文檔

whatwg-fetch

whatwg-fetch是一個完整的window.fetch() polyfill。

替換爲unfetch

unfetchwindow.fetch()的500字節polyfill。與whatwg-fetch不一樣,它不支持完整的window.fetch() API,而是專一於polyfill最經常使用的部分。

謹慎遷移到unfetch 雖然它支持最流行的API部分,但若是它依賴於不太常見的東西,您的應用可能會沒法正常運行。

適用於多個庫的解決方案

固然,也有其餘庫的優化技巧。你能夠將它們與常識一塊兒使用,以得到更小或更高性能的bundle包。

babel-plugin-transform-imports

這個方便的babel插件會將您的導入轉換爲僅導入特定組件,這可確保不會包含整個庫。

// Before
import { Grid, Row, Col } from 'react-bootstrap';
// After
import Grid from 'react-bootstrap/lib/Grid';
import Row from 'react-bootstrap/lib/Row';
import Col from 'react-bootstrap/lib/Col';
複製代碼
相關文章
相關標籤/搜索