Webpack como construir código de produção e como usá-lo

94

Eu sou muito novo no webpack, descobri que na construção de produção podemos reduzir o tamanho do código geral. Atualmente, o webpack constrói em torno de arquivos de 8 MB e main.js em torno de 5 MB. Como reduzir o tamanho do código na construção de produção? Encontrei um arquivo de configuração de webpack de amostra na internet e configurei para meu aplicativo e executo npm run builde sua construção começou e gerou alguns arquivos no ./dist/diretório.

  1. Ainda assim, esses arquivos são pesados ​​(igual à versão de desenvolvimento)
  2. Como usar esses arquivos? Atualmente estou usando webpack-dev-server para executar o aplicativo.

arquivo 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
fonte
1
Você encontrou uma resposta para sua última pergunta? "Como usar esses arquivos? Atualmente estou usando o webpack-dev-server para executar o aplicativo."
Randy de
4
A internet era muito melhor antes do webpack, é só olhar essa pergunta e a resposta.
Randy L de

Respostas:

65

Você pode adicionar os plug-ins conforme sugerido por @Vikramaditya. Em seguida, para gerar o build de produção. Você tem que executar o comando

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

O -pdiz ao webpack para gerar uma construção de produção. Você precisa alterar o script de construção em package.json para incluir o sinalizador de produção.

sandeep
fonte
6
ok obrigado. minha próxima dúvida é como executar o código de produção? quando executo o comando acima, ele cria alguns arquivos no diretório dist. ok compilou com sucesso. agora como usar esses arquivos? no modo de desenvolvimento, usei 'npm start' e foi iniciado.
Gilson PJ
Se você for para o seu src/server/bin/server. Então você pode descobrir como está servindo os arquivos e talvez alterá-lo. O que eu acho que ele fará é executar o webpack para construir arquivos e depois disponibilizá-los. Dê uma olhada no código deste arquivo.
Sandeep
@Vikramaditya Você poderia me ajudar com o cenário em stackoverflow.com/questions/40993795/msbuild-and-webpack
lohiarahul
@GilsonPJ você descobriu como usar esses arquivos de IU?
Randy
Você precisa instalar o webpack primeiro usandonpm install webpack
Peter Rader
43

Depois de observar o número de telespectadores a esta pergunta, decidi concluir uma resposta de Vikramaditya e Sandeep.

Para construir o código de produção, a primeira coisa que você precisa criar é a configuração de produção com pacotes de otimização como,

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

Então, no arquivo package.json, você pode configurar o procedimento de construção com esta configuração de produção

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

agora você tem que executar o seguinte comando para iniciar a construção

npm run build

De acordo com minha configuração de produção, o webpack irá construir o ./distdiretório de origem .

Agora, seu código de IU estará disponível no ./dist/diretório. Configure seu servidor para servir esses arquivos como ativos estáticos. Feito!

Gilson PJ
fonte
7
O que você quer dizer com sua última frase? Como fornecer esses códigos? Eu sei que node.js constrói um servidor em si. Mas como posso executá-lo depois de ter o arquivo no ./dist/diretório?
newguy
6
Apenas uma observação: adicionar a opção -p no topo do plugin uglifyJS causa problemas, pois ele tenta o uglify duas vezes. A remoção da opção -p cli corrigiu esses problemas para mim
timelf123
'NODE_ENV' não é reconhecido como um comando interno ou externo, programa operável ou arquivo em lote.
Anton Duzenko de
2
Essa deve ser a resposta aceita, porque ninguém dizia como servir o site. Agora seu código de IU estará disponível no diretório ./dist/. Configure seu servidor para fornecer esses códigos de UI para a solicitação. e pronto.!
jperelli de
2
Ainda não entendi como "Configure seu servidor para fornecer esses códigos de IU para a solicitação. E pronto.". Eu entendo o que queremos fazer aqui, mas simplesmente não sei como fazer
Randy
42

Use estes plug-ins para otimizar sua versão de produção:

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

Recentemente, descobri sobre o compression-webpack-plugin que gzips seu pacote de saída para reduzir seu tamanho. Adicione isso também na lista de plug-ins listados acima para otimizar ainda mais seu código de produção.

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

A compactação gzip dinâmica do lado do servidor não é recomendada para servir arquivos estáticos do lado do cliente devido ao uso intenso da CPU.

Vikramaditya
fonte
1
o que a parte 'common.js' faz no commonschuckplugin? esse plugin é facilmente o mais difícil de entender.
Echiban
2
CommonsChunkPlugin extrai o código comum de todos os seus pedaços e o coloca em um arquivo separado common.js.
Vikramaditya
3
Esta resposta não é mais válida para a versão 4 do webpack
Dennis
20

Só estou aprendendo isso sozinho. Vou responder a segunda pergunta:

  1. Como usar esses arquivos? Atualmente estou usando webpack-dev-server para executar o aplicativo.

Em vez de usar webpack-dev-server, você pode apenas executar um "express". use npm install "express" e crie um server.js no diretório raiz do projeto, algo assim:

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

Em seguida, no package.json, adicione um script:

"start": "node server.js"

Por fim, execute o aplicativo: npm run startpara iniciar o servidor

Um exemplo detalhado pode ser visto em: https://alejandronapoles.com/2016/03/12/the-simplest-webpack-and-express-setup/ (o código de exemplo não é compatível com os pacotes mais recentes, mas funcionará com pequenos ajustes)

Siyuan Jiang
fonte
2
Se você começou a aprender coisas de nodejs, expressjs etc, então eu quero te dizer. Esta questão é uma questão de nível avançado. Não é apenas para saber como executar esses arquivos. É sobre como minimizar (compactar) o código de produção e como executá-lo
Arpit
1
@Arpit Obrigado por apontar isso. Eu sou muito novo nisso. Presumi que, uma vez gerado o código compactado, o método de execução deveria ser o mesmo.
Siyuan Jiang
9

Você pode usar o módulo argv npm (instale-o executando npm install argv --save ) para obter parâmetros em seu arquivo webpack.config.js e, para a produção, use a sinalização -p "build": "webpack -p" , você pode adicionar condição no arquivo webpack.config.js como abaixo

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

E é isso.

Hayk Aghabekyan
fonte
1
Em vez disso, useprocess.argv.indexOf('-p') != -1
AjaxLeung
@AjaxLeung: você deve incluir argvno arquivo de configuração do webpack:const argv = require('argv');
kadam
6

Isso vai te ajudar.

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
fonte
5

Além da resposta de Gilson PJ:

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

com

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

fazer com que ele tente uglificar seu código duas vezes. Consulte https://webpack.github.io/docs/cli.html#production-shortcut-p para obter mais informações.

Você pode corrigir isso removendo o UglifyJsPlugin do array de plug-ins ou adicionando o OccurrenceOrderPlugin e removendo a sinalização "-p". então uma solução possível seria

 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"
},
Putzi San
fonte
2

Se você tiver muitos códigos duplicados em seu webpack.dev.config e em seu webpack.prod.config, poderá usar um booleano isProdpara ativar determinados recursos apenas em certas situações e ter apenas um único arquivo 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 propósito: O plugin DedupePlugin foi removido do Webpack. Você deve removê-lo de sua configuração.

ATUALIZAR:

Além da minha resposta anterior:

Se você deseja ocultar seu código para lançamento, tente enclosejs.com . Ele permite que você:

  • faça uma versão de lançamento de seu aplicativo sem fontes
  • crie um arquivo de extração automática ou instalador
  • Faça um aplicativo GUI de código fechado
  • Coloque seus ativos dentro do executável

Você pode instalá-lo com npm install -g enclose

MatthiasSommer
fonte