Skip to content

Instantly share code, notes, and snippets.

@lambdahands
Created September 28, 2015 17:09
Show Gist options
  • Save lambdahands/d19e0da96285b749f0ef to your computer and use it in GitHub Desktop.
Save lambdahands/d19e0da96285b749f0ef to your computer and use it in GitHub Desktop.
FlowType and CSS Modules

Huh?

So basically FlowType doesn't know about CSS Modules, a really handy way of dealing with the plagues of CSS in codebases (global variables and dependency wackiness mainly).

What WebPack allows us to do is "require" CSS files and use their class names:

import styles from "my_styles.css";
import React from "react";

const MyComponent = React.createClass({
  render() {
    return <h1 className={styles.redHeader}>Hello!</h1>;
  }
});

Unfortunately, Flow will give us an error Required module not found because, well, let's be honest, importing CSS with JavaScript is pretty out of this world and a little bit crazy (i.e: this).

So here's what I did to fix that. Flow has a nice way of dealing with this in its options, namely one called module.name_mapper. Somebody was kind enough to make an npm module called empty that– you guessed it– returns empty objects and arrays. I'm pretty amazed to have found a use for this.

So as a fix, do this: Run npm install --save empty in your project directory.

Open your .flowconfig, and add the following under [options]:

module.name_mapper='.*\(.css\)' -> 'empty/object'

Ta-da! Another fun day in JavaScript land.

@sgronblo
Copy link

If anyone still cares, there's been a resolution to this problem on the flow issue I linked in my previous message.

@dlants
Copy link

dlants commented Nov 4, 2016

Just a heads up to anyone who has trouble getting this working, it didn't for me until I added module.system=haste

Got the idea from here: facebook/flow#1068

@ckknight
Copy link

In order to not have to declare CSSModule for every project, I've published an npm package that does so:

https://www.npmjs.com/package/css-module-flow

https://github.com/ckknight/css-module-flow

@faceyspacey
Copy link

faceyspacey commented Jan 16, 2017

but what if you're importing styles without the extension, eg: import styles from '../css/foo' where foo is actually foo.css?

module.file_ext=.css doesn't seem to help in that matter. In fact, for me, it makes flow completely not work in VS Code.

@jeznag
Copy link

jeznag commented Jun 14, 2017

Ghost's solution worked for me:

empty/object is an actual npm module that you need to install: npm install --save-dev empty

And then add this to .flowconfig

[options]
module.name_mapper='.*\(.s?css\)' -> 'empty/object'

@skovhus
Copy link

skovhus commented Jun 20, 2017

What I really wanted was Flow to understand and typecheck my CSS Modules. So it would validate that a given identifier is actually in the .css file. Doing so would give us:

  • static type checks showing usage of non existing classes
  • editor autocompletion of CSS classes (for editors supporting Flow)

I actually just released a few tools to do this. Please give them a try! πŸ˜ƒ

See:

Copy link

ghost commented Jul 6, 2017

@jeznag Thanks! Your post actually saved my day.

@johhansantana
Copy link

@nicolasartman that worked

@ndbroadbent
Copy link

@skovhus That's brilliant! Way better than just ignoring the errors. Thanks for building this!

@mechanicals
Copy link

@jeznag: fantastic. you solution works for me..

@Luna2442
Copy link

Luna2442 commented Dec 15, 2017

Why install another dumb package? Just do this :)

[options]
module.name_mapper='.*(.css.scss)' -> '{}'

@piyushmahen
Copy link

thanks @nicolasartman it works!

@dbchristopher
Copy link

Thanks so much for sharing this!! You're a lifesaver.

@Vages
Copy link

Vages commented Apr 19, 2018

Could not get your solution to work, @Luna2442. According to the documentation (https://flow.org/en/docs/config/options/#toc-module-name-mapper-regex-string),

module.name_mapper (regex -> string)

Specify a regular expression to match against module names, and a replacement pattern, separated by a ->.

For example:

module.name_mapper='^image![a-zA-Z0-9$_]+$' -> 'ImageStub'

This makes Flow treat require('image!foo.jpg') as if it were require('ImageStub').

These are OCaml regular expressions. Use \( and \) (slashes required!) to create a capturing group, which you can refer to in the replacement pattern as \1 (up to \9).

So (1) how did you get your regex capturing group to work without the required slashes and (2) how did you get Flow to ignore the .css imports by feeding it require('{}')?

Original solution works perfectly, @lambdahands

@gabrii
Copy link

gabrii commented Jun 5, 2018

Slight modification from @jsermeno solution, which no longer works (facebook/flow#1806 (comment)):

interfaces/global.js

  declare var exports: { [key: string]: string };
  declare export default typeof exports;
}

.flowconfig

[...]

[libs]
./interfaces/global.js

[options]
module.name_mapper='^\(.*\)\.css$' -> 'CSSModule'
module.system=haste

[...]

I believe @lambdahands solution works, but doesn't offer type coverage.

@Eugene-Musika
Copy link

Eugene-Musika commented Oct 24, 2018

As for me, the best solution is css-modules-flow-types.
It's not just a plug. This thing make types for your css modules.

@KareemSalah
Copy link

KareemSalah commented Oct 27, 2018

Google brought me here, and it's late 2018, and still got that same issue and couldn't really solve it following the comments here, here's what I did eventually:

  1. Create a dump module at PROJECT_ROOT/flow-typed/LESSModule.js.flow
  2. Add this code inside of it
declare module 'LESSModule' {
  declare module.exports: any;
}
  1. Add this line under [options] in .flowconfig (just this line, nothing more πŸ˜„)
module.name_mapper.extension='less' -> 'LESSModule'

Notes that I had to take are that the file name must begin with exactly the same name as the stub module name, if you're going to change the module name to SCSSModule or CSSModule, then change the file name accordingly, also put the file under that same directory, flow-typed should be already there if you did npm i --save flow-typed and ran flow-typed install, I tried putting that file somewhere else, but it didn't work.

@giuliano2014
Copy link

πŸ‘ ❀️

@muravjov
Copy link

@KareemSalah
not working for me,

$ node node_modules/.bin/flow check app.js
Error β”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆβ”ˆ app.js:5:8

Cannot resolve module my.less.

     2β”‚
     3β”‚ import "./my.sass"
     4β”‚ import "LESSModule"
     5β”‚ import "my.less"
     6β”‚
     7β”‚

Found 1 error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment