web-dev-qa-db-fra.com

Webpack comment construire le code de production et comment l'utiliser

Je suis très nouveau dans WebPack, j'ai découvert qu'en production, nous pouvions réduire la taille du code. Actuellement, webpack construit environ 8 Mo de fichiers et main.js environ 5 Mo. Comment réduire la taille du code en production? J'ai trouvé un exemple de fichier de configuration Webpack sur Internet, configuré pour mon application et j'exécute npm run build, ainsi que sa construction démarrée. Il a généré des fichiers dans le répertoire ./dist/.

  1. Pourtant, ces fichiers sont lourds (identique à la version de développement)
  2. Comment utiliser ces fichiers? J'utilise actuellement webpack-dev-server pour exécuter l'application.

fichier package.json

{
  "name": "MyAPP",
  "version": "0.1.0",
  "description": "",
  "main": "src/server/server.js",
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [
  ],
  "author": "Iam",
  "license": "MIT",
  "homepage": "http://example.com",
  "scripts": {
    "test": "",
    "start": "babel-node src/server/bin/server",
    "build": "rimraf dist && NODE_ENV=production webpack --config ./webpack.production.config.js --progress --profile --colors"
  },
  "dependencies": {
    "scripts" : "", ...
  },
  "devDependencies": {
    "scripts" : "", ...
  }
}

webpack.config.js

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var public_dir = "src/frontend";
var ModernizrWebpackPlugin = require('modernizr-webpack-plugin');

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    'webpack-hot-middleware/client?reload=true',
    path.join(__dirname, public_dir , 'main.js')
  ],
  output: {
    path: path.join(__dirname, '/dist/'),
    filename: '[name].js',
    publicPath: '/'
  },
  plugins: [
    plugins
  ],
  module: {
    loaders: [loaders]
  }
};

webpack.production.config.js

var path = require('path');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var public_dir = "src/frontend";
var ModernizrWebpackPlugin = require('modernizr-webpack-plugin');
console.log(path.join(__dirname, 'src/frontend' , 'index.html'));

module.exports = {
  devtool: 'eval-source-map',
  entry: [
    'webpack-hot-middleware/client?reload=true',
    path.join(__dirname, 'src/frontend' , 'main.js')
  ],
  output: {
    path: path.join(__dirname, '/dist/'),
    filename: '[name].js',
    publicPath: '/'
  },
  plugins: [plugins],
  resolve: {
    root: [path.resolve('./src/frontend/utils'), path.resolve('./src/frontend')],
    extensions: ['', '.js', '.css']
  },

  module: {
    loaders: [loaders]
  }
};
82
Gilson PJ

Après avoir observé le nombre de téléspectateurs sur cette question, j'ai décidé de conclure une réponse de Vikramaditya et Sandeep.

Pour construire le code de production, la première chose à créer est une configuration de production avec des packages d’optimisation tels que,

  new webpack.optimize.CommonsChunkPlugin('common.js'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()

Ensuite, dans le fichier package.json, vous pouvez configurer la procédure de construction avec cette configuration de production.

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},

maintenant vous devez lancer la commande suivante pour lancer la construction

npm run build

Conformément à ma configuration de production, Webpack construira la source dans le répertoire ./dist.

Votre code d'interface utilisateur sera maintenant disponible dans le répertoire ./dist/. Configurez votre serveur pour traiter ces fichiers sous forme d'actifs statiques. Terminé!

36
Gilson PJ

Vous pouvez ajouter les plugins comme suggéré par @Vikramaditya. Ensuite, pour générer la version de production. Vous devez exécuter la commande

webpack -p --config ./webpack.production.config.js

-p indique à Webpack de générer une version de production. Vous devez modifier le script de construction dans package.json pour inclure l'indicateur de production.

57
sandeep

Utilisez ces plugins pour optimiser votre production:

  new webpack.optimize.CommonsChunkPlugin('common'),
  new webpack.optimize.DedupePlugin(),
  new webpack.optimize.UglifyJsPlugin(),
  new webpack.optimize.AggressiveMergingPlugin()

J'ai récemment appris à connaître compression-webpack-plugin lequel gzips votre paquet de sortie pour réduire sa taille. Ajoutez-le également à la liste des plug-ins énumérés ci-dessus pour optimiser davantage votre code de production.

new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0.8
})

La compression gzip dynamique côté serveur n'est pas recommandée pour servir des fichiers statiques côté client en raison d'une utilisation intensive du processeur.

39
Vikramaditya

Je viens d'apprendre cela moi-même. Je vais répondre à la deuxième question:

  1. Comment utiliser ces fichiers? J'utilise actuellement webpack-dev-server pour exécuter l'application.

Au lieu d'utiliser webpack-dev-server, vous pouvez simplement exécuter un "express". utilisez npm install "express" et créez un fichier server.js dans le répertoire racine du projet, à peu près comme ceci:

var path = require("path");
var express = require("express");

var DIST_DIR = path.join(__dirname, "build");
var PORT = 3000;
var app = express();

//Serving the files on the dist folder
app.use(express.static(DIST_DIR));

//Send index.html when the user access the web
app.get("*", function (req, res) {
  res.sendFile(path.join(DIST_DIR, "index.html"));
});

app.listen(PORT);

Ensuite, dans le package.json, ajoutez un script:

"start": "node server.js"

Enfin, lancez l'application: npm run start pour démarrer le serveur.

Un exemple détaillé est disponible à l'adresse suivante: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (le code de l'exemple n'est pas compatible avec le derniers paquets, mais cela fonctionnera avec de petits ajustements)

12
Siyuan Jiang

Vous pouvez utiliser le module argv npm (installez-le en exécutant npm install argv --save ) pour obtenir des paramètres dans votre pack Web. Le fichier config.js et comme pour la production, vous utilisez - p indicateur "build": "webpack -p" , vous pouvez ajouter une condition dans le fichier webpack.config.js comme ci-dessous

plugins: [
    new webpack.DefinePlugin({
        'process.env':{
            'NODE_ENV': argv.p ? JSON.stringify('production') : JSON.stringify('development')
        }
    })
]

Et c'est tout.

8
Hayk Aghabekyan

Cela vous aidera.

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
      },
      output: {
        comments: false,
      },
      exclude: [/\.min\.js$/gi] // skip pre-minified libs
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, [/moment$/]), //https://stackoverflow.com/questions/25384360/how-to-prevent-moment-js-from-loading-locales-with-webpack
    new CompressionPlugin({
      asset: "[path].gz[query]",
      algorithm: "gzip",
      test: /\.js$|\.css$|\.html$/,
      threshold: 10240,
      minRatio: 0
    })
  ],
6
Khalid Azam

En plus de Gilson PJ répondre:

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()

avec

"scripts": {
    "build": "NODE_ENV=production webpack -p --config ./webpack.production.config.js"
},

car il tente d’obstruer votre code deux fois. Voir https://webpack.github.io/docs/cli.html#production-shortcut-p pour plus d'informations.

Vous pouvez résoudre ce problème en supprimant UglifyJsPlugin de plugins-array ou en ajoutant OccurrenceOrderPlugin et en supprimant le "-p" -flag. donc une solution possible serait

 new webpack.optimize.CommonsChunkPlugin('common.js'),
 new webpack.optimize.DedupePlugin(),
 new webpack.optimize.UglifyJsPlugin(),
 new webpack.optimize.OccurrenceOrderPlugin(),
 new webpack.optimize.AggressiveMergingPlugin()

et

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},
4
Putzi San

Si vous avez beaucoup de code en double dans votre webpack.dev.config et votre webpack.prod.config, vous pouvez utiliser un booléen isProd pour activer certaines fonctionnalités uniquement dans certaines situations et ne disposer que d'un seul webpack.config. fichier js.

const isProd = (process.env.NODE_ENV === 'production');

 if (isProd) {
     plugins.Push(new AotPlugin({
      "mainPath": "main.ts",
      "hostReplacementPaths": {
        "environments/index.ts": "environments/index.prod.ts"
      },
      "exclude": [],
      "tsConfigPath": "src/tsconfig.app.json"
    }));
    plugins.Push(new UglifyJsPlugin({
      "mangle": {
        "screw_ie8": true
      },
      "compress": {
        "screw_ie8": true,
        "warnings": false
      },
      "sourceMap": false
    }));
  }

Au fait: Le plugin DedupePlugin a été supprimé de Webpack. Vous devriez le supprimer de votre configuration.

UPDATE:

En plus de ma réponse précédente:

Si vous souhaitez masquer votre code pour publication, essayez enclosejs.com . Cela vous permet de:

  • faire une version finale de votre application sans sources
  • créer une archive ou un installateur auto-extractible
  • Créer une application d'interface graphique à source fermée
  • Mettez vos actifs dans l'exécutable

Vous pouvez l'installer avec npm install -g enclose

2
MatthiasSommer