Flow: How to use declarations to avoid "required module not found" errors?

Created on 15 Jul 2016  路  21Comments  路  Source: facebook/flow

Per this discussion, I've added .*/node_modules/.* to the ignore section of .flowconfig. And so I'm getting errors about certain imported modules not being found.

I'm tackling the invariant package first. But, from the Flow documentation on declarations, I can't figure out what I need to do. It almost seems like I need to stub it somehow, so I'll stop seeing this error:

imports/helpers.js:3
  3: import invariant from 'invariant';
                           ^^^^^^^^^^^ invariant. Required module not found

Could someone point me in the right direction? (already checked out the docs, I didn't find them helpful)

Needs docs declarations question

Most helpful comment

try this:

Add a [libs] path to your .flowconfig:

...
[libs]
flow-typed
...

Create a file [PROJECT]/flow-typed/invariant.js:

declare module 'invariant' {
  declare module.exports: any;
}

Now flow should find your invariant module :-)

EDIT:

I just realized from the other linked issue that you are not familiar with these mechanics. So this is the deal: Flow recently released breaking changes with it's syntax, so it is very crucial to know which node_module vendors with which kind of flowtype versions. If you ignore node_modules you basically are blind of vendored type-definitions.

To simulate the interfaces for flow, we need libdef files, which are very similar to how C header file would work. They don't contain any implementation details, just the declarations of the library's API.

With [libs] you tell flow specific paths to look up libdef files. from version 0.27, it will by default pick up [PROJECT]/flow-typed if it cannot find any [libs] section. In there, you define your third-party module libdefs, which then will be picked up and stubbed in the import statements you mentioned.

To make things easier, we work on the flow-typed project,... it provides a CLI tool to install specific libdef files for specific lib and flow versions.

https://github.com/flowtype/flow-typed

Hope this helps

All 21 comments

Same here.
react-addons-update. Required module not found

try this:

Add a [libs] path to your .flowconfig:

...
[libs]
flow-typed
...

Create a file [PROJECT]/flow-typed/invariant.js:

declare module 'invariant' {
  declare module.exports: any;
}

Now flow should find your invariant module :-)

EDIT:

I just realized from the other linked issue that you are not familiar with these mechanics. So this is the deal: Flow recently released breaking changes with it's syntax, so it is very crucial to know which node_module vendors with which kind of flowtype versions. If you ignore node_modules you basically are blind of vendored type-definitions.

To simulate the interfaces for flow, we need libdef files, which are very similar to how C header file would work. They don't contain any implementation details, just the declarations of the library's API.

With [libs] you tell flow specific paths to look up libdef files. from version 0.27, it will by default pick up [PROJECT]/flow-typed if it cannot find any [libs] section. In there, you define your third-party module libdefs, which then will be picked up and stubbed in the import statements you mentioned.

To make things easier, we work on the flow-typed project,... it provides a CLI tool to install specific libdef files for specific lib and flow versions.

https://github.com/flowtype/flow-typed

Hope this helps

Thanks, that's very helpful! Though ESLint is not very happy:

/Volumes/SuperData/Sites/harris-partners/harris/flow-typed/invariant.js
  4:17  error  Parsing error: Unexpected token

invariant_js_-_harris_-____sites_harris-partners_harris_

yep, eslint doesn't like that, this is since the syntax change in 0.27... if you use the old syntax (declare var exports = any or so,... you should find some examples in the flow-typed repo), eslint won't complain.... anyways don't take eslint too serious in that case!

The problem is, a passing eslint is part of my CI build process. I'll go back to the older flow-typed syntax.

declare module 'invariant' {
  declare var exports: any
}

It would be great to have better documentation around this whole process.

Quick question: if the idea of flow-typed is to have type declarations for various npm libraries that support flow, why not modify flow so that it looks for a flow-typed folder inside each package in node_modules, and uses that instead?

@ffxsam Yeah, we have an open issue where we wanna make the process of writing declaration files a little bit easier and more transparent... this will take a while tho.

Anyways, in the long run, it wouldn't make sense to track libdefs inside the library repo itself, since the flow syntax will hopefully (I reckon) be stable as soon as there is commonjs / es6 export syntax support. Actual typing information should be retrieved from the source code itself.

flow-typed really targets libraries which are not typed with flow and fills these untyped holes until more maintainers type their source.

As a sidenote, I am currently writing flow guidelines for Runtastic, which will also include a section about properly vendoring flowtype information in ES6 modules and such.

(Currently a WIP branch: https://github.com/runtastic/flow-guide/tree/initial-guidelines/guidelines)

Any updates?
I always got this error with react-addons-css-transition-group. Nothing helps, lib definition, etc. Just flow disabling for file which uses react-addons-css-transition-group.

@nkt What is your current setup to introduce the react-addons-css-transition-group libdef files? If you didn't define the module somewhere, flow needs to complain!

@ryyppy I've tried to detect reason of this behaviour and found it. I'm using css-modules and there are some settings in my flowconfig:

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

From first link in google. But now I see, this regexp matches react-addons-css-transition-group in pair with module.system=haste. I don't know why, but you should add recommended way for using flow with css-modules into flow docs.

Just in case someone runs into the same (mostly unrelated) issue I had and ended up here... If you include the following in your .flowconfig for something like _css-modules_:

[options]
module.file_ext=.css

You will also need to add the default module extensions back in, as the initial declaration wipes out those defaults.

[options]
module.file_ext=.css
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json

@nkt I think you did a small typo in your regex...

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

The . in (.css\) should actually be masked, no?

also you should probably add a $ to mark the end of the string -> (\.css\)$

@ryyppy this is the first regex from google. Now I'm using this one:

module.name_mapper='.*\.css$' -> 'CSSModule'

Exactly, so it was an RegExp issue :-)

And the full solution is?

Found a workaround by following this issue: https://github.com/facebook/flow/issues/662

Okay, since everyone is apparently completely lost here...

GOAL:

Make flow understand *.css files and map them to an exported Object or whatever type you need... also to prevent this dreaded module not found error.

STEPS:

1) In your project folder, create a file helpers/CSSModule.js with following content:

//@flow

export default {};

2) Now tell flow in your .flowconfig that you want to redirect all *.css require / imports to your newly created helpers/CSSModule.js file:

[ignore]

[include]

[libs]

[options]
module.file_ext=.css
module.file_ext=.js
module.file_ext=.jsx
module.file_ext=.json

module.name_mapper='.*\.css$' -> './helpers/CSSModule'

3) Restart your flow with flow stop && flow start

RESULT:

Now everything is set up... let's assume we have a file test.js and whatever.css in the same directory:

// whatever.css

div {
  color: blue;
}
// test.js

//@flow

import styles from './whatever.css';

styles will now be of type Object, since I mapped it to the CSSModule export instead.


Does this solve your problems, or did I already post an unrelated solution, since I already lost track of the actual question?

`> [email protected] flow /Users/lee/eventmosh/vui-boilerplate/tpltest
> flow check

src/main.js:6
6: import Vue from 'vue';
^^^^^ vue. Required module not found`

.flowconfig

[include]
./src/**

[ignore]
.*/node_modules/**

terminal:

> flow; test $? -eq 0 -o $? -eq 2

src/commands/build.js:3
  3: import documentation from 'documentation';
                               ^^^^^^^^^^^^^^^ documentation. Required module not found

Any updates on this.

I think we need a better solution than us adding files with the types spec, something clever that do not add more work and issues and allow us to focus on our platform.

Maybe some way to silence these issues or something?!

OK, I've read through this thread and @ryyppy has provided an answer for many issues that have been posted here.

To summarize: If you get a required module not found error, you should define a library definition. You can get library definitions from flow-typed, and flow-typed will even create stub definitions for you!

If you found this issue because you are having a similar issue, please read the thread for many answers to specific questions. If you are still stuck, please open a new issue with the specifics of your issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ghost picture ghost  路  3Comments

ctrlplusb picture ctrlplusb  路  3Comments

tp picture tp  路  3Comments

jamiebuilds picture jamiebuilds  路  3Comments

damncabbage picture damncabbage  路  3Comments