Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support require which returns any if flow lost it #51

Closed
mizchi opened this issue Nov 19, 2014 · 35 comments
Closed

Support require which returns any if flow lost it #51

mizchi opened this issue Nov 19, 2014 · 35 comments

Comments

@mizchi
Copy link

mizchi commented Nov 19, 2014

I want to ignore Required module not found and load it as any.
Type checking to extenal libraries are not serious problem.

I tried this

declare require: (s: string) => any;

but it overrides all require and lost other info.

@mizchi mizchi changed the title Support require whitch return any if it lost dependencies Support require whitch returns any if flow lost it Nov 19, 2014
@mizchi mizchi changed the title Support require whitch returns any if flow lost it Support require which returns any if flow lost it Nov 19, 2014
@tcoopman
Copy link
Contributor

I believe this also could be helpful for loading images, css, json with webpack.

Webpack lets you do: var image = require('image.jpg'); and obviously flow complains about this. It would be nice to be able to set it to any or say that flow can ignore this.

@mizchi
Copy link
Author

mizchi commented Nov 30, 2014

Or I though I want to do if left value of right require is like var somelib: any = require('foo') then ignore right if it can.

tcoopman added a commit to tcoopman/boilerplate-webpack-react that referenced this issue Dec 13, 2014
@iammerrick
Copy link

Yes this would be great for exactly what @tcoopman said.

@iammerrick
Copy link

@tcoopman Can this be "resolved" with an ignore of all files ending in css or a particular extension?

@iammerrick
Copy link

@avikchaudhuri See above comment :-)

@gaearon
Copy link
Contributor

gaearon commented Jan 23, 2015

+1. This is currently my blocker for Flow.

@tcoopman
Copy link
Contributor

Mine too. Maybe some way to tell flow that a type is what it is and that it should not check it any further?

var image: !string = require('image.jpg');
var css: !any = require('main.css');

Comparable with maybe types, but instead of ? you add !. This doesn't let you do require('./Activity.less'); though, so maybe the suggestion of @gaearon is still necessary unless you could do: reauire('./Activity.less'): !any

@syranide
Copy link

+1

4 similar comments
@thealjey
Copy link

thealjey commented Mar 7, 2015

+1

@williamfligor
Copy link

+1

@gcazaciuc
Copy link

+1

@nktpro
Copy link

nktpro commented Mar 24, 2015

+1

@syranide
Copy link

Perhaps the proper approach is to actually have an intermediate step where autogenerated files are output instead, so that flow can parse them. I'd imagine there are a bunch of benefits to it not only being part of the final bundling process.

@tcoopman
Copy link
Contributor

@syranide not sure what you mean. You mean that flow should parse the css or url?

@syranide
Copy link

@tcoopman Rather than webpack (etc) generating js-files for css-files/etc only at the final bundle-stage, being able to output them to disk could make sense, then flow would have access to all the js-files it needs, no workarounds necessary. This would be useful for making many other transforms compatible with flow as well.

@tcoopman
Copy link
Contributor

@syranide ok I see. That would be nice but it also seems that would need more support from the build tools?
Wouldn't you then also need to transform your original files or create a mapping file so flow knows where to find them?

So

var f = require(file.jpg)
Outputs file.jpg minimised and hashed filename + a is file that has the hashed filename.

After the translation it would be var f = 'file.hash.jpg' and flow could type check that.

Again seems nice but in the meantime a solution where you can tell flow that a variable is of a type without type checking it would be a good start.

@syranide
Copy link

@tcoopman It wouldn't necessarily need more support from the build tools, but some of the steps would have to be available separately (either by the bundler or by an entirely separate transform tool, which seems preferable).

Wouldn't you then also need to transform your original files or create a mapping file so flow knows where to find them?

require('app.css') would generate app.css.js according to some user specified css transform (which it already does, it just does so internally), so the initial require would still work as-is. If you had some non-standard resolution of requires (say @providesModule) then it could also be applied in this step, flattening the files and rewriting the requires.

A nice side-effect is that this would also be compatible with any bundler (or no bundler if running node on the server), so you're less committed to any one bundler and can more easily switch if the need arises.

@tcoopman
Copy link
Contributor

@syranide that looks like it could work indeed. I've asked @sokra on gitter to give his opinion about this.

@sokra
Copy link

sokra commented Mar 25, 2015

require('app.css') would generate app.css.js

Workaround and too error prone.


We could implement a webpack output mode, which outputs every module as separate js file and generate node.js requires. Basically compiling to a node.js app containing multiple files.


Or we could generate a bundle that can be parsed by flow. SourceMaps could be used to map errors back to the original sources...

@samwgoldman
Copy link
Member

Each example given in this issue deals with requiring non-JS files, which I believe can now be handled using the module.name_mapper config with a declaration file. See #345, #382, and the commit message for the fix, which goes into a bit more usage detail.

Does anyone have a use case that isn't addressed with module.name_mapper?

@frederickfogerty
Copy link

@samwgoldman do you have an example of how it would work for css files?

I guess the issue is that we don't have a type definition for a css file, I guess it's more blocked on some webpack config/transform than on flow

jeffmo added a commit to jeffmo/flow that referenced this issue Jul 31, 2015
Add type annotations for ArrayPatterns and ObjectPatterns.
@matthewoates
Copy link

+1

@jeffutter
Copy link
Contributor

I imagine this would work by including something like:

module.name_mapper= '.*\.s*css$' -> './CSSStub'

in your config and then declaring a module like this:

declare module CSSStub { }

But I still get errors like this:
admin.js:8:1,41: sweetalert/dev/sweetalert.scss Required module not found

I'm probably overlooking something simple, any advice?

@samwgoldman
Copy link
Member

I recently saw someone post a complete example in a gist. Does this help?

@frederickfogerty
Copy link

@samwgoldman I will give that a go, seems like it should work.

@tcoopman
Copy link
Contributor

@samwgoldman maybe something for the documentation?

@jeffutter
Copy link
Contributor

@samwgoldman Awesome. Thanks for that article it works. Any idea why declaring my own empty module wouldn't work though? Even with the same regex, it doesn't seem to find my module declaration. Personally I would rather have an extra module declaration rather than add another npm dep.

@samwgoldman
Copy link
Member

@jeffutter Could you provide a repo that has the minimal code+config to reproduce what you're seeing? What you're describing should work, so a repro would help me figure out what's going on.

@cesarandreu
Copy link
Contributor

@samwgoldman I avoided adding webpack and setting up its config file, but the following code is exactly what you'd be using with Webpack and css modules.

I'll also note that the example you linked above is working great. I'd vote +1 for adding it to the docs, this was one of the remaining errors I was getting in one of my repos after moving the code to be more flow-friendly.

Terminal

~/D/flow-css-modules ❯❯❯ ../flow/bin/flow .

src/Foo.js:3:10,29: ./Foo.css
Required module not found

Found 1 error

package.json

{
  "name": "flow-css-modules",
  "version": "1.0.0",
  "main": "src/Foo.js",
  "dependencies": {
    "react": "^0.13.3"
  }
}

.flowconfig

[include]
.*/src/.*

[libs]
./interfaces/CSSModule.js

[options]
module.name_mapper='.*\(.css\)' -> 'CSSModule'
module.system=node
strip_root=true

src/Foo.js

/* @flow */
import cn from './Foo.css'
import type { ReactElement } from 'react'
import React, { Component } from 'react'

export default class Foo extends Component {
  render (): ReactElement {
    return (
      <div className={cn.Foo}>
        Foo
      </div>
    )
  }
}

src/Foo.css

.Foo {
  height: 100px;
  width: 100px;
}

interfaces/CSSModule.js

declare module CSSModule {
  declare var exports: { [key: string]: string };
}

declare module 'CSSModule' {
  declare var exports: { [key: string]: string };
}

I tried both of those variations and neither works. However if I change it so it has the same string, it works. For example:

declare module './Foo.css' {
  declare var exports: { [key: string]: string };
}

@briandipalma
Copy link

I'm seeing this error,

app/main.js:7
  7: import "./main-style.css";
            ^^^^^^^^^^^^^^^^^^ ./main-style.css. Required module not found

I guess that means the replacement didn't occur, so there is an issue with the RegExp (module.name_mapper='^.*.css' -> 'CSSModule')?

@mkatrenik
Copy link

@briandipalma your regex works for me if i set module.system=haste

@briandipalma
Copy link

@mkatrenik
I eventually went for the empty/object trick from one of the linked gists https://github.com/briandipalma/wp-r-template/blob/master/.flowconfig#L12 it works fine.

@eudisd
Copy link

eudisd commented Jan 12, 2016

+1

@samwgoldman
Copy link
Member

Sorry for the delay here. @cesarandreu thank you for the very clear repro case. I figured out what is going on here, and it seems like a simple oversight.

In an effort to make the issues a bit higher signal, I'm going to close this and replace it with #1322, which is more to the point with the exact issue.

Thanks everyone!

@faceyspacey
Copy link

but what about when you import files without the extension?

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

No branches or pull requests