Подтвердить что ты не робот

Как свести к минимуму размер пакета веб-пакетов?

Я пишу веб-приложение, использующее react и webpack в качестве моего модуля. Мой jsx код действительно светлый, размер всей папки составляет 25 кб.

Мой bundle.js, созданный из webpack, равен 2,2 мб. После выполнения оптимизации с помощью флага -p он уменьшает пакет до 700 кбайт, что по-прежнему чрезвычайно велико.

Я просмотрел файл react.min.js и его размер составляет 130kb.

Возможно ли, что веб-пакет создает такие большие файлы, или я делаю что-то неправильно?

webpack.config.js

var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './public/components/main.jsx',
  output: {
    path: __dirname + "/public",
    filename: 'bundle.js'
  },
  module: {
    loaders: [{
      test: /.jsx?$/,
      loader: 'babel-loader',
      exclude: /node_modules/,
      query: {
        presets: ['es2015', 'react']
      }
    }, {
      test: /\.css$/,
      loader: "style!css"
    }]
  }
};

ИЗМЕНИТЬ

package.json:

{
  "name": "XChange",
  "version": "0.0.0",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "main": "./bin/www",
  "devDependencies": {
    "body-parser": "~1.13.2",
    "cookie-parser": "~1.3.5",
    "debug": "~2.2.0",
    "express": "~4.13.1",
    "jade": "~1.11.0",
    "morgan": "~1.6.1",
    "serve-favicon": "~2.3.0",
    "react-dom": "~0.14.3",
    "react": "~0.14.3",
    "webpack": "~1.12.9",
    "babel-loader": "~6.2.0",
    "babel-core": "~6.2.1",
    "babel-preset-react": "~6.1.18",
    "babel-preset-es2015": "~6.1.18",
    "react-bootstrap": "~0.28.1",
    "material-ui": "~0.14.0-rc1",
    "history": "~1.13.1",
    "react-router": "~1.0.2",
    "style-loader": "~0.13.0",
    "css-loader": "~0.18.0"
  },
  "dependencies": {
    "express-validator": "~2.18.0",
    "mongoose": "~4.2.9",
    "kerberos": "~0.0.17",
    "bcrypt": "~0.8.5"
  }
}
4b9b3361

Ответ 1

В соответствии с вашими комментариями вы используете material-ui и react-bootstrap. Эти зависимости связаны с веб-пакетом вместе с вашими пакетами react и react-dom. Каждый раз, когда вы require или import пакет, он входит в состав вашего пакета.

И здесь я догадываюсь. Вероятно, вы импортируете компоненты react-bootstrap и material-ui, используя путь библиотеки:

import { Button } from 'react-bootstrap';
import { FlatButton } from 'material-ui';

Это удобно и удобно, но это не только пакеты Button и FlatButton (и их зависимости), но библиотеки в целом.

Один из способов облегчить это - попробовать только import или require, что нужно, скажем, компонентный способ. Используя тот же пример:

import Button from 'react-bootstrap/lib/Button';
import FlatButton from 'material-ui/lib/flat-button';

Это будет только связывать Button, FlatButton и их соответствующие зависимости. Но не вся библиотека. Поэтому я попытался бы избавиться от всех ваших импортных библиотек и использовать компонентный способ.

Если вы не используете много компонентов, это должно значительно уменьшить размер вашего связанного файла.

В качестве дополнительного объяснения:

Когда вы используете библиотечный способ, вы импортируете все эти реакционные бутстрапы и все эти материалы-ui, независимо от того, какие из них вы фактически используете.

Ответ 2

01/2017 EDIT. С тех пор я узнал немного больше о разных плагинах Webpack и хотел обновить его. Оказывается, что UglifyJS имеет небольшую конфигурацию опций, которые, похоже, не очень популярны, но могут иметь драматическое влияние на ваш размер пакета. Это моя текущая конфигурация с некоторыми аннотациями (документы на сайте велики):

 new webpack.optimize.UglifyJsPlugin({
      comments: false, // remove comments
      compress: {
        unused: true,
        dead_code: true, // big one--strip code that will never execute
        warnings: false, // good for prod apps so users can't peek behind curtain
        drop_debugger: true,
        conditionals: true,
        evaluate: true,
        drop_console: true, // strips console statements
        sequences: true,
        booleans: true,
      }
    })

Однажды я столкнулся с неясной проблемой с uglify -элементом экранов unicode unicode, поэтому будьте внимательны, если вы используете эти преобразования, чтобы такие кросс-подобные вещи были возможны.

Подробнее о конкретных опциях webpack можно узнать в webpack docs с некоторыми последующими ссылками для дальнейшего чтения.


(sidenote: Я думаю, что ваш пакет .json запутан... по крайней мере некоторые из этих зависимостей dev зависят от каждого пакета. json, который я видел (например, react-starter-kit)

Если вы готовитесь к производству, вы должны предпринять еще несколько шагов, чтобы уменьшить размер вашего файла. Здесь снимок моего webpack.config.js:

 plugins: [


        new webpack.optimize.UglifyJsPlugin(),
        new webpack.optimize.DedupePlugin(),
        new webpack.DefinePlugin({
            'process.env': {
                'NODE_ENV': JSON.stringify('production')
            }
        })
    ],

1) минимизирует/убирает ваш код

2) заменяет дублирующий код, чтобы свести к минимуму размер файла

3) сообщает webpack о том, что он использует для сборки node вещи, которые он использует

Наконец, если вы используете исходную карту (что вам, вероятно, и нужно), вы захотите добавить соответствующую строку. Sentry написал хорошее сообщение в блоге об этом.

В моей сборке я использую devtool: 'source-map' для производства

Ответ 3

ОБНОВЛЕНО 05/18: обновить настройку UglifyJsPlugin для лучшей минимизации

Я использую ниже конфигурацию для минимизации в производственном коде.

 plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        // This has effect on the react lib size
        'NODE_ENV': JSON.stringify('production'),
      }
    }),
    new ExtractTextPlugin("bundle.css", {allChunks: false}),
    new webpack.optimize.AggressiveMergingPlugin(),
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({
      mangle: true,
      compress: {
        warnings: false, // Suppress uglification warnings
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        screw_ie8: true,
        conditionals: true,
        unused: true,
        comparisons: true,
        sequences: true,
        dead_code: true,
        evaluate: true,
        if_return: true,
        join_vars: true
      },
      output: {
        comments: false,
      },
      exclude: [/\.min\.js$/gi] // skip pre-minified libs
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]), 
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    })
  ],

Ответ 4

Вы посмотрели, как вы отправляете скрипты по проводам... У меня были очень простые компоненты реакции, которые составляли около 300 кбайт каждый, и это было после оптимизации веб-пакета. После того, как они были gzipped, они спустились до 38kb. Все еще значительна - но это то, что мы получаем для использования функций tomorrows сегодня. Если вы используете node/express для обслуживания статических ресурсов, включая ваш javascript, посмотрите на сжатие (https://github.com/expressjs/compression). Я также предлагаю посмотреть руководство по лучшей практике node для производства https://expressjs.com/en/advanced/best-practice-performance.html Если вы не используете файлы через node, тогда у apache (или другого веб-сервера) будут опции для сжатия текстовых файлов.