I am very new to Aurelia, and new web development in general (nodejs, gulp, and so on).
Thanks to the Aurelia CLI it was easy for me to setup a nice Aurelia project for Visual Studio Code using Typescript + SASS. I thought it would be a good idea (but please tell me if it is not a good idea :) to use scoped css. There is already much information about this subject, but it is hard to find something that I can actually use. So I thought I would do it myself in the following way:
- I have general stylesheets that can be imported "anywhere". Nothing new needs to be done to do this.
- There will be component specific stylesheets that match the component name + ".scss". So e.g. if there is a view + model like: component.ts, component.html, there can be a component.scss which will contain styling that is specific for component.ts and component.html and thus should be scoped to this component.
I've tried to use style scoped html tags but this is not widely supported by browsers (and seems to be dropped from the spec?) and I've tried something (I forgot what I've tried exactly) as described on
https://github.com/bryanrsmith/aurelia-binding-loader
with:
<template>
<require from="styles.css!module!bind" as="styles"></require>
<div class.one-time="styles.first">First</div>
<div class.one-time="styles.second">Second</div>
</template>
which was very slow.
My knowledge about all this is very limited and I think it does a conversion from CSS to a JS object, after which the class of a tag are bound to the style in the JS object.
I thought it would make sense to to this conversion to JS at build time. So with my very limited gulp knowledge I changed process-css.ts in the following way:
import * as gulp from 'gulp';
import * as sourcemaps from 'gulp-sourcemaps';
import * as sass from 'gulp-sass';
import * as project from '../aurelia.json';
import { build } from 'aurelia-cli';
import * as path from "path";
import * as fs from "fs";
import * as rename from "gulp-rename";
import * as postcssmodules from "postcss-modules";
import * as postcss from "postcss"
import * as postcssJs from "postcss-js"
import * as tap from "gulp-tap";
export default function processCSS() {
return gulp.src(project.cssProcessor.source)
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(tap(handleCss))
.pipe(build.bundle())
};
function handleCss(cssFile, t) {
// get the path of the html file
var baseFilename = path.basename(cssFile.path, '.css');
var baseFilepath = path.join(path.dirname(cssFile.path), baseFilename);
var htmlFilepath = baseFilepath + '.html';
// check if the html file exists
if (fs.existsSync(htmlFilepath)) {
var root = postcss.parse(cssFile.contents.toString());
var cssAsJson = postcssJs.objectify(root);
var s = JSON.stringify(cssAsJson);
cssFile.contents = Buffer.from(s);
}
}
(adding handleCss).
This is not yet finished. The new object with the style has to be added to the bundle under the same name but WITH an extension ".js". How can I do this in a nice way?
It would be nice if this would work, but still it would be limited to scoped css classes, not css elements. Another possibility I thought about is, maybe the component.scss styling can be inserted into the component.html (e.g. setting style properties of elements) during build time? If so, how could/should this be done? And are there any drawbacks from doing this?
Sorry if there are "dumb" questions in this post, basically this is all very new and it is difficult to find where to begin.
Thanks!
css_prefix, and add that class to your template tag (<template class='css_user_list>). That should effectively restrict the CSS tags to anything inside that component (and its children). - LStarky.my-component) and because there can't be two components with the same name, you'll never have two classes with the same names either. Optionally, you could actually use anidinstead. Arguably that's exactly what it's for (uniquely styling a single element and its descendants). - powerbuoy