Webpack cara membuat kode produksi dan cara menggunakannya

95

Saya sangat baru mengenal webpack, saya menemukan bahwa dalam produksi build kami dapat mengurangi ukuran kode secara keseluruhan. Saat ini webpack membuat sekitar 8MB file dan main.js sekitar 5MB. Bagaimana cara mengurangi ukuran kode dalam produksi build? Saya menemukan contoh file konfigurasi webpack dari internet dan saya mengonfigurasi untuk aplikasi saya dan saya menjalankan npm run builddan mulai membangun dan menghasilkan beberapa file dalam ./dist/direktori.

  1. Masih file-file ini berat (sama dengan versi pengembangan)
  2. Bagaimana cara menggunakan file-file ini? Saat ini saya menggunakan webpack-dev-server untuk menjalankan aplikasi.

package.json file

{
  "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]
  }
};
Gilson PJ
sumber
1
Apakah Anda menemukan jawaban untuk pertanyaan terakhir Anda? "Bagaimana cara menggunakan file ini? Saat ini saya menggunakan webpack-dev-server untuk menjalankan aplikasi."
Randy
4
Internet jauh lebih baik sebelum webpack, lihat saja pertanyaan ini dan jawabannya.
Randy L

Jawaban:

66

Anda dapat menambahkan plugin seperti yang disarankan oleh @Vikramaditya. Kemudian untuk menghasilkan build produksi. Anda harus menjalankan perintah

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

The -pmemberitahu Webpack untuk menghasilkan membangun produksi. Anda harus mengubah skrip build di package.json untuk menyertakan flag produksi.

sandeep
sumber
7
Ok terima kasih. keraguan saya selanjutnya adalah bagaimana menjalankan kode produksi? ketika saya menjalankan perintah di atas itu membuat beberapa file di direktori dist. ok itu berhasil dikompilasi. sekarang bagaimana cara menggunakan file-file ini? dalam mode pengembangan saya menggunakan 'npm start' dan dimulai.
Gilson PJ
Jika Anda pergi ke src/server/bin/server. Kemudian Anda dapat mengetahui bagaimana itu melayani file dan mungkin mengubahnya. Apa yang saya pikir akan lakukan adalah menjalankan webpack untuk membangun file dan kemudian melayani mereka. Lihat kode file ini.
sandeep
@Vikramaditya Bisakah Anda membantu saya dengan skenario di stackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul
@GilsonPJ, apakah Anda mengetahui cara menggunakan file UI ini?
Randy
Anda perlu menginstal webpack terlebih dahulu menggunakannpm install webpack
Peter Rader
43

Setelah mengamati jumlah penonton pertanyaan ini, saya memutuskan untuk menyimpulkan jawaban dari Vikramaditya dan Sandeep.

Untuk membuat kode produksi, hal pertama yang harus Anda buat adalah konfigurasi produksi dengan paket pengoptimalan seperti,

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

Kemudian di file package.json Anda dapat mengonfigurasi prosedur build dengan konfigurasi produksi ini

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

sekarang Anda harus menjalankan perintah berikut untuk memulai build

npm run build

Sesuai dengan konfigurasi build produksi saya, webpack akan membangun source to ./distdirectory.

Sekarang kode UI Anda akan tersedia di ./dist/direktori. Konfigurasikan server Anda untuk menyajikan file-file ini sebagai aset statis. Selesai!

Gilson PJ
sumber
7
Apa yang Anda maksud di kalimat terakhir Anda? Bagaimana cara memberikan kode-kode ini? Saya tahu node.js membangun server sendiri. Tetapi bagaimana saya bisa menjalankannya setelah saya memiliki file di ./dist/direktori?
newguy
6
Sekadar catatan, menambahkan opsi -p di atas plugin uglifyJS menyebabkan masalah karena plugin tersebut mencoba melakukan uglify dua kali. Menghapus opsi -p cli memperbaiki masalah ini untuk saya
timelf123
'NODE_ENV' tidak dikenali sebagai perintah internal atau eksternal, program yang dapat dioperasikan atau file batch.
Anton Duzenko
2
Ini harus menjadi jawaban yang diterima, karena tidak ada yang mengatakan bagaimana melayani situs web Sekarang kode UI Anda akan tersedia di direktori ./dist/. Setel server Anda untuk menyediakan kode UI ini untuk permintaan tersebut. dan kamu selesai.!
jperelli
2
Saya masih tidak mengerti cara "Setel server Anda untuk menyediakan kode UI ini untuk permintaan tersebut. Dan Anda selesai.". Saya mengerti apa yang ingin kami lakukan di sini tetapi saya tidak tahu bagaimana melakukannya
Randy
42

Gunakan plugin ini untuk mengoptimalkan produksi Anda:

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

Saya baru-baru ini mengetahui tentang kompresi-webpack-plugin yang meng-gzip bundel output Anda untuk mengurangi ukurannya. Tambahkan ini juga di daftar plugin yang tercantum di atas untuk lebih mengoptimalkan kode produksi Anda.

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

Kompresi gzip dinamis sisi server tidak disarankan untuk menyajikan file sisi klien statis karena penggunaan CPU yang berat.

Vikramaditya
sumber
1
apa yang dilakukan bagian 'common.js' di commonschuckplugin? plugin itu adalah yang paling sulit untuk saya pahami.
Echiban
2
CommonsChunkPlugin mengekstrak kode umum dari semua potongan Anda dan meletakkannya di file terpisah common.js.
Vikramaditya
3
Jawaban ini tidak lagi berlaku untuk webpack versi 4
Dennis
20

Baru mempelajari ini sendiri. Saya akan menjawab pertanyaan kedua:

  1. Bagaimana cara menggunakan file-file ini? Saat ini saya menggunakan webpack-dev-server untuk menjalankan aplikasi.

Alih-alih menggunakan webpack-dev-server, Anda cukup menjalankan "express". gunakan npm install "express" dan buat server.js di direktori root proyek, seperti ini:

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

Kemudian, di package.json, tambahkan skrip:

"start": "node server.js"

Terakhir, jalankan aplikasi: npm run startuntuk memulai server

Contoh detailnya dapat dilihat di: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (kode contoh tidak kompatibel dengan paket terbaru, tetapi akan berfungsi dengan sedikit perubahan)

Siyuan Jiang
sumber
2
Jika Anda mulai mempelajari hal-hal nodejs, expressjs dll, maka saya ingin memberi tahu Anda. Pertanyaan ini adalah pertanyaan tingkat lanjut. Ini bukan hanya untuk Bagaimana menjalankan file-file ini. Ini untuk Cara meminimalkan (mengompres) kode produksi dan cara menjalankan kode terkompresi itu
Arpit
1
@Arpit Terima kasih telah menunjukkan hal ini. Saya sangat baru dalam hal ini. Saya berasumsi setelah kode terkompresi dibuat, metode yang dijalankan harus sama.
Siyuan Jiang
9

Anda dapat menggunakan modul argv npm (instal dengan menjalankan npm install argv --save ) untuk mendapatkan params di file webpack.config.js Anda dan untuk produksi Anda menggunakan -p flag "build": "webpack -p" , Anda dapat tambahkan kondisi di file webpack.config.js seperti di bawah ini

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

Dan hanya itu.

Hayk Aghabekyan
sumber
1
Sebagai gantinya gunakanprocess.argv.indexOf('-p') != -1
AjaxLeung
@AjaxLeung: Anda harus memasukkan argvfile konfigurasi webpack:const argv = require('argv');
kadam
6

Ini akan membantumu.

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
    })
  ],
Khalid Azam
sumber
5

Selain jawaban Gilson PJ:

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

dengan

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

karena itu mencoba untuk memperjelas kode Anda dua kali. Lihat https://webpack.github.io/docs/cli.html#production-shortcut-p untuk informasi lebih lanjut.

Anda dapat memperbaikinya dengan menghapus UglifyJsPlugin dari plugins-array atau menambahkan OccurrenceOrderPlugin dan menghapus "-p" -flag. jadi salah satu solusi yang mungkin adalah

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

dan

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

Jika Anda memiliki banyak kode duplikat di webpack.dev.config dan webpack.prod.config Anda, Anda dapat menggunakan boolean isProduntuk mengaktifkan fitur tertentu hanya dalam situasi tertentu dan hanya memiliki satu 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
    }));
  }

By the way: Plugin DedupePlugin telah dihapus dari Webpack. Anda harus menghapusnya dari konfigurasi Anda.

MEMPERBARUI:

Selain jawaban saya sebelumnya:

Jika Anda ingin menyembunyikan kode Anda untuk rilis, coba enclosejs.com . Ini memungkinkan Anda untuk:

  • buat versi rilis aplikasi Anda tanpa sumber
  • membuat arsip atau pemasang yang mengekstrak sendiri
  • Buat aplikasi GUI sumber tertutup
  • Letakkan aset Anda di dalam file yang dapat dieksekusi

Anda dapat menginstalnya dengan npm install -g enclose

MatthiasSommer
sumber