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

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.


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!


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.


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)


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.


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

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"
},

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.