Вы когда-нибудь задумывались, почему размер вашего пакета так велик только для того, чтобы использовать несколько зависимостей?
Я создал простой проект с несколькими производственными зависимостями - React, ReactDOM и компонент Button из response-bootstrap.
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'react-bootstrap';
После этого я запустил webpack в продакшене и был шокирован размером пакета даже в продакшене! 359 КБ - это довольно много для отправки, особенно для начинающих пользователей, которые потенциально могут иметь очень медленное подключение к Интернету. Мы можем выполнить некоторое разделение кода и кэширование для повторного использования ресурсов, но все же это всего лишь простое минимальное приложение, которое не должно быть таким большим - все, что я сделал, это подключил приложение Hello World к DOM с помощью кнопки из react-bootstrap .
Version: webpack 2.2.1
Time: 20143ms
Asset Size Chunks Chunk Names
bundle.js 359 kB 0 [emitted] [big] main
[0] ./~/react/react.js 55 bytes {0} [built]
[17] ./~/react-dom/index.js 58 bytes {0} [built]
[24] ./~/react-bootstrap/es/SafeAnchor.js 3.75 kB {0} [built]
[25] ./~/react-dom/lib/ReactUpdates.js 9.67 kB {0} [built]
[44] ./~/react-dom/lib/ReactReconciler.js 6.29 kB {0} [built]
[45] ./~/react/lib/React.js 2.71 kB {0} [built]
[194] ./src/App.js 64 bytes {0} [built]
[314] ./~/react-bootstrap/es/Pager.js 2.93 kB {0} [built]
[331] ./~/react-bootstrap/es/index.js 10.8 kB {0} [built]
[349] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built]
[375] ./~/react-dom/lib/ReactVersion.js 350 bytes {0} [built]
[391] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built]
[415] ./~/react/lib/ReactVersion.js 350 bytes {0} [built]
[416] ./~/react/lib/onlyChild.js 1.34 kB {0} [built]
[420] ./src/index.js 781 bytes {0} [built]
+ 406 hidden modules
Что-то точно не так. Итак, я начал с того, что увидел размер файла для двух зависимостей - React и ReactDOM.
Version: webpack 2.2.1
Time: 8397ms
Asset Size Chunks Chunk Names
bundle.js 146 kB 0 [emitted] main
[3] ./~/object-assign/index.js 2.1 kB {0} [built]
[15] ./~/react/lib/React.js 2.71 kB {0} [built]
[16] ./~/react/lib/ReactElement.js 11.6 kB {0} [built]
[76] ./~/react-dom/index.js 58 bytes {0} [built]
[77] ./~/react/react.js 55 bytes {0} [built]
[78] ./src/App.js 65 bytes {0} [built]
[104] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built]
[146] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built]
[154] ./~/react-dom/lib/renderSubtreeIntoContainer.js 422 bytes {0} [built]
[158] ./~/react/lib/ReactClass.js 27.1 kB {0} [built]
[159] ./~/react/lib/ReactDOMFactories.js 5.53 kB {0} [built]
[160] ./~/react/lib/ReactPropTypes.js 16.2 kB {0} [built]
[162] ./~/react/lib/ReactPureComponent.js 1.32 kB {0} [built]
[163] ./~/react/lib/ReactVersion.js 350 bytes {0} [built]
[166] ./src/index.js 781 bytes {0} [built]
+ 152 hidden modules
Окей, примерно ~ 146 КБ. Звучит примерно правильно, согласно спецификациям React. Это означает, что для импорта компонента Button из react-bootstrap потребовалось огромное количество ~ 213 КБ! Эй, подожди минутку. Это явно не имеет смысла. Все, что я сделал, это импортировал Button из react-bootstrap. Мне сейчас не нужна вся библиотека… или нет?
Давайте еще раз посмотрим на импорт.
import React from 'react';
import ReactDOM from 'react-dom';
import { Button } from 'react-bootstrap';
Ага, меня осенило. Теперь я вижу, что сделал. Что происходит «под капотом»?
import { Button } from 'react-bootstrap';
эквивалентен
const { Button } = require('react-bootstrap');
что эквивалентно
const Button = {/*react-bootstrap module*/}.Button;
Итак, в конечном итоге я импортировал всю библиотеку response-bootstrap. Мне пришлось это сделать, прежде чем я смог добраться до кнопки!
Итак, что мы можем сделать, чтобы получить именно то, что мы хотим? Получите это прямо сейчас!
import Button from 'react-bootstrap/lib/Button';
И снова запуск webpack в продакшене дает
Version: webpack 2.2.1
Time: 9681ms
Asset Size Chunks Chunk Names
bundle.js 174 kB 0 [emitted] main
[8] ./~/react-dom/lib/ReactUpdates.js 9.67 kB {0} [built]
[25] ./~/react/lib/React.js 2.71 kB {0} [built]
[28] ./~/react/react.js 55 bytes {0} [built]
[127] ./~/react-dom/index.js 58 bytes {0} [built]
[128] ./src/App.js 213 bytes {0} [built]
[187] ./~/react-bootstrap/lib/Button.js 4.47 kB {0} [built]
[203] ./~/react-dom/lib/ReactDOM.js 5.16 kB {0} [built]
[229] ./~/react-dom/lib/ReactVersion.js 350 bytes {0} [built]
[245] ./~/react-dom/lib/findDOMNode.js 2.46 kB {0} [built]
[253] ./~/react-dom/lib/renderSubtreeIntoContainer.js 422 bytes {0} [built]
[257] ./~/react/lib/ReactChildren.js 6.19 kB {0} [built]
[258] ./~/react/lib/ReactClass.js 27.1 kB {0} [built]
[259] ./~/react/lib/ReactDOMFactories.js 5.53 kB {0} [built]
[260] ./~/react/lib/ReactPropTypes.js 16.2 kB {0} [built]
[266] ./src/index.js 781 bytes {0} [built]
+ 252 hidden modules
разница в ~ 28kb. Так намного лучше. Но для компонента Button это еще немного =)
Вывод
Урок заключается в том, чтобы всегда проверять размер вашего пакета и проводить базовое сравнение в каждой новой сборке и критически относиться к своим зависимостям. Клиенты всегда на первом месте. Сделайте их счастливыми, и вы будете счастливы. Кроме того, не полагайтесь на деструктуризацию, когда требуются зависимости для уменьшения размера сборки. Это просто для того, чтобы более четко изложить ваши требования.