DEV Community

loading...
Cover image for Creación de un proyecto svelte + bulma + sass.

Creación de un proyecto svelte + bulma + sass.

1n0t profile image 1N0T ・4 min read

Durante las vacaciones de verano, descubrí svelte, un framework javascript que me ha parecido interesante, así que decidí realizar algunas pruebas de concepto. Una de ellas, era la integración con algún frameworks CSS popular y, ya puestos, que fuera personalizable con sass.

Buscando ejemplos y documentación, encontré alguna referencia al uso de tailwindcss y bulma, pero si bien describían como integrar el uso de sass, durante la fase de build, no se eliminaban los estilos css no utilizados, por lo que un hola mundo, con unas pocas clases css, acababa ocupndo más de 200KB.

Pese a que dediqué algo de tiempo a la búsqueda, no encontré ningún ejemplo que lo hiciera, asi que me ha parecido que podría ser interesante compartir la solución que, tras varios intentos fallidos, me ha funcionado.

Asumiré que ya conoces svelte (si no es así, te aconsejo que visites su sitio web que está bastante bien documentado). Tampoco explicaré nada de bulma y sass (entre otras cosas, porque mis conocimientos brillan por su ausencia) así que me limitaré a enumerar brevemente los pasos necesarios para la configuración inicial mínima de un proyecto muy básico (como se puede observar en la imagen), pero que consigue el resultado perseguido, tener un esqueleto funcional con los 3 elementos integrados.

Hello World

Lo primero que haremos es crear un nuevo proyecto svelte utitlizando el procedimiento habitual,y al que llamaremos bulma-sass.

npx degit sveltejs/template bulma-sass
cd bulma-sass/

Instalaremos las dependencias y módulos necesarios.

npm install
npm install --save-dev bulma
npm install --save-dev node-sass
npm install --save-dev rollup-plugin-postcss 
npm install --save-dev @fullhuman/postcss-purgecss

Como no lo necesitaremos, borramos el contenido de global.css y App.svelte.

echo > ./public/global.css
echo > ./src/App.svelte

Nos aseguramos de que en la página public/index.html los enlaces sean relativos, en lugar de absolutos desde la raiz.

    <link rel='stylesheet' href='global.css'>
    <link rel='stylesheet' href='build/bundle.css'>

    <script defer src='build/bundle.js'></script>

Creamos el fichero src/mi-bulma.scss para personalizar bulma a nuestro gusto y, como podéis comprobar, me he limitado a modificar las fuentes y el color primario, pero es suficiente para comprobar que el circuito funciona correctamente.

@charset "utf-8";

// Importamos fuentes de Google Font
@import url('https://fonts.googleapis.com/css?family=Nunito:100,200');

// Definimos nuestros colores
$color-primario: #990099;

// Actualizamos variables globales de Bulma
$family-sans-serif: "Nunito", sans-serif;
$primary: $color-primario;

// Importamos lo que necesitemos de Bulma.
@import "../node_modules/bulma/sass/utilities/_all.sass";
@import "../node_modules/bulma/sass/base/_all.sass";
@import "../node_modules/bulma/sass/components/_all.sass";
@import "../node_modules/bulma/sass/elements/_all.sass";
@import "../node_modules/bulma/sass/form/_all.sass";
@import "../node_modules/bulma/sass/grid/_all.sass";
@import "../node_modules/bulma/sass/layout/_all.sass";
@import "../node_modules/bulma/sass/helpers/_all.sass";

Ahora procedemos a modificar el fichero rollup.config.js generado por defecto, para que tenga el siguiente aspecto

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import livereload from 'rollup-plugin-livereload';
import { terser } from 'rollup-plugin-terser';

// Añadidos a configuración por defecto para procesar Bulma scss
import postcss from 'rollup-plugin-postcss';                  // [+]
import Purgecss from "@fullhuman/postcss-purgecss";           // [+]

// Indicamos archivos a examinar para eliminar estilos no utilizados.
const purgeCss = Purgecss({                                   // [+]
    content: ["./src/**/*.svelte"],                           // [+]
    whitelist: ['body']                                       // [+]
});                                                           // [+] 

const production = !process.env.ROLLUP_WATCH;

function serve() {
    let server;

    function toExit() {
        if (server) server.kill(0);
    }

    return {
        writeBundle() {
            if (server) return;
            server = require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], {
                stdio: ['ignore', 'inherit', 'inherit'],
                shell: true
            });

            process.on('SIGTERM', toExit);
            process.on('exit', toExit);
        }
    };
}

export default {
    input: 'src/main.js',
    output: {
        sourcemap: true,
        format: 'iife',
        name: 'app',
        file: 'public/build/bundle.js'
    },
    plugins: [
        svelte({
            // enable run-time checks when not in production
            dev: !production,
            // we'll extract any component CSS out into
            // a separate file - better for performance
            css: css => {
                css.write('bundle.css');
            }
        }),

        // Plugin para postproceso de CSS
        postcss({                                             // [+]      
            plugins: [                                        // [+]
              purgeCss                                        // [+]
            ]                                                 // [+]
        }),                                                   // [+]


        // If you have external dependencies installed from
        // npm, you'll most likely need these plugins. In
        // some cases you'll need additional configuration -
        // consult the documentation for details:
        // https://github.com/rollup/plugins/tree/master/packages/commonjs
        resolve({
            browser: true,
            dedupe: ['svelte']
        }),
        commonjs(),

        // In dev mode, call `npm run start` once
        // the bundle has been generated
        !production && serve(),

        // Watch the `public` directory and refresh the
        // browser on changes when not in production
        !production && livereload('public'),

        // If we're building for production (npm run build
        // instead of npm run dev), minify
        production && terser()
    ],
    watch: {
        clearScreen: false
    }
};

He marcado las líneas añadidas con el comentario // [+]. No son muchas, pero son la clave de la solución.

Ya está todo preparado para que desarrollemos nuestra magnífica aplicación. Lo único que tenemos que hacer es importar nuestro fichero src/mi-bulma.scss en el fichero src/App.svelte para poder utilizar los estilos de bulma y dar rienda suelta a nuestra imaginación.

Os dejo, a modo de ejemplo, mi complicado desarrollo.

<script>
     import './mi-bulma.scss';
</script>

<section class="section">
    <div class="container">
        <h1 class="title">
            <span style="color: blue">Hello</span> World
        </h1>
        <p class="subtitle" style="color: purple">
            Mi primer website con <strong>svelte + bulma + sass</strong>.
        </p>
        <p>
            <button class="button">
            Botón
            </button>

            <button class="button is-primary">
            Botón primario
            </button>

            <button class="button is-warning">
            Advertencia
            </button>
        </p>
    </div>
</section>

Ya sólo nos falta ejecutar

npm run build

Et voilà !!! en 8KB tenemos empaquetada nuestra aplicación con todo lo necesario para funcionar.

Discussion

pic
Editor guide