javascript - Varför är min Webpack-bunt så stor?


Jag skriver lite JavaScript som använder Moment.js och Handlebars. Moment.js ska vara 30 KB gzip-komprimerad och Handlebars ska vara mindre än 10 KB gzip-komprimerad. Men när jag använder Webpack för att bunta min kod får jag en resulterande fil som är 271 KB!

Jag installerade webpack-bundle-size-analyzer för att undersöka och upptäckte mycket större filer än förväntat:

webpack --json | webpack-bundle-size-analyzer
moment: 454.54 KB (74.1%)
handlebars: 94.39 KB (15.4%)
twitter-text: 62.3 KB (10.2%)
<self>: 1.94 KB (0.317%)

Jag har en känsla av att jag gör något som orsakar att många onödiga saker laddas eftersom jag förväntade mig en slutfilstorlek på <100 KB.

main.js

var template = require('./template.handlebars')
var Handlebars = require('handlebars/runtime')
var twitter = require('twitter-text')
var moment = require('moment')

webpack.config.js

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

module.exports = {
  entry: './src/main.js',

  output: {
    path: path.resolve(__dirname, './dist'),
    publicPath: '/dist/',
    filename: 'bundle.min.js'
  },

  resolveLoader: {
    root: path.join(__dirname, 'node_modules')
  },

  module: {
    loaders: [
      {
        test: /\.handlebars$/,
        loader: 'handlebars-loader'
      }
    ]
  },

  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
}

Svar #1

Uppdatering den 10 augusti

Du kan hänvisa till detta problem på github/moment. I princip kan du eliminera alla andra lokala inställningar som du inte behöver.

Utdrag ur kommentarerna:

plugins: [
    new webpack.ContextReplacementPlugin(/moment["/]locale$/, /^\.\/(en|zh-tw)$/)
]

Jag tror att webpack redan gjorde sitt bästa. När du tittar i filerna i node_modules/moment/min/

Du kommer att se dessa:

220K  moment-with-locales.min.js
 57K  moment.min.js

Så om du inkluderar ögonblicket med lokaler, verkar 2XXKB rimligt. För att ytterligare minska storleken kan du försöka

  1. inkludera momentet utan lokaler explicit

    var moment = require('moment/min/moment.min')
    // if you dun need the locale support
    
  2. Eller så kan du försöka komprimera din utdata med gz manuellt med detta plugin compression-webpack-plugin.

Svar #2

Lägg till IgnorePlugin i webpack.config.js-filen och importera locale/xx som du behöver.

Läs mer: https://webpack.js.org/plugins/ignore-plugin/

const webpack = require('webpack')
new webpack.IgnorePlugin({
  resourceRegExp: /^\.\/locale$/,
  contextRegExp: /moment$/,
});