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




webpack-dev-server (6)

Eu sou muito novo no webpack, descobri que na produção podemos reduzir o tamanho do código geral. Atualmente, o webpack constrói em torno de 8MB e main.js em torno de 5MB. Como reduzir o tamanho do código na criação de produção? Eu encontrei um exemplo de arquivo de configuração do webpack da internet e eu configurei para o meu aplicativo e eu executo npm run build e seu building iniciado e ele gerou alguns arquivos no diretório ./dist/ .

  1. Ainda assim, esses arquivos são pesados ​​(como na versão de desenvolvimento)
  2. Como usar esses arquivos? Atualmente estou usando o 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]
  }
};

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

cause que o tente uglify seu código duas vezes. Consulte https://webpack.github.io/docs/cli.html#production-shortcut-p para mais informações.

Você pode corrigir isso removendo o UglifyJsPlugin do plugins-array ou adicionar o OccurrenceOrderPlugin e remover o "-p" -flag. então uma possível solução 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"
},

Apenas aprendendo isso eu mesmo. Eu responderei a segunda pergunta:

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

Em vez de usar o webpack-dev-server, você pode simplesmente executar um "express". use o 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);

Então, no package.json, adicione um script:

"start": "node server.js"

Finalmente, execute o aplicativo: npm run start para 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)


Isso ajudará você.

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$/]), //https://.com/questions/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
    })
  ],

Se você tem um monte de código duplicado em seu webpack.dev.config e seu webpack.prod.config, você pode usar um isProd booleano para ativar determinados recursos somente em determinadas 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 da sua configuração.

ATUALIZAR:

Além da minha resposta anterior:

Se você quiser ocultar seu código para lançamento, tente o enclosejs.com . Permite-lhe:

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

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


Você pode adicionar os plugins como sugerido pelo @Vikramaditya. Então, para gerar a construção de produção. Você tem que executar o comando

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

O -p diz 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.


Você pode usar argv npm module (instale-o executando npm install argv --save ) para obter parâmetros em seu arquivo webpack.config.js e como para produção você usa -p flag "build": "webpack -p" , você pode adicione 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.





webpack-dev-server