Sass w Web Components
Nawiązując do poprzedniego artykułu pt. „Pierwszy komponent w Polymerze”, chciałbym zwrócić uwagę na problem związany z umieszczaniem stylów wewnątrz pliku HTML.
Dla przypomnienia wstawię kod źródłowy z poprzedniego wpisu.
<dom-module id="polymer-modal-style">
<template>
<style>
:host {
--modal-width: 400px;
--modal-background: #fff;
--modal-padding: 10px;
--modal-border: 1px solid #000;
display: none;
}
:host([opened]) {
position: fixed;
top: 0;
left: 0;
display: flex;
width: 100vw;
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
justify-content: center;
align-items: center;
}
.modal {
position: relative;
top: 0;
left: 0;
width: var(--modal-width);
background: var(--modal-background);
padding: var(--modal-padding);
border: var(--modal-border);
}
.modal__heading {
border-bottom: var(--modal-border);
}
.modal__close {
position: absolute;
top: var(--modal-padding);
right: var(--modal-padding);
}
</style>
</template>
</dom-module>
Umieszczenie stylów w pliku HTML, powoduje komplikacje, w momencie, gdybyśmy chcieli użyć preprocesora Sass. Wynika to z faktu, że Sass nie potrafi ignorować znaczników HTML. Próba skompilowania powyższego kodu najpewniej zakończy się syntax errorem.
Rozwiązanie problemu
W celu rozwiązania problemu użyję Gulpa,
gulp-sass i
gulp-style-modules.
Szczególnie istotny jest tutaj plugin gulp-style-modules
, którego zadaniem jest opakowywanie kodu CSS
w deklarację modułu typową dla Polymera.
Utwórzmy zatem plik package.json:
{
"devDependencies": {
"gulp": "^3.9.1",
"gulp-sass": "^3.1.0",
"gulp-style-modules": "^0.1.0"
}
}
Teraz należy wykonać komendę npm install
i utworzyć plik o nazwie gulpfile.js
,
w którym zostanie napisany task odpowiedzialny za kompilowanie plików .scss.
const gulp = require('gulp');
const stylemod = require('gulp-style-modules');
const sass = require('gulp-sass');
gulp.task('modularize-styles', () => {
return gulp.src('./src/elements/**/*.scss')
.pipe(sass({
outputStyle: 'compressed',
}).on('error', sass.logError))
.pipe(stylemod())
.pipe(gulp.dest("./src/elements"));
});
gulp.task('watch:modularize-styles', () => {
return gulp.watch('./src/elements/**/*.scss', ['modularize-styles']);
});
W powyższym pliku zostały utworzone dwa taski: modularize-styles
i watch:modularize-styles
.
Pierwszy z nich służy do budowania modułów ze stylami, natomiast drugi do tego samego,
lecz w czasie rzeczywistym (jest to tzw. watcher).
Od teraz dla każdego z plików scss umieszczonych w folderze src/elements
, zostanie utworzony plik modułu
z przyrostkiem -styles.html
.
Utworzę plik o nazwie polymer-modal.scss
, żeby zobrazować jak to działa.
:host {
--modal-width: 400px;
--modal-background: #fff;
--modal-padding: 10px;
--modal-border: 1px solid #000;
display: none;
}
:host([opened]) {
position: fixed;
top: 0;
left: 0;
display: flex;
width: 100vw;
height: 100vh;
overflow-y: auto;
overflow-x: hidden;
justify-content: center;
align-items: center;
}
.modal {
position: relative;
top: 0;
left: 0;
width: var(--modal-width);
background: var(--modal-background);
padding: var(--modal-padding);
border: var(--modal-border);
&__heading {
border-bottom: var(--modal-border);
}
&__close {
position: absolute;
top: var(--modal-padding);
right: var(--modal-padding);
}
}
Po uruchomieniu komendy gulp modularize-styles
zostanie utworzony plik polymer-modal-styles.html
.
W jego wnętrzu znajdzie się deklaracja modułu o id
identycznym z nazwą pliku bez rozszerzenia.
Tak wygląda kod wynikowy:
<dom-module id="polymer-modal-styles">
<template>
<style>
:host{--modal-width:400px;--modal-background:#fff;--modal-padding:10px;--modal-border:1px solid #000;display:none}:host([opened]){position:fixed;top:0;left:0;display:flex;width:100vw;height:100vh;overflow-y:auto;overflow-x:hidden;justify-content:center;align-items:center}.modal{position:relative;top:0;left:0;width:var(--modal-width);background:var(--modal-background);padding:var(--modal-padding);border:var(--modal-border)}.modal__heading{border-bottom:var(--modal-border)}.modal__close{position:absolute;top:var(--modal-padding);right:var(--modal-padding)}
</style>
</template>
</dom-module>
Podsumowanie
Pokazałem, że używanie Sass w komponentach webowych wcale nie jest takie trudne. Co prawda wymaga to poświęcenia dodatkowego czasu na skonfigurowanie gulpa, ale w ostatecznym rozrachunku i tak się to opłaci ze względu na zmniejszoną liczbę linii kodu źródłowego stylów.