Contents
Introducción
Este artículo explica, con todo lujo de detalles, cómo empaquetar bloques de Gutenberg para WordPress usando Webpack y @wordpress/scripts. Cubriré desde la configuración mínima hasta técnicas avanzadas: entradas múltiples, optimización, manejo de estilos, externals, integración con block.json y registro en PHP. Los fragmentos de código se incluyen tal como pides, usando la etiqueta específica para que puedas copiar y pegar.
Requisitos previos
- Node.js (preferiblemente versión LTS reciente) y npm o yarn.
- Instalación básica de WordPress para pruebas.
- Conocimientos básicos de JavaScript moderno (ESNext), JSX y React (la capa de elementos de WP).
Motivación: ¿por qué usar @wordpress/scripts?
@wordpress/scripts es un envoltorio sobre Babel, Webpack y herramientas comunes que WordPress proporciona para estandarizar la compilación de bloques. Te evita configurar Babel/webpack desde cero, pero permite personalizaciones cuando necesitas empaquetados más complejos.
Esqueleto del plugin / bloque
Partimos de una estructura mínima de plugin:
my-block-plugin/ ├─ src/ │ ├─ index.js │ ├─ edit.js │ ├─ save.js │ └─ editor.scss ├─ build/ (generado) ├─ block.json ├─ package.json └─ my-block-plugin.php
package.json mínimo
Instala las dependencias de desarrollo y las dependencias de bloqueo de WordPress en dependencies o peerDependencies según tu estrategia. Ejemplo básico:
{ name: my-block-plugin, version: 1.0.0, private: true, scripts: { start: wp-scripts start, build: wp-scripts build, build:dev: wp-scripts build --dev }, devDependencies: { @wordpress/scripts: ^25.0.0, webpack-merge: ^5.8.0 }, dependencies: { @wordpress/blocks: ^14.0.0, @wordpress/i18n: ^15.0.0, @wordpress/components: ^14.0.0, @wordpress/element: ^14.0.0 } }
block.json (metadatos)
block.json es la forma recomendada de declarar metadatos del bloque. Esto permite la autointegración y facilita el empaquetado.
{ schema: https://schemas.wp.org/trunk/block.json, apiVersion: 2, name: my-plugin/my-block, title: Mi Bloque, category: widgets, icon: smiley, description: Un bloque de ejemplo empaquetado con @wordpress/scripts, supports: { html: false }, textdomain: my-block-plugin, editorScript: file:./build/index.js, editorStyle: file:./build/index.css, script: file:./build/frontend.js, style: file:./build/style.css }
Archivo PHP de registro
La forma más simple con block.json es delegar la ruta al metadata en register_block_type. WordPress se encargará de cargar los assets desde los paths generados por wp-scripts.
Archivos JavaScript y estilos
En src/index.js registras tu bloque y exportas lo necesario para la edición/guardado.
import { registerBlockType } from @wordpress/blocks import edit from ./edit import save from ./save import ./editor.scss registerBlockType( my-plugin/my-block, { edit, save, } )// src/edit.js import { __ } from @wordpress/i18n import { RichText } from @wordpress/block-editor export default function Edit( props ) { const { attributes, setAttributes } = props return () }setAttributes({ content }) } /> // src/save.js import { RichText } from @wordpress/block-editor export default function save( { attributes } ) { return () } / src/editor.scss / .my-block-editor { border: 1px dashed #ccc padding: 12px }Uso básico de @wordpress/scripts
Con la configuración anterior, ejecutar:
- npm install
- npm run start
...iniciará un watcher y empaquetará en modo desarrollo. npm run build genera la carpeta build con los assets minificados para producción.
Personalizar Webpack: cuándo y cómo
@wordpress/scripts expone una configuración de Webpack por defecto en @wordpress/scripts/config/webpack.config.js. Para extenderla sin reescribir todo, importa esa configuración y fusiónala con webpack-merge.
Ejemplo: archivo webpack.config.js personalizado
Este ejemplo añade entradas múltiples, personaliza output para cache busting y marca algunos paquetes como externos (evitando bundling de dependencias que WP ya provee).
// webpack.config.js const defaultConfig = require( @wordpress/scripts/config/webpack.config ) const { merge } = require( webpack-merge ) const path = require( path ) module.exports = merge( defaultConfig, { entry: { index: path.resolve( process.cwd(), src, index.js ), frontend: path.resolve( process.cwd(), src, frontend.js ) }, output: { filename: [name].js }, externals: { // Evita incluir @wordpress/element y deja que WP lo provea como window.wp.element @wordpress/element: wp.element, @wordpress/i18n: wp.i18n, react: React, react-dom: ReactDOM }, optimization: { splitChunks: { chunks: all } } } )Notas:
- Usar externals ahorra tamaño de bundle y evita conflictos con la versión de React/element de WordPress.
- Si no pones externals, @wordpress/scripts suele externalizar paquetes de WP por defecto, pero al añadir una configuración personalizada conviene ser explícito.
Manejo de estilos (editor y frontend)
@wordpress/scripts procesa CSS/SCSS importados desde JS y genera archivos .css. Buenas prácticas:
- Importa tu SCSS en el archivo JS de entrada (p. ej. src/index.js) para el CSS del editor.
- Para estilos frontend separados, crea una entrada específica (p. ej. src/frontend.js) que importe src/style.scss y configúralo como script o style en block.json.
- Usa classnames y evita CSS globales excesivos.
Generación de index.asset.php y versionado
Cuando usas wp-scripts build, se genera build/index.asset.php con un array PHP que contiene dependencias y versión basada en el hash. Si registras bloques manualmente desde PHP sin usar register_block_type con metadata, utiliza ese archivo para encolar correctamente:
my-block-editor, editor_style => my-block-editor-style, ) )
Entradas múltiples y código compartido
Cuando tu plugin tiene varios bloques o quieres un bundle compartido, define múltiples entradas en webpack (ejemplo más arriba). Ventajas:
- Chunks compartidos para dependencias comunes.
- Menos duplicación de código entre bloques.
Recuerda exponer cada entrada en block.json o registrarla en PHP con sus handles y dependencies.
Optimización y producción
- Ejecuta npm run build para obtener código minificado y optimizado.
- Habilita splitChunks si tienes varias entradas para repartir dependencias comunes.
- Revisa el contenido de build/index.asset.php puesto que contiene hashes de versión que facilitan el cache busting.
- Evita empaquetar librerías grandes que WordPress ya provea.
Testing y flujo de desarrollo
- npm run start para trabajar con hot reload (watch). Observa la consola por errores de compilación.
- Habilita sourcemaps si necesitas depurar (normalmente wp-scripts ya proporciona sourcemaps en dev).
- Prueba el bloque en diferentes temas y en modo producción después de npm run build.
Errores frecuentes y soluciones
- Error: Cannot find module @wordpress/scripts/config/webpack.config — Asegúrate de tener instalada la versión correcta de @wordpress/scripts y que tu node_modules esté actualizado: npm install.
- CSS no se aplica en frontend — Verifica que register_block_type incluya la key style o que estés registrando la hoja de estilos generada en PHP.
- Problemas de versiones / React duplicado — Usa externals para React/element o evita instalar React como dependencia dentro del bundle.
- Problemas con block.json path — register_block_type( __DIR__ . /block.json ) espera que block.json tenga referencias file:./build/... correctas.
Buenas prácticas
- Usa block.json para definir metadatos y facilitar registro automático.
- Mantén las dependencias de runtime en dependencies y las herramientas de compilación en devDependencies.
- Externaliza paquetes de WP para evitar bundling innecesario.
- Usa archivos index.asset.php generados por build para versionar correctamente los scripts encolados.
- Divide en entradas cuando tengas varios bloques y comparte código común en chunks.
Ejemplo avanzado: dividir en varios bloques
Estructura con dos bloques en src/blocks/block-a y src/blocks/block-b, y una configuración que genere un bundle por bloque:
// webpack.config.js (extracto) const entries = { block-a: path.resolve( process.cwd(), src, blocks, block-a, index.js ), block-b: path.resolve( process.cwd(), src, blocks, block-b, index.js ), } module.exports = merge( defaultConfig, { entry: entries, output: { filename: [name].js, // generará block-a.js y block-b.js path: path.resolve( process.cwd(), build ) }, optimization: { splitChunks: { chunks: all, name: shared } } } )
Registra en PHP cada bloque usando el asset file correspondiente o usa block.json por bloque (cada bloque puede tener su propio block.json en su carpeta y WordPress 5.5 puede manejar registros desde carpetas).
Recursos útiles
Conclusión
Empaquetar bloques con @wordpress/scripts Webpack ofrece una combinación potente y estandarizada: arranca rápido con herramientas ya configuradas y permite personalizaciones cuando se requiere empaquetado avanzado. La clave es aprovechar block.json, usar index.asset.php para versionado y emplear externals para no duplicar librerías que WordPress ya provee. Con las técnicas de entradas múltiples, splitChunks y configuraciones personalizadas puedes escalar y optimizar un conjunto grande de bloques sin perder control sobre la salida final.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |