Webpack come costruire codice di produzione e come usarlo


95

Sono molto nuovo nel webpack, ho scoperto che nella build di produzione possiamo ridurre le dimensioni del codice complessivo. Attualmente webpack costruisce circa 8 MB di file e main.js circa 5 MB. Come ridurre le dimensioni del codice nella build di produzione? Ho trovato un file di configurazione del pacchetto web di esempio da Internet e l'ho configurato per la mia applicazione, lo corro npm run builde la sua creazione ha iniziato a generare alcuni file nella ./dist/directory.

  1. Tuttavia questi file sono pesanti (come la versione di sviluppo)
  2. Come utilizzare questi file? Attualmente sto usando webpack-dev-server per eseguire l'applicazione.

file 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]
  }
};

1
Hai trovato una risposta alla tua ultima domanda? "Come usare questi file? Attualmente sto usando webpack-dev-server per eseguire l'applicazione."
Randy

4
Internet era molto meglio prima del webpack, basta guardare questa domanda e la risposta.
Randy L

Risposte:


66

Puoi aggiungere i plugin come suggerito da @Vikramaditya. Quindi per generare la build di produzione. Devi eseguire il comando

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

Il -pwebpack dice di generare una build di produzione. È necessario modificare lo script di compilazione in package.json per includere il flag di produzione.


6
ok grazie. il mio prossimo dubbio è come eseguire il codice di produzione? quando eseguo il comando sopra, crea alcuni file nella directory dist. ok è stato compilato con successo. ora come utilizzare questi file? in modalità di sviluppo ho usato 'npm start' ed è stato avviato.
Gilson PJ

Se vai al tuo src/server/bin/server. Quindi puoi capire come sta servendo i file e magari cambiarlo. Quello che penso che farà è eseguire webpack per creare file e poi servirli. Dai un'occhiata al codice di questo file.
sandeep

@Vikramaditya Potresti aiutarmi con lo scenario in stackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul

@ GilsonPJ hai capito come utilizzare questi file dell'interfaccia utente?
Randy

È necessario installare prima il webpack utilizzandonpm install webpack
Peter Rader

43

Dopo aver osservato il numero di spettatori a questa domanda, ho deciso di concludere una risposta di Vikramaditya e Sandeep.

Per costruire il codice di produzione la prima cosa che devi creare è la configurazione della produzione con pacchetti di ottimizzazione come,

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

Quindi nel file package.json è possibile configurare la procedura di compilazione con questa configurazione di produzione

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

ora devi eseguire il seguente comando per avviare la compilazione

npm run build

Secondo la mia configurazione di build di produzione, il webpack creerà il sorgente nella ./distdirectory.

Ora il codice dell'interfaccia utente sarà disponibile nella ./dist/directory. Configura il tuo server per servire questi file come risorse statiche. Fatto!


7
Cosa intendi nella tua ultima frase? Come fornire questi codici? So che node.js crea un server in sé. Ma come posso eseguirlo dopo che ho il file nella ./dist/directory?
newguy

6
Solo una nota, l'aggiunta dell'opzione -p sopra il plug-in uglifyJS causa problemi in quanto cerca di sgretolare due volte. La rimozione dell'opzione -p cli ha risolto questi problemi per me
timelf123

"NODE_ENV" non è riconosciuto come comando interno o esterno, programma eseguibile o file batch.
Anton Duzenko

2
Questa dovrebbe essere la risposta accettata, perché nessuno stava dicendo come servire il sito Web. Ora il tuo codice dell'interfaccia utente sarà disponibile nella directory ./dist/. Imposta il tuo server per fornire questi codici UI per la richiesta. e il gioco è fatto.!
jperelli

2
Continuo a non capire come "Impostare il server in modo che fornisca il codice dell'interfaccia utente per la richiesta. E il gioco è fatto.". Capisco cosa vogliamo fare qui ma semplicemente non so come farlo
Randy

42

Usa questi plugin per ottimizzare la tua build di produzione:

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

Recentemente sono venuto a conoscenza del plugin di compressione-webpack che comprime il tuo pacchetto di output per ridurne le dimensioni. Aggiungilo anche nell'elenco dei plugin sopra elencati per ottimizzare ulteriormente il tuo codice di produzione.

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

La compressione gzip dinamica lato server non è consigliata per servire file statici lato client a causa dell'utilizzo intenso della CPU.


1
cosa fa la parte "common.js" su commonschuckplugin? quel plugin è facilmente il più difficile da capire per me.
Echiban

2
CommonsChunkPlugin estrae il codice comune da tutti i tuoi blocchi e lo inserisce in un file separato common.js.
Vikramaditya

3
Questa risposta non è più valida per la versione webpack 4
Dennis

20

Sto imparando questo da solo. Risponderò alla seconda domanda:

  1. Come utilizzare questi file? Attualmente sto usando webpack-dev-server per eseguire l'applicazione.

Invece di usare webpack-dev-server, puoi semplicemente eseguire un "express". usa npm install "express" e crea un server.js nella directory root del progetto, qualcosa del genere:

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);

Quindi, in package.json, aggiungi uno script:

"start": "node server.js"

Infine, esegui l'app: npm run startper avviare il server

Un esempio dettagliato può essere visto su: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (il codice di esempio non è compatibile con i pacchetti più recenti, ma funzionerà con piccole modifiche)


2
Se hai iniziato a imparare cose su nodejs, expressjs ecc, allora voglio dirtelo. Questa domanda è una domanda di livello avanzato. Non è solo per come eseguire questi file. È per come minimizzare (comprimere) il codice di produzione e come eseguire quel codice compresso
Arpit

1
@ Arpit Grazie per averlo sottolineato. Sono molto nuovo a questo. Ho pensato che una volta generato il codice compresso, il metodo di esecuzione dovrebbe essere lo stesso.
Siyuan Jiang

9

Puoi usare il modulo argv npm (installalo eseguendo npm install argv --save ) per ottenere i parametri nel tuo file webpack.config.js e per la produzione usi -p flag "build": "webpack -p" , puoi aggiungi la condizione nel file webpack.config.js come sotto

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

E questo è tutto.


1
Usa inveceprocess.argv.indexOf('-p') != -1
AjaxLeung

@AjaxLeung: devi includere argvnel file di configurazione del webpack:const argv = require('argv');
kadam

6

Questo ti aiuterà.

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$/]), ///programming/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
    })
  ],

5

Oltre alla risposta di Gilson PJ:

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

con

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

perché prova a rendere il tuo codice inadeguato due volte. Vedere https://webpack.github.io/docs/cli.html#production-shortcut-p per ulteriori informazioni.

Puoi risolvere questo problema rimuovendo UglifyJsPlugin dall'array dei plug-in o aggiungere OccurrenceOrderPlugin e rimuovere il flag "-p". quindi una possibile soluzione sarebbe

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

e

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

2

Se hai molto codice duplicato nel tuo webpack.dev.config e nel tuo webpack.prod.config, puoi usare un booleano isProdper attivare alcune funzionalità solo in determinate situazioni e avere solo un singolo file webpack.config.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
    }));
  }

A proposito: il plugin DedupePlugin è stato rimosso da Webpack. Dovresti rimuoverlo dalla tua configurazione.

AGGIORNARE:

Oltre alla mia risposta precedente:

Se vuoi nascondere il tuo codice per il rilascio, prova enclosejs.com . Ti permette di:

  • crea una versione di rilascio della tua applicazione senza sorgenti
  • creare un archivio o un programma di installazione autoestraente
  • Crea un'applicazione GUI closed source
  • Metti le tue risorse all'interno dell'eseguibile

Puoi installarlo con npm install -g enclose

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.