webpack
une application web en utilisant webpack
et webpack
comme mon bundler de modules. Mon code jsx
est vraiment léger jusqu’à présent, la taille de tout le dossier est de 25 kb.
Mon bundle.js
créé à partir de webpack
est 2.2 Mo cependant. Après avoir exécuté l’optimisation avec l’indicateur -p
, il réduit le bundle à 700 ko, ce qui est encore extrêmement important.
J’ai regardé dans le fichier react.min.js
et sa taille est 130kb.
Est-il possible que le webpack produise de si gros fichiers ou est-ce que je fais quelque chose de mal?
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" }] } };
MODIFIER
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" } }
Selon vos commentaires, vous utilisez material-ui
et react-bootstrap
. Ces dépendances sont regroupées par webpack avec vos paquets de react
et de react-dom
. Chaque fois que vous avez require
ou import
un paquet, il est inclus dans le fichier de votre paquet.
Et voilà que je devine. Vous importez probablement les composants material-ui
react-bootstrap
et material-ui
utilisant la méthode bibliothèque :
import { Button } from 'react-bootstrap'; import { FlatButton } from 'material-ui';
C’est bien pratique, mais il ne regroupe pas seulement Button
et FlatButton
(et leurs dépendances), mais aussi toutes les bibliothèques.
Une façon de l’atténuer est d’essayer uniquement d’ import
ou de require
ce qui est nécessaire, disons la façon dont les composants . En utilisant le même exemple:
import Button from 'react-bootstrap/lib/Button'; import FlatButton from 'material-ui/lib/flat-button';
Cela ne regroupera que Button
, FlatButton
et leurs dépendances respectives. Mais pas toute la bibliothèque. J’essaierais donc de me débarrasser de toutes vos importations de bibliothèque et d’utiliser plutôt le composant .
Si vous n’utilisez pas beaucoup de composants, cela devrait réduire considérablement la taille de votre fichier groupé.
Comme autre explication:
Lorsque vous utilisez le mode bibliothèque , vous importez tous ces composants react -bootstrap et tous ces composants ui-matières , quels que soient ceux que vous utilisez réellement.
01/2017 EDIT – J’ai depuis appris un peu plus sur les différents plugins Webpack, et je voulais le mettre à jour. Il s’avère que UglifyJS a un petit nombre d’options de configuration qui ne semblent pas très courantes, mais peut avoir un effet dramatique sur la taille de votre bundle. Ceci est ma configuration actuelle avec quelques annotations (les documents sur site sont géniaux):
new webpack.optimize.UglifyJsPlugin({ comments: false, // remove comments compress: { unused: true, dead_code: true, // big one--ssortingp 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, // ssortingps console statements sequences: true, booleans: true, } })
Une fois, j’ai rencontré un problème obscur avec la uglify
des caractères unicode échappés, alors soyez attentif si vous employez ces transformations comme celles-ci sont possibles.
Vous pouvez en savoir plus sur les options spécifiques webpack
charge par webpack
dans les documents Webpack avec des liens vers d’autres lectures.
(note sidenote: je pense que votre package.json est mélangé … au moins quelques-unes de ces dépendances de dev sont des dépendances dans chaque package.json que j’ai vu (par exemple, le kit de démarrage de réaction )
Si vous vous préparez à la production, vous devez suivre quelques étapes supplémentaires pour réduire la taille de votre fichier. Voici un extrait de mon webpack.config.js:
plugins: [ new webpack.optimize.UglifyJsPlugin(), new webpack.optimize.DedupePlugin(), new webpack.DefinePlugin({ 'process.env': { 'NODE_ENV': JSON.ssortingngify('production') } }) ],
1) Minifie / règle votre code
2) remplace le code en double pour minimiser la taille du fichier
3) dit à Webpack d’omettre certaines choses qu’il utilise pour les builds d’environnement de noeuds
Enfin, si vous utilisez une carte source (que vous devriez probablement), vous voudrez append la ligne appropriée. Sentry a écrit un article sur ce blog .
Dans ma version, j’utilise devtool: 'source-map'
pour la production
MISE À JOUR 18/05: mise à jour du paramètre UglifyJsPlugin pour une meilleure minification
J’utilise la configuration ci-dessous pour la minification dans le code de production.
plugins: [ new webpack.DefinePlugin({ 'process.env': { // This has effect on the react lib size 'NODE_ENV': JSON.ssortingngify('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 }) ],
Avez-vous regardé comment vos scripts sont envoyés sur le réseau … J’ai eu des composants de réaction très simples qui étaient autour de 300kb chacun, et ceci après les optimisations de webpack. Après avoir été aspergés, ils sont tombés à 38 kb. Encore considérable – mais c’est ce que nous obtenons pour utiliser les fonctionnalités de demain aujourd’hui. Si vous utilisez node / express pour servir des ressources statiques, y compris votre javascript – regardez la compression ( https://github.com/expressjs/compression ). Je suggère également de consulter le guide des meilleures pratiques pour la production du noeud https://expressjs.com/en/advanced/best-practice-performance.html aura des options pour la compression des fichiers texte.
Je trouve utile de mentionner l’utilitaire source-map-explorer qui aide à savoir ce que contient exactement votre fichier bundle.js. Cela peut vous aider à identifier s’il y a des choses inutiles dans le paquet js. vous pouvez installer l’explorateur de carte source à partir de npm et l’utiliser comme
source-map-explorer yourBundle.js
En outre, comme mentionné par @kimmiju, vérifiez si votre serveur utilise une certaine compression.
Vous pouvez également essayer de charger les itinéraires de manière asynchrone (chargement différé dans Webpack), afin que votre fichier bundlejs entier ne soit pas envoyé en une seule fois, au lieu de cela, il est envoyé en morceaux lorsque l’utilisateur navigue vers ces itinéraires.