Desafortunadamente, no tengo el tiempo ni el entusiasmo para mantener este proyecto en este momento. Recomiendo bifurcar este proyecto o leer su código fuente para saber cómo está construido.
Este modelo estándar de paquete web es para desarrolladores principiantes, intermedios y avanzados que buscan crear sitios web estáticos rápidamente y al mismo tiempo lograr todas las optimizaciones adecuadas para obtener una puntuación perfecta en Google Page Speed Insights y Google Lighthouse Reports. Esta es una evolución de tris-gulp-boilerplate, ahora con Webpack 4. Webpack es el nuevo estándar para agrupar JS que Gulp no era capaz de hacer. Afortunadamente, Webpack puede ejecutar tareas y agrupar js.
El objetivo de este proyecto/repetitivo es llegar a las siguientes personas:
¿ Los principiantes ? - quienes, aunque usan Gulp/Webpack/Node/Npm, aún necesitan explicaciones más detalladas que los desarrolladores más familiarizados. Quieren que las cosas funcionen, pero también quieren saber cómo y por qué .
¿ Los estafadores de proyectos paralelos ?♀️: aquellos que tienen grandes ideas pero no quieren perder el tiempo con la configuración. Necesitan sacar sus ideas, aplicaciones y sitios web al navegador... rápidamente .
Los obsesivo compulsivos ♂️: personas a las que les encanta obtener esas puntuaciones perfectas en los informes de rendimiento y optimización. Personas que están organizadas digitalmente y se enorgullecen de saber que todos sus archivos están minimizados, comprimidos, comprimidos y listos para enviar.
¡Siéntete libre de bifurcar este repositorio y crear tu propio flujo de trabajo basado en esta plantilla! Cada uno es un poco diferente, lo entiendo.
Necesita git y node.js en su computadora antes de ejecutarlo.
git clone https://github.com/tr1s/tris-webpack-boilerplate.git your-project-name
cd your-project-name && rm -rf .git
npm install
npm start
Ya está todo listo, ¡comience a codificar ??!
Elimine todo lo que esté en la carpeta src/styles/
, src/index.html
y src/index.scss/
si desea comenzar 100% nuevo y/o crear su propio flujo de trabajo Sass. Basé la estructura de mi carpeta en el patrón 7-1.
npm run build
cuando esté listo para cargar su sitio en la plataforma FTP/alojamiento que elija. Esto creará una carpeta dist
con todos los recursos de su sitio web optimizados y comprimidos.
Si desea una explicación detallada de cómo funciona todo, lea acerca de las funciones a continuación. De lo contrario, continúa codificando y diviértete :)
tris-webpack-repetitivo
Uso
Características / Contenidos
Características explicadas
División de configuración del paquete web
Servidor de desarrollo de paquetes web
Activos HTML y minificación
404 página no encontrada
SCSS a CSS + optimizaciones
Transpilación de ES6
Lista de navegadores
Recursos de imagen + compresión
Carga de fuentes + precarga
Compresión de activos
Complemento de paquete web limpio
Mapas fuente
generación de favicon
Primero sin conexión y almacenamiento en caché
Aplicación web progresiva (PWA)
Te tengo
Contribuyendo
En lugar de tener un webpack.config.js
grande, dividiremos nuestras compilaciones de producción y desarrollo en dos nuevas configuraciones llamadas webpack.dev.js
y webpack.prod.js
. Las configuraciones que queremos tanto en desarrollo como en producción irán en la configuración webpack.common.js
.
Cuando ejecutamos npm start
, ejecutará la compilación de desarrollo basada en la configuración webpack.dev.js
que también tiene las configuraciones webpack.common.js
fusionadas. Lea más sobre esto en la documentación de Webpack.
/* wenpack.dev.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* fusiona webpack.common.js y luego agregas su extra */module.exports = merge(common, { modo: "desarrollo", /* el resto del código va aquí */});
Cuando ejecutamos npm run build
, ejecutará la compilación de producción basada en la configuración webpack.prod.js
que también tiene las configuraciones webpack.common.js
fusionadas.
/* webpack.prod.js */const merge = require("webpack-merge");const common = require("./webpack.common.js");/* fusiona webpack.common.js y luego agregas su extra */module.exports = merge(common, { modo: "producción",});
Queremos que nuestras compilaciones de desarrollo y producción produzcan los mismos resultados visualmente en el navegador. No querrás terminar de codificar, ejecutar la compilación y luego tener un sitio web totalmente diferente al que le faltan imágenes, por ejemplo. Es por eso que tenemos webpack.common.js
para manejar todos los cargadores y la gestión de activos. webpack.dev.js
será ligeramente diferente con un mapa fuente más liviano. Finalmente, webpack.prod.js
se encargará de todas las etapas finales para llevar su sitio web a producción. Es decir, compresión de imágenes, compresión de activos (gzip), minificación de activos, generación de favicon, almacenamiento en caché y creación de una experiencia sin conexión.
Analizaré cada proceso a continuación.
El servidor webpack-dev-server está configurado en package.json. npm start
ejecutará el servidor y abrirá su proyecto en el navegador usando la configuración webpack.dev.js
. npm start
es el script predeterminado de npm, por lo que no es necesario agregarle run
. Pero para el script de compilación necesitas escribir npm run build
.
"scripts": { "start": "webpack-dev-server --open --config webpack.dev.js", "build": "webpack --config webpack.prod.js"},
Usamos el cargador html para exportar HTML como una cadena y minimizar la salida. Esto le permite importar su src/index.html
dentro de su src/index.js
. Simplemente podemos minimizar el HTML con una opción de cargador minimize: true
, por eso lo dejamos en webpack.common.js
en lugar de moverlo a webpack.prod.js
.
/* webpack.common.js */{ prueba: /.html$/, utilizar: [{cargador: 'html-loader', opciones: {minimizar: verdadero} }]},
/* src/index.js */import "./index.html";
Luego usamos html-webpack-plugin para crear un nuevo index.html
generado con todas las importaciones de activos correctas.
La opción template:
es de donde estás extrayendo tu HTML fuente. Puede utilizar su propia plantilla html, plantilla de manillar o cualquiera de estas otras plantillas.
La opción inject:
es donde irán sus activos. Webpack colocará el script webpack-bundle.js
incluido en la parte inferior del cuerpo de forma predeterminada, pero aquí lo cambié al head
porque usaremos el script-ext-html-webpack-plugin para agregar un atributo defer
al script y colóquelo en el encabezado del sitio web. Esto ayuda con el rendimiento.
/* webpack.common.js */const HtmlWebpackPlugin = require('html-webpack-plugin');const ScriptExtHtmlWebpackPlugin = require("script-ext-html-webpack-plugin");complementos: [ nuevo HtmlWebpackPlugin ({título: 'tris-webpack-boilerplate', nombre de archivo: 'index.html', plantilla: './src/index.html', inyectar: 'head' }), nuevo HtmlWebpackPlugin ({título: 'tris-404-page', nombre de archivo: '404.html', plantilla: './src/404.html', inyectar: 'head' }), nuevo ScriptExtHtmlWebpackPlugin({defaultAttribute: 'aplazar' }),],
Siga agregando más complementos new HtmlWebpackPlugin({})
si va a tener un sitio web de varias páginas. Nombra la página apropiadamente con el title:
clave.
Netlify es un fantástico servicio gratuito que le permite administrar e implementar sus sitios web. Netlify busca automáticamente un 404.html
y cargará esa página cuando alguien intente abrir un enlace roto en su sitio web. Así que no tienes nada de qué preocuparte.
Si utiliza un servicio diferente, investigue un poco sobre cómo puede vincular su página 404.html
para que esté activa. Es una excelente manera de enviar a las personas de regreso a su página principal si llegan a un enlace roto.
Para usar Sass/SCSS, necesitamos usar algunos cargadores para obtener los resultados deseados. El cargador css, el cargador postcss y el cargador sass.
test:
utiliza expresiones regulares (expresión regular) para verificar si hay archivos sass, scss o css y luego los ejecuta a través de estos tres cargadores, que están incluidos en el complemento mini-css-extract, que luego genera un único archivo CSS para usted. para utilizar en la producción.
Lea más sobre el concepto de cargadores.
/* webpack.common.js */{ prueba: /.(sa|sc|c)ss$/, utilizar: [MiniCssExtractPlugin.loader,{ cargador: 'css-loader', opciones: {sourceMap: true }},{ cargador: 'postcss-loader', opciones: {sourceMap: true }},{ cargador: 'sass-loader ', opciones: {sourceMap: verdadero }} ]},
La segunda parte de la secuencia del cargador, postcss-loader
, es donde minimizarás y prefijarás automáticamente tu CSS. Para hacer esto creamos un postcss.config.js
en la raíz del proyecto y lo configuramos así...
/* postcss.config.js */const purgecss = require("@fullhuman/postcss-purgecss");module.exports = { complementos: [require("autoprefixer"),require("cssnano")({ preset: "default",}),purgecss({ content: ["./**/*.html"], fotogramas clave: true,} ), ],};
Lea sobre autoprefixer y cssnano para configurarlo más a su gusto si es necesario. Además, lea sobre postcss en general, ya que es una herramienta muy poderosa para tener en su arsenal.
Purgecss es un complemento postcss fantástico para deshacerse del CSS no utilizado en su código. Purgecss analiza su contenido y sus archivos CSS. Luego hace coincidir los selectores utilizados en sus archivos con el de sus archivos de contenido. Elimina selectores no utilizados de su CSS, lo que da como resultado archivos CSS más pequeños.
Está listo para funcionar de forma predeterminada, pero si desea probarlo visualmente usted mismo, descomente @import "../node_modules/bulma/bulma";
en index.scss
y luego ejecute npm run build
y observe el webpack-bundle.css
resultante en su carpeta dist. Notarás que no hay tanto código. Luego elimine purgecss de su postcss.config.js
y ejecute npm run build
nuevamente; notará que hay más de 10,000 líneas de código en su CSS provenientes del marco Bulma. Como puedes ver, purgecss es perfecto para deshacerte del CSS que no estás usando cuando usas frameworks grandes como Bootstrap, Foundation, Bulma, etc.
El mini-css-extract-plugin es el paso final, ya que extrae el CSS y le da un nombre antes de generarlo.
/* webpack.common.js */const MiniCssExtractPlugin = require("mini-css-extract-plugin");complementos: [ nuevo MiniCssExtractPlugin({nombre de archivo: 'webpack-bundle.css',chunkFilename: '[id].css' })],
Básicamente... el css-loader
recopilará CSS de todos los archivos css a los que se hace referencia en su aplicación y los colocará en una cadena. Luego, postcss-loader
autoprefija y minimiza sus estilos, luego sass-loader
lo convierte en un módulo JS, luego mini-css-extract-plugin
extrae el CSS del módulo JS en un único archivo CSS para que el navegador web lo analice.
Es posible que desee utilizar las últimas funciones y sintaxis de JavaScript, pero no todos los navegadores las admiten todavía. Babel se encargará de eso por nosotros.
Aquí estamos probando todos los archivos js pero excluyendo la carpeta node_modules
, luego la ejecutamos a través de babel-loader con el valor preestablecido babel-preset-env.
/* webpack.common.js */{ prueba: /.js$/, excluir: /(node_modules)/, utilizar: {cargador: 'babel-loader', opciones: { ajustes preestablecidos: ['@babel/preset-env']} }}
Esta vez nos aventuramos en el archivo webpack.prod.js
. Cuando npm run build
, nuestro js de salida se minimizará y tendrá mapas fuente completos. Al ejecutar en modo de desarrollo a través de npm start
todavía tendremos mapas fuente más livianos, pero el js no se minimizará.
/* webpack.prod.js */const TerserPlugin = require("terser-webpack-plugin");module.exports = merge(common, { modo: "producción", devtool: "mapa fuente", optimización: {minimizador: [new TerserPlugin({test: /.js(?.*)?$/i,parallel: true,sourceMap: true, }),], },});
Lea más sobre las opciones en la documentación de terser.
Aquí queremos tener un lugar donde podamos decirle a ciertas herramientas para qué navegadores nos gustaría agregar soporte. Logramos esto usando browserslist y el archivo .browserslistrc
correspondiente en la raíz del proyecto. Autoprefixer y babel-present-env recogerán este archivo y aplicarán lo que necesite según la configuración.
Lea qué más puede pasar a .browserslistrc
y use browserl.ist para ver a qué navegadores se dirigirá específicamente su configuración. Bien, creo que ya he dicho navegadores suficientes veces.
/* .browserslistrc */> 0,25%no muerto
Primero probamos jpeg, jpg, png, gif y svg usando expresiones regulares (expresión regular), luego usamos el cargador de archivos, que resuelve las importaciones y los requisitos de un archivo en una URL y luego emite el archivo al directorio de salida. Entonces, si está utilizando un elemento <img>
que toma un archivo de la carpeta src/images
, se importará y emitirá a la ruta de images
especificada. Lo que termina siendo src/images
si npm start
(ejecutando dev) o npm run build
(ejecutando build).
/* webpack.common.js */{ prueba: /.(jpe?g|png|gif|svg)$/, uso: [{cargador: 'cargador de archivos', opciones: { nombre: '[nombre].[ext]', ruta de salida: 'imágenes/', ruta pública: 'imágenes/'}, }]},
Ahora solo queremos optimizar nuestras imágenes en npm run build
, por lo que editamos nuestro webpack.prod.js
como se muestra a continuación.
Nuevamente probamos jpeg, jpg, png, gif y svg usando expresiones regulares y aplicamos las optimizaciones apropiadas. gifsicle
es un compresor de gif sin pérdida, pngquant
es un compresor de png con pérdida y podemos agregar un complemento adicional llamado imageminMozjpeg
para realizar compresión jpg/jpeg con pérdida. Una apuesta segura es establecer la calidad entre 75 y 90 y debería obtener una compresión decente sin pérdida de calidad visible.
Sugiero ceñirse a la compresión sin pérdidas y recortar las imágenes al tamaño correcto antes de agregarlas a su proyecto. Simplemente elimine las secciones clave imageminMozjpeg y pngquant para hacerlo.
También puedes usar tinypng para comprimir imágenes.
/* webpack.prod.js */const ImageminPlugin = require("imagemin-webpack-plugin").default;const imageminMozjpeg = require("imagemin-mozjpeg");plugins: [ new ImageminPlugin({test: /.(jpe?g|png|gif|svg)$/i,gifsicle: { // optimización del compresor gif sin pérdidaLevel: 9,},pngquant: { // compresor png con pérdida, eliminar por defecto sin pérdida calidad: "75",}, complementos: [ imageminMozjpeg({// compresor jpg con pérdida, eliminar por calidad predeterminada sin pérdida: "75", }),], }),];
Aquí estamos probando todas las extensiones de fuentes comunes y usando el cargador de archivos nuevamente para resolver nuestras importaciones de fuentes y generarlas.
/* webpack.common.js */{ prueba: /.(woff|woff2|ttf|otf)$/, uso: [{cargador: 'cargador de archivos', opciones: { nombre: '[nombre].[ext]', ruta de salida: 'fuentes/', ruta pública: 'fuentes/'}, }]},
En nuestro src/styles/base/_typography.scss
estamos cargando las fuentes mediante la regla @font-face
. Google Webfonts Helper también es una herramienta fantástica para alojar Google Fonts sin problemas. Lea más sobre la regla @font-face
en trucos CSS. Además, lea también sobre la propiedad font-display.
Siempre es una buena práctica precargar las fuentes. Lo lograremos utilizando el complemento webpack de precarga y deberá colocarlo justo después de HtmlWebpackPlugin
para que funcione correctamente.
/* webpack.common.js */new PreloadWebpackPlugin({ rel: 'precarga', as(entrada) {if (/.(woff|woff2|ttf|otf)$/.test(entrada)) return 'fuente'; }, fileWhitelist: [/.(woff|woff2|ttf|otf)$/], incluir: 'todos los activos'}),
Aquí estamos de vuelta en la configuración webpack.prod.js
usando el complemento de compresión-webpack para comprimir solo los archivos html, css y javascript. Esto es para evitar comprimir los archivos de mapas fuente que se generan.
/* webpack.prod.js */module.exports = fusionar(común, { modo: 'producción', complementos: [new CompressionPlugin({ test: /.(html|css|js)(?.*)?$/i // solo html/css/js comprimido, omite la compresión de mapas fuente, etc.}),});
Clean-webpack-plugin es solo un complemento de paquete web simple para eliminar/limpiar sus carpetas de compilación antes de crear una nueva. Observe la exploración de su carpeta mientras ejecuta npm run build
o npm start
. Su carpeta dist
actual (si ya tenía una creada) se eliminará y aparecerá una nueva inmediatamente después.
/* webpack.common.js */const CleanWebpackPlugin = require("clean-webpack-plugin"); complementos: [new CleanWebpackPlugin(["dist"])];
El uso de mapas fuente es esencial para depurar su código en las herramientas de desarrollo.
Como puede ver cuando npm start
y abre devtools en Chrome y luego hace clic en la consola, verá que hay dos console.logs provenientes de las líneas 1 y 2 script.js
Podemos ver esto fácilmente en nuestra estructura de carpetas en src/scripts/script.js
. Si no usáramos sourcemaps, devtools nos mostraría que estos console.logs provienen de nuestro webpack-bundle.js
incluido, lo cual no es muy útil.
Caso similar con nuestros estilos. Si observa el elemento body
en devtools, verá que se aplican algunos estilos desde nuestro archivo _global.scss
y algunos desde nuestro archivo _typography.scss
, ambos ubicados en nuestra carpeta src/styles/base/
. No podríamos saber esto si omitiéramos los mapas fuente. Simplemente nos mostraría los estilos que provienen de nuestro webpack-bundle.css
incluido.
/* webpack.dev.js */module.exports = fusionar(común, { modo: "desarrollo", devtool: "mapa-fuente-en línea",});
/* webpack.prod.js */module.exports = fusionar(común, { modo: "producción", devtool: "mapa fuente",});
Lea más sobre los diferentes tipos de mapas fuente para encontrar cuál funciona mejor para su proyecto. Lea además sobre la opción devtool en los documentos del paquete web.
Este es un gran complemento que genera todos los íconos que necesitarás en función de una fuente de imagen. En mi carpeta src/images/
tengo un tris-package.svg
que ingreso en favicons-webpack-plugin.
Generará íconos para Apple, Android, Chrome, Firefox, Twitter, Windows, lo que sea. Generará cada ícono en diferentes tamaños y los importará directamente al encabezado de su sitio web, donde pertenecen. Twitter y Windows están configurados en falso pero de forma predeterminada, así que los cambié a verdadero solo para cubrir todas las bases, por si acaso.
Nota: esto aumenta drásticamente el tiempo de construcción. Lo cual es comprensible considerando cuánto hace bajo el capó y cuánto tiempo le ahorra a largo plazo. No se sorprenda si npm run build
tarda 20 segundos más de lo habitual.
/* webpack.prod.js */const FaviconsWebpackPlugin = require("favicons-webpack-plugin");module.exports = merge(common, { modo: "producción", complementos: [nuevo FaviconsWebpackPlugin({ logo: "./src/images/favicon.svg", iconos: {twitter: true,windows: true, },}), ],});
Aquí utilizamos el complemento fuera de línea para almacenar en caché todos nuestros activos al cargar la página.
Este complemento está destinado a proporcionar una experiencia sin conexión para proyectos de paquetes web . Utiliza ServiceWorker y AppCache como respaldo interno. Simplemente incluimos este complemento en nuestro webpack.prod.js
y el tiempo de ejecución que lo acompaña en nuestro script de cliente (src/index.js), y nuestro proyecto estará listo sin conexión al almacenar en caché todos (o algunos) de los activos de salida del paquete web.
Nota: Si npm run build
y carga los cambios en su servidor (o si mantiene su sitio web actualizado), su sitio web deberá haber sido cerrado y reabierto antes de que pueda ver los cambios. No puede tenerlo abierto y seguir actualizándose, debe cerrar la pestaña y volver a abrirla para que se rompa el caché.
/* webpack.prod.js */const OfflinePlugin = require("offline-plugin");module.exports = merge(common, { modo: "producción", complementos: [nuevo OfflinePlugin()],});
Las aplicaciones web progresivas (PWA) son aplicaciones web que se cargan como páginas web o sitios web normales, pero que pueden ofrecer al usuario funcionalidades como trabajar sin conexión, notificaciones automáticas y acceso al hardware del dispositivo que tradicionalmente solo están disponibles para aplicaciones nativas. Las PWA combinan la flexibilidad de la web con la experiencia de una aplicación nativa.
El último paso para convertir este modelo estándar en una PWA es agregar el manifiesto de aplicación web obligatorio a la raíz de su proyecto y configurarlo adecuadamente.
Webpack tiene problemas al intentar agrupar bibliotecas grandes como jQuery. Terminará con errores de consola como $ is not defined
o jQuery is not defined
. Para resolver esto, dejamos que Webpack lo trate como externo. Luego definimos las variables e incluimos jQuery a través de una CDN. La mayoría de las personas tienen jQuery almacenado en caché en su navegador, por lo que esto no será un problema en términos de rendimiento. Agregué la configuración externals:
de forma predeterminada, pero tendrás que agregar el cdn de jQuery tú mismo si planeas usarlo.
Lea más sobre externos en la documentación de Webpack.
/* webpack.common.js */plugins: [], externos: { $: 'jquery', jquery: 'jQuery', 'ventana.$': 'jquery',}
/* src/index.html */<cabeza> <scriptdefersrc="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js" </script></head>
Hago lo mejor que puedo para explicar las cosas detalladamente, pero si algo se puede explicar con mayor claridad, no dude en enviar una solicitud de extracción con algunas ediciones sugeridas. ¡Gracias!
¡Espero que esto haya ayudado! Sígueme en Twitter si te gusta eso. ?