Migrando para o wp-scripts: análise de dois casos
O wp-scripts (@wordpress/scripts1) é um pacote com um conjunto de scripts para padronizar e simplificar o desenvolvimento de projetos WordPress que precisam transformar e otimizar o código JavaScript e outros assets (images, fontes, arquivos CSS, etc) para que seja compatível com a maioria dos navegadores.
Dessa forma, ao invés de configurar ferramentas como webpack2, Babel3 e ESLint4, você pode usar o wp-scripts para que essa única dependência seja responsável por isso e você possa se concentrar em outros aspectos do seu projeto WordPress.
Motivos para migrar
- Você não precisa aprender e configurar várias ferramentas (webpack, Babel, ESLint, etc)
- Reduz o número de depêndencias do projeto
- Facilidade na manutenção e atualização em especial se você trabalha com vários projetos ao mesmo tempo
- Ajuda manter a qualidade do código
- Ajuda a seguir os padrões de formatação de código do WordPress
Motivos para não migrar
Dependendo da estrutura do seu projeto, você vai precisar customizar o wp-scripts. A customização pode ser passar um parâmetro adicional na hora de executar um script e/ou usar o seu próprio arquivo de configuração do webpack.
Preparando o ambiente
Será usado o node v20.11.0 e npm v10.2.4. Vamos iniciar um projeto npm e instalar o pacote wp-scripts como dependência do ambiente de desenvolvimento.
# Inicia um projeto com os valores padrão
npm init -y
# Instala o pacote wp-scripts
npm install @wordpress/scripts --save-dev
No arquivo package.json, vamos adicionar alguns scripts básicos chamando o wp-scripts. Existem outros, mas vamos nos concentrar nesses que eu julgo serem os mais importantes se você quer migrar para o wp-scripts.
{
[...]
"scripts": {
"build": "wp-scripts build",
"format": "wp-scripts format",
"lint:css": "wp-scripts lint-style",
"lint:js": "wp-scripts lint-js"
},
[...]
}
Por fim, vamos adicionar três arquivos na pasta src
: index.js, style.scss e image.png.
// index.js
console.log('Hello world!');
// style.scss
.my-class {
background-color: #9ca3af;
}
A estrutura do projeto vai ficar dessa forma:
wp-scripts-post/
├── src/
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── package.json
├── node_modules/ (gerado automaticamente)
└── package-lock.json (gerado automaticamente)
Casos
#1
O caso mais ideal é onde os arquivos JavaScript importam os demais assets via import. Nesse cenário, você basicamente precisa rodar o comando build e uma nova pasta será criada como resultado.
Para chegarmos nesse cenário usando os arquivos inicias do nosso projeto, precisamos atualizar o arquivo index.js para importar os arquivos style.scss e image.png.
// index.js
import './style.scss';
import 'image.png';
console.log('Hello world!');
Após executar o comando npm run build
, teremos a seguinte estrutura:
wp-scripts-post/
├── build/
│ ├── index.asset.php
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── src/
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── package.json
├── node_modules/ (gerado automaticamente)
└── package-lock.json (gerado automaticamente)
Note que index.asset.php também é criado. Este arquivo é útil na hora de inserir o script em uma página por meio da função wp_enqueue_script5 pois nele temos as dependências do script e um número de versão.
Podemos ter uma varição desse cenário ideal que é quando seus arquivos fonte não estão na pasta src e/ou o resultado do script build não deve ficar na pasta build. Por exemplo, os arquivo estão na pasta source e o resultado deve ser colocado na pasta dist.
Nesse caso, podemos seguir dois caminhos. O primeiro é passar parâmetros adicionais ao comando build para especificar qual deve ser a pasta utilizada como entrada e qual pasta deve ser utilizada como saída. Os parâmetros nesse caso são --webpack-src-dir
e --output-path
.
{
[...]
"scripts": {
"build": "wp-scripts build --webpack-src-dir=source --output-path=dist",
[...]
},
[...]
}
Para os scripts format
, lint-css
e lint-js
é preciso passar o caminho para o diretório na frente do comando.
{
[...]
"scripts": {
[...]
"format": "wp-scripts format ./source",
"lint:css": "wp-scripts lint-style ./source",
"lint:js": "wp-scripts lint-js ./source"
},
[...]
}
A segunda forma de especificar as pastas de entrada e saída é por meio de um arquivo de configuração do webpack. Para isso precisamos criar um arquivo webpack.config.js
.
wp-scripts-post/
├── build/
│ ├── index.asset.php
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── src/
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── webpack.config.js <-- <-- <--
├── package.json
├── node_modules/ (gerado automaticamente)
└── package-lock.json (gerado automaticamente)
No webpack.config.js vamos modificar duas configurações: entry6 e output.path7. Note que no arquivo abaixo nós modificamos apenas essas duas configurações e continuamos usando as configurações padrão do wp-scripts. O que facilita o uso das configurações padrão é o spread operator8 (…)
const path = require('path');
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
module.exports = {
...defaultConfig,
entry: './source',
output: {
...defaultConfig.output,
/**
* A configuração `output.path` espera um caminho
* absoluto e por isso usamos a função `path.resolve`.
*/
path: path.resolve(__dirname, 'dist')
},
}
Ao executar o comando npm run build
o arquivo webpack.config.js será utilizado automaticamente pois ele está no mesmo diretório que o arquivo package.json. Também é possível especificar um caminho para o arquivo webpack.config.js por meio da opção --config
.
#2
Nesse segundo caso, suponha que você tenha mais de um arquivo JavaScript, CSS e imagem. Além disso, você não importa os arquivos de CSS e imagem nos arquivos JavaScript. Apesar de ser possível atualizar os arquivos JavaScript para importar os assets, nesse primeiro momento você quer apenas incorporar o wp-scripts ao seu projeto sem alterar os seus arquivos fontes.
Apenas para recapitular, temos essa estrutura de pastas e arquivos:
wp-scripts-post/
├── src/
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── package.json
├── node_modules/ (gerado automaticamente)
└── package-lock.json (gerado automaticamente)
// index.js
console.log('Hello world!');
// style.scss
.my-class {
background-color: #9ca3af;
}
Sem fazer nenhuma alteração e executando o wp-scripts build (npm run build
), teremos como resultado na pasta build apenas os arquivos index.js e index.asset.php:
wp-scripts-post/
├── build/
│ ├── index.js
│ └── index.asset.php
├── src/
│ ├── index.js
│ ├── style.scss
│ └── image.png
├── package.json
├── node_modules/ (gerado automaticamente)
└── package-lock.json (gerado automaticamente)
Isso ocorre pois o arquivo style.scss e image.png não foram importados no arquivo index.js. Dessa forma, não é possível que o script de build saiba da existência desses arquivos.
Nesse cenário, vamos utilizar o arquivo webpack.config.js para informar os arquivos que queremos utilizar como entrada na configuração entry. Ao invés de passarmos uma string, vamos passar um objeto onde a chave será o nome da nossa entrada e o valor um array de strings com o caminho dos arquivos de JavaScript e SCSS:
const path = require('path');
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
module.exports = {
...defaultConfig,
entry: {
index: ['./src/index.js', './src/style.scss']
},
}
Ao executar o comando npm run build, teremos o seguinte resultado na pasta build:
wp-scripts-post/
├── build/
│ ├── index.js
│ ├── style-index.css
│ └── index.asset.php
[...]
Apesar dos dois arquivos terem sido gerados, o nome do arquivo CSS teve uma mudança de style.scss para style-index.css. Como isso pode ser um problema pois teríamos que alterar o nome desse arquivo onde ele é usado, vamos ajustar nossa configuração para gerar o arquivo CSS com o nome style.css.
O webpack é uma ferramenta que possui muitas configurações e que consegue lidar com diversos cenários. Além disso, permite que suas funcionalidades sejam extendidas por meio de uma interface para plugins9.
Se você analisar o webpack.config.js do wp-scripts10, notará que o wp-scripts utiliza alguns plugins. Um deles é o MiniCssExtractPlugin11. Este plugin extrai o CSS para um arquivo separado. Se esse plugin não fosse utilizado e executassemos npm run build
, o CSS importado em um arquivo JavaScript seria inserido no arquivo JavaScript compilado.
Assim, para alterar o nome do arquivo CSS precisamos alterar a configuração filename12 do plugin MiniCssExtractPlugin. Como esse plugin é inserido pelo wp-scripts, primeiro vamos removê-lo e depois inserir novamente com a nossa configuração. A nossa configuração consiste em remover tudo depois do traço do nome do arquivo. Dessa forma, ao invés do nome do arquivo ser style-index
, será apenas style
.
// webpack.config.js
const defaultConfig = require( '@wordpress/scripts/config/webpack.config' );
const MiniCSSExtractPlugin = require( 'mini-css-extract-plugin' );
// Remove o plugin MiniCSSExtractPlugin da lista de plugins do wp-script.
const plugins = defaultConfig.plugins.filter(
plugin => ! (plugin instanceof MiniCSSExtractPlugin)
);
module.exports = {
...defaultConfig,
entry: {
index: ['./src/index.js', './src/style.scss'],
},
plugins: [
...plugins,
// Adiciona o plugin MiniCSSExtractPlugin
new MiniCSSExtractPlugin( {
filename: ({chunk}) => {
// Regex para remover tudo depois do `-`.
return `${chunk.name.replace(/-.*/, '')}.css`
},
} ),
]
}
Ao executar npm run build
, teremos o resultado esperado:
wp-scripts-post/
├── build/
│ ├── index.js
│ ├── style.css
│ └── index.asset.php
[...]
Um detalhe interessante é que se utilizarmos uma imagem no arquivo style.scss, o wp-scripts irá copiar essa imagem para dentro da pasta build e ajustar o arquivo style.css para referenciar o nome correto da imagem na pasta build.
// style.scss
.my-class {
background-color: #9ca3af;
background-image: url('./image.png');
}
wp-scripts-post/
├── build/
│ ├── images/
│ │ └── image.438eef35.png
│ ├── index.js
│ ├── style.css
│ └── index.asset.php
[...]
Se você tem outros arquivos .js e .scss, basta adicioná-los na chave entry do webpack.config.js que executar o comando de build, esses arquivo também serão processados pelo wp-scripts.
Conclusão
O wp-scripts é uma boa ferramenta e pode acelerar o desenvolvimento de projetos WordPress onde o código se apoia fortemente no JavaScript. Entretanto, se o seu projeto foge um pouco do básico, configurar o wp-scripts para que se adapte a suas necessidades pode ser desafiador pois você precisará entender e ir um pouco afundo em como o webpack funciona. Somado ao fato de que é difícil encontrar tutoriais e/ou exemplos de casos não triviais.
No universo WordPress existe outra alternativa que é o 10up-toolkit. Mas se você gostaria de usar uma ferramenta que não fica no seu caminho, possui uma interface mais compreensível e uma curva de aprendizagem pequena, então Laravel Mix pode ser a ferramenta mais adequada.
Para conhecer mais opções e configurações do wp-scripts:
- https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/
- https://developer.wordpress.org/block-editor/getting-started/devenv/get-started-with-wp-scripts/
Notas de rodapé
- https://developer.wordpress.org/block-editor/reference-guides/packages/packages-scripts/ ↩︎
- https://webpack.js.org/ ↩︎
- https://babeljs.io/ ↩︎
- https://eslint.org/ ↩︎
- https://developer.wordpress.org/reference/functions/wp_enqueue_script/ ↩︎
- https://webpack.js.org/configuration/entry-context/#entry ↩︎
- https://webpack.js.org/configuration/output/#outputpath ↩︎
- https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Operators/Spread_syntax ↩︎
- https://webpack.js.org/plugins/ ↩︎
- https://github.com/WordPress/gutenberg/blob/trunk/packages/scripts/config/webpack.config.js#L306 ↩︎
- https://webpack.js.org/plugins/mini-css-extract-plugin ↩︎
- https://webpack.js.org/plugins/mini-css-extract-plugin#filename ↩︎