State of CSS in Meteor

I’d like to think that’s not an issue with the caching, but if it is you can use the newly documented cache option to disable it.

I’d be surprised if it’s a cache issue, but it could be. The cache check uses a hash of your source file (generated by Meteor’s caching compiler package) + a hash of your package options to determine if a file needs reprocessed.
Anyways, if you continue to see this issue, please let me know.

Also, yes - a meteor reset will also reset your cache.

1 Like

After making the switch on-the-go to CSS Modules and a few days of first hand experience, I’m really happy I switched :heart: I’d say I spent a few hours understanding the patterns, flow and syntax to be productive enough, which was gained back in the next few hours because of not having to write BEM class names anymore.

It feels like a missing piece of a near-perfect-stack has been found. I never could justify doing CSS-in-JS with all the quirks and issues (media queries for example). Meanwhile, CSS Modules sits in the middle, taking best of both worlds (or that’s how it feels) and is just pure awesome [*] .

[*] As long as you know the few no-can-do’s that can pretty easily be worked around

@nathantreid, thanks for making this package! I highly recommend it.

1 Like

@nathantreid , right now my class names are like this even in production builds:

_client_modules_tools_guests__guests_m__primaryButton

Does CSS Modules -package support truncating this to something like button_15jfiefj2x in production builds?

Class shortening for production is on my list, but I haven’t implemented it yet. In case you’d like to more into it, the class name generation takes place here: https://github.com/nathantreid/meteor-css-modules/blob/master/postcss-plugins.js#L16

1 Like

@arggh I just published nathantreid:css-modules@1.5.0-beta.1, which includes support for supplying a template string in the package.json:

"cssModules": 
  "cssClassNamingConvention": {
    "template": "some string"
  }
}

The template uses es6 template literal syntax, and has the following arguments available (examples use the class .world from the file client/hello.css):
scopedName: the default css class name (_client__hello__world)
path: the sanitized path to the css file (_client__hello)
originalPath: the unsanitized path to the css file (D:\projects\css-modules\demo-css\client\hello.css)
name: the class name (world)
hasha: a reference to the hasha package
shorthash: a reference to the shorthash package

To create hashed CSS classes, you could use one of the following templates:

"template": "${name}--${hasha(scopedName, {algorithm: 'md5'})}" // world--200da8ad03f9a588526a2fe8c1c3fe73
"template": "${name}--${hasha(scopedName, {algorithm: 'md5'}).substring(0, 5)}" // world--200da
"template": "${name}--${shorthash.unique(scopedName)}" // world--1etuHN

Custom template strings will be run through any replacers you have set up.

[edit] Forgot to mention I also added a way to create your own custom generator function (inspired by @akryum’s addons to his vue package). Create a new package in your app’s packages folder e.g. meteor create --package scoped-name, add it your app, and make it a build plugin (package.js):

Package.describe({
  name: 'scoped-name',
  version: '0.0.1',
  summary: '',
  git: '',
  documentation: 'README.md'
});


Package.registerBuildPlugin({
  name: 'scoped-name',
  use: [
    'ecmascript',
  ],
  sources: [
    'scoped-name.js'
  ]
});

Then set up your own generater function (scoped-name.js):

global.cssModules = global.cssModules || {};
global.cssModules.generateScopedName = function(exportedName, filePath, sanitisedPath) {
  return `abc-${exportedName}_${sanitisedPath}`;
};

Now your styles will look like: abc-world_client__hello.

Let me know what you think - I’m open to feedback!

Great! I’ll try it as soon as I get to my laptop :ok_hand:t2:

I just checked out the repo on Github, happy to notice CSS Modules is evolving!

I’m facing a new problem that I wanted to ask @nathantreid 's opinion for, it’s related to theming:

Let’s say I have an app like Wix or Squarespace, where a user can create websites using simple building blocks like title or map or imageGallery.

Now, I want to support theming, so that the user can switch and toggle between different looks or even mix and match them.

My initial idea is to use a passed down (or shared) property to specify the selected theme’s name, eg. black or red. I could allow the user to define a global theme for the page, but also to override it on block level to mix themes.

How? Let’s say I have a building block called title.

  • In the title.m.css file, I have a class for each theme like so:
.default {
   .title { color: grey; }
}

.black {
   .title { color: black; }
}

.red {
   .title { color: red; }
}
  • In JS, retrieve styles like so:
import themes from './title.m.css';

themeClass() {
   const themeName = Template.currentData().theme || DEFAULT_THEME_NAME;
   return themes[themeName];
}
  • In template code:
<div class="{{themeClass}}">
   <h1>Title</h1>
</div>

I did a quick POC and this seems to work just fine.

I really can’t think of any alternative way of achieving the same using CSS Modules. That worries me, am I missing something? Any ideas how you would do the same? :slight_smile:

First off, thanks, because I just found/patched a SASS importing bug while replying to this. :slight_smile:
I’m not quite sure what you’re asking. I see you’ve got a working example, but you’re worried about it. Could you explain why?
If I were doing switchable themes, I’d likely do something very similar, except I prefer to use SASS, so it’d look like this (assuming that my styles would end up being much more complex than in the example):
_variables.scss

$default: (
  textColor: grey,
);

$red: (
  textColor: red,
);

title.scss

@import '/imports/themes/_variables.scss';

@mixin styles($theme) {
  .title {
    color: map-get($theme, textColor);
  }
}

.default {
  @include styles($default);
}

.red {
  @include styles($red);
}

The JS would be the same as what you have.

You’re most welcome :smiley:

CSS Modules is still a fresh concept for me!

I stumbled across a few different ideas regarding theming with CSS Modules and was perplexed by the implied difficulty of the problem, when it seemed quite simple to me. Probably my scenario just happened to be very easy.

I guess I just wanted to double check my ideas with someone who knows this stuff before I use the pattern above to write quite many lines of theming related code :slight_smile:

Thanks for the input (and for the package)!

1 Like