¡Webpack está tan de moda ahora mismo! Webpack es excelente cuando se trata de agrupar módulos y trabajar con marcos como Vue o React, pero es un poco más incómodo cuando se manejan activos estáticos (como CSS). Es posible que esté más acostumbrado a manejar sus activos estáticos con algo como Gulp, y hay algunas buenas razones para ello.
Aún así, la cantidad de JavaScript en nuestros proyectos estáticos está creciendo, así que para compensar, hagamos uso de Webpack, mientras permanecemos en Gulp. En este artículo, específicamente, Gulp 4. Usaremos técnicas modernas para construir un flujo de trabajo fácil de mantener, incluyendo el poderoso y útil Recarga de módulo en caliente (HMR).
Es posible que desee comenzar aquí
Este artículo no es para principiantes. Si es nuevo en Webpack o Gulp, quizás comience con estos tutoriales.
Tutoriales de Gulp
- Gulp para principiantes
- La guía completa para actualizar a Gulp 4
- Gulp 4.0 en GitHub
Tutoriales de Webpack
- Documentos oficiales de Webpack
- Configuración de Webpack Artículo 1
- Configuración de Webpack Artículo 2
- ¿Qué es la recarga de módulos en caliente?
Manifestación
Consulte el repositorio de demostración en GitHub. La rama “hmr” muestra cómo configurar la recarga de módulos en caliente.
Prerrequisitos
Ejecute lo siguiente para instalar los paquetes necesarios:
npm install babel-core
babel-preset-es2015
browser-sync
gulpjs/gulp#4.0
webpack
webpack-dev-middleware
webpack-hot-middleware -D
A partir de Node v7.9.0, los módulos ES6 no son compatibles, es por eso que instalamos Babel para hacer uso de declaraciones de importación y otras funciones JS de vanguardia en nuestras tareas.
Si no necesita HMR, no dude en dejar Hot Middleware fuera de los paquetes enumerados anteriormente. Dev Middleware no depende de él.
Puntos de partida
¡Empecemos! Crear un tasks
carpeta en la raíz de su proyecto con tres archivos: index.js
, webpack.js
y server.js
. Tenemos menos desorden en la raíz de nuestro proyecto ya que el archivo de índice actúa como gulpfile.js
y el archivo webpack como webpack.config.js
.
El site
carpeta contiene todos los activos de su sitio:
╔ site
║ ╚═══ main.js
╠ tasks
║ ╠═══ index.js
║ ╠═══ server.js
║ ╚═══ webpack.js
╚ package.json
Para decirle a Gulp dónde están ubicadas las tareas, necesitamos agregar banderas en nuestro `package.json`:
"scripts": {
"dev": "gulp --require babel-register --gulpfile tasks",
"build": "NODE_ENV=production gulp build --require babel-register --gulpfile tasks"
}
El babel-register
comando procesa las declaraciones de importación y el --gulpfile
bandera define el camino a gulpfile.js
o, en nuestro caso, index.js
. Solo necesitamos hacer referencia al tasks
carpeta porque, como en HTML, el archivo llamado índice marca el punto de entrada.
Configurar una configuración básica de Webpack
En `webpack.js`:
import path from 'path'
import webpack from 'webpack'
let config = {
entry: './main.js',
output: {
filename: './bundle.js',
path: path.resolve(__dirname, '../site')
},
context: path.resolve(__dirname, '../site')
}
function scripts() {
return new Promise(resolve => webpack(config, (err, stats) => {
if (err) console.log('Webpack', err)
console.log(stats.toString({ /* stats options */ }))
resolve()
}))
}
module.exports = { config, scripts }
Observe cómo no exportamos el objeto directamente como muestran muchos tutoriales, sino que lo colocamos en una variable primero. Esto es necesario para que podamos usar la configuración en la tarea Gulp scripts
a continuación, así como en el middleware del servidor en el siguiente paso.
Contexto
El config.context
La configuración es necesaria para establecer todas las rutas relativas a nuestro site
carpeta. De lo contrario, comenzarían desde el tasks
carpeta que podría generar confusión en el futuro.
Configuración y tarea independientes
Si tiene una configuración de Webpack muy larga, también puede dividirla y la tarea en dos archivos.
// webpack.js
export let config = { /* ... */ }
// scripts.js
import { config } from './webpack'
export function scripts() { /* ... */ }
Recarga de módulo en caliente
Aquí se explica cómo hacer que HMR funcione. Cambie la entrada y los complementos:
entry: {
main: [
'./main.js',
'webpack/hot/dev-server',
'webpack-hot-middleware/client'
]
},
/* ... */
plugins: [
new webpack.HotModuleReplacementPlugin()
]
Asegúrese de deshabilitar las entradas adicionales y el complemento HMR para la producción. El paquete Webpack Merge ayuda a configurar diferentes entornos para el desarrollo y la producción.
BrowserSync
Ahora una configuración de tarea BrowserSync:
import gulp from 'gulp'
import Browser from 'browser-sync'
import webpack from 'webpack'
import webpackDevMiddleware from 'webpack-dev-middleware'
import webpackHotMiddleware from 'webpack-hot-middleware'
import { config as webpackConfig } from './webpack'
const browser = Browser.create()
const bundler = webpack(webpackConfig)
export function server() {
let config = {
server: 'site',
middleware: [
webpackDevMiddleware(bundler, { /* options */ }),
webpackHotMiddleware(bundler)
],
}
browser.init(config)
gulp.watch('site/*.js').on('change', () => browser.reload())
}
El Dev Middleware permite que BrowserSync procese lo que se definió como entrada en webpack.js
. Para darle esta información importamos el módulo de configuración. Middlware caliente por otro lado, comprueba si hay cambios en los componentes de la aplicación como archivos `.vue` para que Vue.js los inyecte.
Dado que no podemos recargar archivos en caliente como main.js
, nosotros reloj ellos y vuelva a cargar la ventana en el cambio. Nuevamente, si no necesita HMR, elimine webpackHotMiddleware.
Importar todas las tareas
El archivo `index.js` incluye todas las tareas:
import gulp from 'gulp'
import { scripts } from './webpack'
import { server } from './server'
export const dev = gulp.series( server )
export const build = gulp.series( scripts )
export default dev
Las variables exportadas definen qué tareas ejecutar bajo qué comando. La exportación predeterminada se ejecuta con gulp
.
Si separa los entornos de desarrollo y producción para Webpack, es posible que desee ejecutar un gulp build
tarea que hace uso de opciones de producción. Para eso, importamos el scripts
tareas por sí solo, ya que no es necesario iniciar el servidor aquí.
Durante el desarrollo, BrowserSync ejecuta Webpack, por lo que no es necesario poner la tarea de scripts en el comando dev.
Tareas en ejecución
Para empezar a desarrollar no puedes simplemente correr gulp
o gulp build
ya que buscará un gulpfile.js
en la raíz del proyecto. Tenemos que ejecutar los comandos npm npm run dev
y npm run build
para hacer uso de las banderas definidas.
En expansión
Ahora puede imaginar lo fácil que es expandir y escribir más tareas. Exporta una tarea en un archivo e impórtala en `index.js`. ¡Limpio y fácil de mantener!
Para darle una idea de cómo configurar la carpeta de su proyecto, aquí está mi configuración personal:
╔ build
╠ src
╠ tasks
║ ╠═══ config.js => project wide
║ ╠═══ icons.js => optimize/concat SVG
║ ╠═══ images.js => optimize images
║ ╠═══ index.js => run tasks
║ ╠═══ misc.js => copy, delete
║ ╠═══ server.js => start dev server
║ ╠═══ styles.js => CSS + preprocessor
║ ╚═══ webpack.js
╚ package.json
Nuevamente, ¿por qué usar Webpack y Gulp?
Manejo de archivos estáticos
Gulp puede manejar activos estáticos mejor que Webpack. El complemento Copy Webpack también puede copiar archivos desde su fuente a su carpeta de compilación, pero cuando se trata de ver la eliminación de archivos o cambios como anular una imagen, gulp.watch
es una apuesta más segura.
Entorno del servidor
Webpack también viene con un entorno de servidor local a través de Webpack Dev Server, pero el uso de BrowserSync tiene algunas características que no querrá perderse:
- Inyección de CSS / HTML / imagen para proyectos que no son aplicaciones
- prueba de múltiples dispositivos fuera de la caja
- incluye un panel de administración para mayor control
- estrangulamiento del ancho de banda para pruebas de velocidad y carga
Tiempo de compilación
Como se ve en esta publicación en GitHub, Sass es procesado por node-sass mucho más rápido que por la combinación de Webpack de sass-loader, css-loader y extract-text-webpack-plugin.
Conveniencia
En Webpack, debe importar sus archivos CSS y SVG, por ejemplo, en JavaScript para procesarlos, lo que a veces puede ser bastante complicado y confuso. Con Gulp, no necesita ajustar su flujo de trabajo.