Como empaquetar bloques con Webpack y @wordpress/scripts en WordPress

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:

  1. npm install
  2. 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 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *