Skip to content

Latest commit

 

History

History
446 lines (361 loc) · 16.1 KB

File metadata and controls

446 lines (361 loc) · 16.1 KB

shieldsIO shieldsIO shieldsIO

WideImg

Master en Programación de Aplicaciones con JavaScript y Node.js

JS, Node.js, Frontend, Express, Patrones, IoT, HTML5_APIs, Asincronía, Websockets, ECMA6, ECMA7

Clase 93

Browserify

Logo

Browserify: Caracteristicas

  • solo soporta el patrón CommonJS, usaremos require() en el browser
  • Genera un fichero bundle con todo el js
  • Se puede usar con un fichero de configuración complejo
  • Se instala globalmente npm install browserify -g

Browserify: Funcionamiento

Nuestro fichero public/main.js:

var foo = require('./foo.js');
var bar = require('../lib/bar.js');
var gamma = require('gamma');

var elem = document.getElementById('result');
var x = foo(100) + bar('baz');
elem.textContent = gamma(x);

Nuestro fichero public/foo.js:

module.exports = function (n) { return n * 111 }

Comando que hace toda la magia:

browserify main.js > bundle.js

Nuestro fichero public/index.html

<!doctype html>
<html>
  <head>
    <title>Browserify Playground</title>
  </head>
  <body>
    <script src="/static/js/bundle.js"></script>
  </body>
</html>

Browserify: Profundizando

Webpack

webpack

Webpack takes modules with dependencies and generates static assets representing those modules.

webpack

Importante

Conceptos Clave

  • Webpack intenta gestioanr todo tipo de ficheros y no únicamente el código
  • El objetivo final de Webpack es generar un grafico de dependencias
  • Para Webpack todo son modulos, y como tal puedes requerirlos require("css/estilos.css")
  • La filosfía es cargar solo las cosas que se necesitan y cuando se necesitan, evitando una compilación masiva y permitiendo una carga asíncrona
  • Webpack es un sistema CLI, si necesitas también un servidor funcionando... necesitas instalar webpack-dev-server
  • webpack-dev-server es básicamente un Express.. lanzado por defecto en el puerto 8080
  • Toda la configuración se guarda en el fichero webpack.config.js
  • Cuando el sistema es muy complejo se dividen las tareas de Production-and-Development a Production-only o Development-only. Para ello se crea un fichero adicional, webpack.config.prod.js

Migraciones y comparativas

Instalación

Instalación de dependencias

npm install webpack webpack-dev-server --save-dev

Añadir las tareas al package.json

"scripts": {
  "start": "webpack-dev-server",
  "build": "webpack"
}
  • Es el punto de entrada de nuestra aplicación
  • Existen varias formas de determinar el punto o puntos de entrada

Entrada única

  • Esta es la más común cuando se trata de single-page application (SPA)
  • Podemos pasar un Array de Strings para usar el paradigma de multi-main entry
const config = {
  entry: './path/to/my/entry/file.js'
};

module.exports = config;

Entrada única

  • Esta es la más común cuando se trata de single-page application (SPA)
const config = {
  entry: './path/to/my/entry/file.js'
};

module.exports = config;

Entrada única (objeto)

const config = {
  entry: {
    main: './src/index.js'
  }
};

Separanado app y vendors

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js'
  }
};

Aplicación multipágina

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};

Concepto: Salida (output)

Options affecting the output of the compilation. output options tell webpack how to write the compiled files to disk. Note that, while there can be multiple entry points, only one output configuration is specified.

  • Se determina que fichero o ficheros se generarán después del proceso de bundle.
  • Para ubicar los ficheros en una carpeta usamos la propiedad path
  • Para definir el nombre de salida, usaremos filename aunque generemos varios ficheros
  • También podemos usar la propiedad publicPath para generar correctamente las rutas relativas dentro del CSS y HTML, solo es requerido por algunso plugins
  • publicPath tambén es util para gestionar nuestros fiheros pro CDN en producción y en local durante el desarrollo de forma automática

Una única salida (SPA)

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  }
};

Multipagina

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[file].js' // Genera pageOne.js, pageTwo.js, pageThree.js
    /*
    //pageOne.html
    <script src=”dist/pageOne.js”></script>
    //pageTwo.html
    <script src=”dist/pageTwo.js”></script>
    */
  }
};

Loaders are transformations that are applied on the source code of a module. They allow you to preprocess files as you require() or “load” them. Thus, loaders are kind of like “tasks” in other build tools, and provide a powerful way to handle front-end build steps. Loaders can transform files from a different language (like TypeScript) to JavaScript, or inline images as data URLs. Loaders even allow you to do things like require() CSS files right in your JavaScript!

  • Es la manera que tiene webpack de gestionar nuestros assets
  • Es necesario utilizar una expresion regular dentro de la propiedad test para determinar que ficheros serán acoplados al proceso de Webpack
  • Podemos vincular este loader con un módulo usando use -> loader
  • Podemos pasar configuracion adicional desde use -> query
  • exclude nos permite excluir ficheros/carpetas no deseados
  • Los cargadores trabajan con los ficheros antes de ser procesados por Webpack
const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.txt$/, use: 'raw-loader',
        use: [
          {
            exclude: /node_modules/ /*Exclude node_modules folder*/,
            loader: /* Nombre del módulo */,
            query: /* Configuración opcional del objeto */
          }
        ] 
      }
    ]
  }
};

module.exports = config;

Concepto: Plugins

Plugins are the backbone of webpack. webpack itself is built on the same plugin system that you use in your webpack configuration! They also serve the purpose of doing anything else that a loader cannot do.

  • nos permiten alterar el resultado final de nuestro bundle
  • Al contrario que los loaders, aqui estamos trabajando después de generar el chunk de información del bundle
const HtmlWebpackPlugin = require('html-webpack-plugin'); //installed via npm
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');

const config = {
  entry: './path/to/my/entry/file.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'my-first-webpack.bundle.js'
  },
  module: {
    rules: [
      {test: /\.txt$/, use: 'raw-loader'}
    ]
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin(),
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};

module.exports = config;

In modular programming, developers break programs up into discrete chunks of functionality called a module. Each module has a smaller surface area than a full program, making verification, debugging, and testing trivial. Well-written modules provide solid abstractions and encapsulation boundaries, so that each module has a coherent design and a clear purpose within the overall application. Node.js has supported modular programming almost since its inception. On the web, however, support for modules has been slow to arrive. Multiple tools exist that support modular JavaScript on the web, with a variety of benefits and limitations. webpack builds on lessons learned from these systems and applies the concept of modules to any file in your project.

Existen muchas formas de gestionar la modularización en Webpack:

  • Con el patrón ES2015 usando import
  • Con el patrón CommonJS usando require()
  • Con el patrón AMD usando define y require
  • Usando @import en ficheros del tipo css/sass/less
  • Importnado imágenes desde el css con url(...) o desde el html con <img src="...">
  • Con Webpack 2.x no existen limitaciones. En Webpack 1.x solo se podia usar ES2015

Because JavaScript can be written for both server and browser, webpack offers multiple deployment targets that you can set in your webpack configuration.

Con los objetivos puedes definir cual es el objetivo de la configuración, permitiendo multiples casos.

webpack.config.js con un objetivo

module.exports = {
  target: 'node'
};

webpack.config.js con multiples objetivos

var path = require('path');
var serverConfig = {
  target: 'node',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.node.js'
  }
  //…
};

var clientConfig = {
  target: 'web', // Por defecto es siempre "web", asi que puede ser omitido
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'lib.js'
  }
  //…
};

module.exports = [ serverConfig, clientConfig ];
// Se generará dist/lib.js y dist/lib.node.js

Hot Module Replacement (HMR) exchanges, adds, or removes modules while an application is running, without a full reload. This can significantly speed up development in a few ways:

  • Retain application state which is lost during a full reload.
  • Save valuable development time by only updating what's changed.
  • Tweak styling faster -- almost comparable to changing styles in the browser's debugger.

Cuando el cósigo cambia... tenemos 3 formas de procesar los cambios con webpack-dev-server

  • webpack-dev-server: Refrescamos nosotros la página manualmente
  • webpack-dev-server --inline: Se refresca la página entera
  • webpack-dev-server --inline --hot: Se refresca exclusivamente el fragmento que cambio, Hot Module Replacement (HMR)

Webpack con Ejemplos: Lidiando con estilos

Instalando las dependencias css-loader y style-loader

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

Fichero webpack.config.js

var baseConfig = {
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve('./build')
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' }
        ]
      }
    ]
  }
};

Webpack con Ejemplos: Lidiando con estilos y LESS

Instalando las dependencias less-loader, css-loader y style-loader

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

Fichero webpack.config.js

var baseConfig = {
  entry: {
    main: './src/index.js'
  },
  output: {
    filename: '[name].js',
    path: path.resolve('./build')
  },
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          { loader: 'style-loader' },
          { loader: 'css-loader' },
          { loader: 'less-loader' }
        ]
      }
    ]
  }
};

JS Drama: Grunt, Gulp, NPM Scripts, Webpack...

evolution....

Google Trends trends...

Aclarando puntos

  • Gulp/Grunt/NPM Scripts son Task Runners
  • webpack NO es un Task Runner, es un module bundler como Browserify
  • Webpack es ideal para trabajar con frameworks, especialmente React

Recursos

¡Manos a la obra!