Webpack

Permite la generarción de "bundles" para desarrollo y producción.

Instalación

Instalación local de Webpack

mkdir webpack-test1 && cd webpack-test1
npm init -y && npm i --save-dev webpack

Generar archivo de prueba en directorio "src" con el siguiente contenido:

const greet = function( name ) {
  return 'Hello ' + name + '!';
};
console.log(greet('Lenin Meza'));

Un archivo de configuración(webpack.config.js) básico sería

var path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

Ejecutar Webpack indicando el archivo de configuración:

./node_modules/.bin/webpack --config webpack.config.js --colors -p

Webpack generará un archivo bundle optimizado para producción.

Hash: 848c6e51cb7022588343
Version: webpack 3.1.0
Time: 136ms
    Asset       Size  Chunks             Chunk Names
bundle.js  539 bytes       0  [emitted]  main
   [0] ./src/index.js 100 bytes {0} [built]

El archivo puede ser probado con NodeJs:

node dist/bundle.js
Hello Lenin Meza!

Module Loaders

Webpack permite transformar el código fuente de un módulo mediante su pre-procesamiento.

Los loaders más usados son:

Nombre Descripción Instalación
file-loader

Emite objetos como archivos y regresa su URL pública.

npm install --save-dev file-loader
style-loader

Agrega CSS al DOM inyectando una etiqueta <style>

npm install --save-dev style-loader
css-loader

Interpreta @import y url() como import/require() y los resuelve.

npm install --save-dev css-loader
less-loader

Compila LESS a CSS

npm install --save-dev less-loader less
sass-loader

Compila SASS/SCSS a CSS

npm install --save-dev sass-loader node-sass
babel-loader

Transpila ECMAScript 6 o 7 a ECMAScript 5

npm install --save-dev babel-loader babel-core 
babel-preset-env

Plugins

https://webpack.js.org/plugins/define-plugin/
Nombre Descripción Instalación/Configuración
HtmlWebpackPlugin

Genera archivo(s) HTML

npm install --save-dev html-webpack-plugin
ExtractTextWebpackPlugin

Permite extraer CSS a un archivo

npm install --save-dev extract-text-webpack-plugin
Hot Module Replacement

Permite actualizar módulos sin recargar la página.

Viene incluido con Webpack. Se habilita con:

plugins: [
    new webpack.HotModuleReplacementPlugin()
],
devServer: {
    hot: true,
}
DefinePlugin

Permite crear constantes globales

Viene incluido con Webpack. Se habilita con:

plugins:[
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('production')
    })
]
UglifyJsPlugin

Minimiza archivos mediante UglifyJS.

Viene incluido con Webpack. Se habilita con:

plugins:[
    new webpack.optimize.UglifyJsPlugin({
      sourceMap: options.devtool && (options.devtool.indexOf("sourcemap") >= 0 || options.devtool.indexOf("source-map") >= 0),
      compress: {
        warnings: false,
		comments: false
      }
    })
]
LoaderOptionsPlugin

Configura opciones globales para los Loaders.

Viene incluido con Webpack. Se habilita con:

new webpack.LoaderOptionsPlugin({
  minimize: true,
  debug: false,
  options: {
    context: __dirname
  }
})

Desarrollo

La forma ideal y más rápida para desarrollar es con WebpackDevServer ya que contiene un servidor web(Express), "Live reloading" y HMR(Hot Module Replacement) entre otros Features.

Instalación local de WebpackDevServer:

npm i --save-dev webpack-dev-server

Dentro del archivo de configuración(webpack.config.js) se debe agregar la configuración:

devServer: {
  contentBase: path.join(__dirname, "dist"),
  compress: true,
  progress: true,
  stats: "errors-only",
  host: "0.0.0.0",
  port: 9000,
  hot: true
}

Producción

Las configuraciones para optimizar un bundle para producción son las siguientes:

  • Se debe usar el plugin UglifyJsPlugin

  • Se debe usar el plugin LoaderOptionsPlugin

  • El tipo del SourceMap(devtool) debe ser: cheap-module-source-map

  • El valor de process.env.NODE_ENV debe ser: production

Un ejemplo del archivo de configuración para producción seria:

module.exports = {
  output: {
    path: path.join(__dirname, '/../dist/assets'),
    filename: '[name].bundle.js',
    publicPath: publicPath,
    sourceMapFilename: '[name].map'
  },

  plugins: [
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false
    }),
    new webpack.optimize.UglifyJsPlugin({
      beautify: false,
      mangle: {
        screw_ie8: true,
        keep_fnames: true
      },
      compress: {
        screw_ie8: true
      },
      comments: false
    })
  ]
}