No .NET6 as aplicações ganharam o Hot Reload para agilizar o desenvolvimento. Abaixo explico uma maneira de adicionar o Tailwindcss mantendo sua funcionalidade de purge das classes css durante o desenvolvimento.
Em um terminal na pasta raiz do projeto Blazor execute a instalação do Tailwindcss:
/BlazorApp> npm install -D tailwindcss
Crie o arquivo de configuração do Tailwind:
/BlazorApp> npx tailwindcss init
Adicione as regras de purge. No caso queremos rastrear também os arquivos .razor
:
module.exports = {
mode: 'jit',
purge: [
'./**/*.html',
'./**/*.razor', // <=== ARQUIVOS .razor!!!!!
'./**/*.js',
],
darkMode: false, // or 'media' or 'class'
theme: {
extend: {},
},
variants: {
extend: {},
},
plugins: [],
}
Adicione as instruções de @import
do Tailwind em um css. Eu coloquei aqui:
São essas abaixo, conforme as instruções de instalação no site oficial:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
Para seguir com o desenvolvimento com o Hot Reload e a geração automatica das classes do Tailwind é necessário executar 2 terminais, um para o dotnet e outro para o Tailwind:
/BlazorApp> dotnet watch run
/BlazorApp> npx tailwindcss -i ./Styles/app.css -o ./wwwroot/css/app.css --watch
<=== Não se esqueça de ajustar aqui os arquivos de input e output conforme sua necessidade!
Para evitar o incômodo de abrir 2 terminais e executar 2 comandos, você pode instalar o concurrently
:
/BlazorApp> npm install -D concurrently
Adicione o seguinte script em seu package.json
:
{
"scripts": {
"serve": "concurrently --kill-others \"dotnet watch run\" \"npx tailwindcss -i ./Styles/app.css -o ./wwwroot/css/app.css --watch\""
}
}
(Mais uma vez, não se esqueça de ajustar os arquivos de input e output)
Com isso é possível executar em um único terminal tanto o watch do dotnet quanto o do Tailwind:
/BlazorApp> npm run serve
Porém essa solução possui um problema pois eventualmente o Hot Reload do Blazor não consegue resolver as alterações e ele solicita resposta do usuário para realizar um reinício da aplicação:
Até então não consegui fazer o concurrently
repassar o input para o processo do dotnet. Isso poderia ser contornado caso o dotnet watch
tivesse uma opção para determinar a resposta padrão desde o início.
Se eu encontrar alguma solução, voltarei para atualizar este texto.