Webpack, jak zbudować kod produkcyjny i jak go używać

95

Jestem bardzo nowy w pakiecie webpack. Odkryłem, że w wersji produkcyjnej możemy zmniejszyć rozmiar całego kodu. Obecnie pakiet webowy tworzy około 8 MB plików, a main.js około 5 MB. Jak zmniejszyć rozmiar kodu w kompilacji produkcyjnej? Znalazłem przykładowy plik konfiguracyjny webpacka z Internetu i skonfigurowałem dla mojej aplikacji i uruchomiłem npm run buildi rozpoczęto jego budowanie, a on wygenerował kilka plików w ./dist/katalogu.

  1. Nadal te pliki są ciężkie (tak samo jak wersja rozwojowa)
  2. Jak korzystać z tych plików? Obecnie używam webpack-dev-server do uruchamiania aplikacji.

plik 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]
  }
};
Gilson PJ
źródło
1
Czy znalazłeś odpowiedź na swoje ostatnie pytanie? „Jak używać tych plików? Obecnie do uruchomienia aplikacji używam serwera webpack-dev-server”.
Randy
4
Internet był o wiele lepszy przed webpackiem, wystarczy spojrzeć na to pytanie i odpowiedź.
Randy L,

Odpowiedzi:

66

Możesz dodać wtyczki zgodnie z sugestią @Vikramaditya. Następnie, aby wygenerować wersję produkcyjną. Musisz uruchomić polecenie

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

-pMówi WebPack wygenerować build produkcyjny. Musisz zmienić skrypt kompilacji w package.json, aby zawierał flagę Production.

Sandeep
źródło
7
ok dzięki. moja następna wątpliwość to jak uruchomić kod produkcyjny? kiedy uruchamiam powyższe polecenie, tworzy ono pliki w katalogu dist. ok, skompilowano pomyślnie. teraz jak korzystać z tych plików? w trybie programowania użyłem 'npm start' i jego uruchomienie.
Gilson PJ
Jeśli przejdziesz do swojego src/server/bin/server. Następnie możesz dowiedzieć się, jak obsługuje pliki, i może to zmienić. Myślę, że będzie to robił pakiet WebPack w celu tworzenia plików, a następnie ich obsługi. Spójrz na kod tego pliku.
sandeep
@Vikramaditya Czy możesz mi pomóc ze scenariuszem w stackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul
@GilsonPJ Czy odkryłeś, jak używać tych plików interfejsu użytkownika?
Randy
Najpierw musisz zainstalować pakiet webpack za pomocąnpm install webpack
Peter Rader,
43

Po obserwacji liczby widzów na to pytanie zdecydowałem się podsumować odpowiedź Vikramaditya i Sandeep.

Aby zbudować kod produkcyjny, pierwszą rzeczą, którą musisz utworzyć, jest konfiguracja produkcji z pakietami optymalizacyjnymi, takimi jak,

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

Następnie w pliku package.json możesz skonfigurować procedurę kompilacji z tą konfiguracją produkcyjną

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

teraz musisz uruchomić następujące polecenie, aby zainicjować kompilację

npm run build

Zgodnie z moim pakietem konfiguracyjnym kompilacji produkcyjnej, utworzy źródło do ./distkatalogu.

Teraz twój kod UI będzie dostępny w ./dist/katalogu. Skonfiguruj serwer, aby obsługiwał te pliki jako zasoby statyczne. Gotowe!

Gilson PJ
źródło
7
Co masz na myśli w swoim ostatnim zdaniu? Jak dostarczyć te kody? Wiem, że node.js sam buduje serwer. Ale jak mogę go uruchomić po umieszczeniu pliku w ./dist/katalogu?
newguy,
6
Uwaga, dodanie opcji -p na górze wtyczki uglifyJS powoduje problemy, ponieważ próbuje ona dwukrotnie uglify. Usunięcie opcji -p cli rozwiązało te problemy
timelf123
„NODE_ENV” nie jest rozpoznawany jako polecenie wewnętrzne lub zewnętrzne, program operacyjny lub plik wsadowy.
Anton Duzenko
2
To powinna być akceptowana odpowiedź, ponieważ nikt nie mówił, jak obsługiwać witrynę. Teraz Twój kod interfejsu użytkownika będzie dostępny w katalogu ./dist/. Ustaw serwer, aby dostarczał ten kod interfejsu użytkownika dla żądania. i gotowe.!
jperelli
2
Nadal nie rozumiem, jak „Ustaw serwer, aby dostarczał ten kod interfejsu użytkownika dla żądania. I gotowe.”. Rozumiem, co chcemy tutaj zrobić, ale po prostu nie wiem, jak to zrobić
Randy
42

Użyj tych wtyczek, aby zoptymalizować swoją kompilację produkcyjną:

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

Niedawno dowiedziałem się o wtyczce kompresji- webpack, która gzipuje twój pakiet wyjściowy, aby zmniejszyć jego rozmiar. Dodaj to również do powyższej listy wtyczek, aby jeszcze bardziej zoptymalizować kod produkcyjny.

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

Dynamiczna kompresja gzip po stronie serwera nie jest zalecana do obsługi statycznych plików po stronie klienta z powodu dużego obciążenia procesora.

Vikramaditya
źródło
1
co robi część „common.js” na commonschuckplugin? ta wtyczka jest dla mnie najtrudniejsza do uchwycenia.
Echiban
2
CommonsChunkPlugin wyodrębnia wspólny kod ze wszystkich Twoich fragmentów i umieszcza go w oddzielnym pliku common.js.
Vikramaditya
3
Ta odpowiedź nie jest już ważna dla wersji 4 pakietu webpack
Dennis
20

Sam się tego uczę. Odpowiem na drugie pytanie:

  1. Jak korzystać z tych plików? Obecnie używam webpack-dev-server do uruchamiania aplikacji.

Zamiast używać webpack-dev-server, możesz po prostu uruchomić "express". użyj npm install "express" i utwórz server.js w katalogu głównym projektu, coś takiego:

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

Następnie w pliku package.json dodaj skrypt:

"start": "node server.js"

Na koniec uruchom aplikację: npm run startaby uruchomić serwer

Szczegółowy przykład można zobaczyć pod adresem : https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (przykładowy kod nie jest kompatybilny z najnowszymi pakietami, ale zadziała z małymi poprawkami)

Siyuan Jiang
źródło
2
Jeśli zacząłeś uczyć się nodejs, expressjs itp., To chcę ci powiedzieć. To pytanie jest pytaniem na poziomie zaawansowanym. Nie chodzi tylko o sposób uruchamiania tych plików. To dla Jak zminimalizować (skompresować) kod produkcyjny i jak uruchomić ten skompresowany kod
Arpit
1
@Arpit Dzięki za wskazanie tego. Jestem w tym bardzo nowy. Założyłem, że po wygenerowaniu skompresowanego kodu metoda uruchamiania powinna być taka sama.
Siyuan Jiang
9

Możesz użyć modułu argv npm (zainstaluj go uruchamiając npm install argv --save ) do pobrania parametrów w pliku webpack.config.js, a do produkcji możesz użyć flagi -p "build": "webpack -p" , możesz dodaj warunek w pliku webpack.config.js jak poniżej

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

I to wszystko.

Hayk Aghabekyan
źródło
1
Zamiast tego użyjprocess.argv.indexOf('-p') != -1
AjaxLeung
@AjaxLeung: musisz uwzględnić argvw pliku konfiguracyjnym webpacka:const argv = require('argv');
kadam
6

To ci pomoże.

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
źródło
5

Oprócz odpowiedzi Gilson PJ:

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

z

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

powoduje, że dwukrotnie próbuje zdublować twój kod. Więcej informacji można znaleźć pod adresem https://webpack.github.io/docs/cli.html#production-shortcut-p .

Możesz to naprawić, usuwając UglifyJsPlugin z tablicy wtyczek lub dodając wtyczkę OccurrenceOrderPlugin i usuwając flagę „-p”. więc jednym możliwym rozwiązaniem byłoby

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

i

"scripts": {
    "build": "NODE_ENV=production webpack --config ./webpack.production.config.js"
},
Putzi San
źródło
3

Jeśli masz dużo zduplikowanego kodu w swoim pliku webpack.dev.config i pliku webpack.prod.config, możesz użyć wartości logicznej isProddo aktywowania niektórych funkcji tylko w określonych sytuacjach i mieć tylko jeden plik 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
    }));
  }

Przy okazji: wtyczka DedupePlugin została usunięta z Webpacka. Powinieneś usunąć go ze swojej konfiguracji.

AKTUALIZACJA:

Oprócz mojej poprzedniej odpowiedzi:

Jeśli chcesz ukryć swój kod w celu wydania, wypróbuj witrynę pod adresem: enklasejs.com . Pozwala na:

  • stwórz oficjalną wersję swojej aplikacji bez źródeł
  • utwórz samorozpakowujące się archiwum lub instalator
  • Stwórz aplikację GUI o zamkniętym kodzie źródłowym
  • Umieść swoje zasoby w pliku wykonywalnym

Możesz go zainstalować za pomocą npm install -g enclose

MatthiasSommer
źródło