Skip to content

Compile-check LESS/CSS classnames using TypeScript and Webpack

Alt

As I am making myself familiar with modern frontend development based on React, TypeScript, Webpack and some more I learned something really cool. I like to write this down not only for you – dear reader – but also for my own reference.

The problem

Let’s say you have a trivial React component like this where you specify a classsName to tell what CSS class should be used:

const MyComponent = (props: MyComponentProps) => (

....

);

export default MyComponent;

The problem with this is that we don’t have any compiler-check to ensure this class myclass really exists in our LESS file. So if we have a Typo or later change the LESS file we can not be sure all classes/selectors are still valid. Not even the browser will show that. It silently breaks. Bad thing!

A solution

Using Webpack and the LESS loader one can fix this by check this at compile time. To do so you can define the style and its classname in the LESS file and import it into .tsx files. The LESS loader for webpack will expose the following LESS variables to the build process where the TypeScript loader (used for the .tsx files) can pick it up.

MyComponent.less:

@my-class: ~':local(.myClass)';

@{my-class}{
width: 100%;
background-color: green;
}
...

Note the local() function supported by the LESS loader (see webpack config at the end) which scopes that class to a local scope.

The above LESS files can be typed and imported into the .TSX file like this:

MyComponent.tsx:

type TStyles = {
myClass: string;
};

const styles: TStyles = require('./MyComponent.less');

const MyComponent = (props: MyComponentProps) => (

....

);

export default MyComponent;

Then firing your build the .less file gets picked up using the require() function and checked against the TypeScript type TStyles. The property myClass will contain the LESS/CSS classname as defined in the .less file.

I then can use the styles.myClass instead of the string literal of the original code.

To get this working ensure you have to LESS loader included in your webpack configuration (you probably have if your are already using LESS:

webpack.json:

module: {
rules: [
{
test: /.tsx?$/,
loader: "ts-loader"
},
{
test: /.less$/,
use: ExtractTextPlugin.extract({
use: [
{
loader: "css-loader",
options: {
localIdentName: '[local]--[hash:5]',
sourceMap: true
}
}, {
loader: "less-loader",
options: {
sourceMap: true
}
}
],
fallback: "style-loader",
...
}),
...
},
...

Note: The samples use LESS stylesheets but one can to the same with SCSS/SASS – I guess. You just have to use another loader for webpack and therefore the syntax supported by that loader.

No broken CSS classnames anymore – isen’t this cool? Let me know your feedback.

marcd View All

I love to write software. More then two decades ago I managed to make my hobby my full-time job so I spent more then 20 year writing professional software (I guess that makes me a "Senior Software Developer"). The last few years I spend most of the time developing in C#/.Net for all kind of windows-, web- and embedded-software.

In my free time I enjoy my family, taking photos and go diving in cold lakes and rivers in Switzerland.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: