-
-
Notifications
You must be signed in to change notification settings - Fork 26.9k
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
Add flow typechecking as a webpack plugin #1152
Conversation
Neat! Going to look later this week. Want to make a GIF 😄 ? |
@gaearon Not done yet, will do a gif when I'm completely happy about it! |
Btw, for now, the code is pretty awful callback hell-spaghetti, I have to admit I got used to promises, almost forgot about working like this! |
We depend on Node >= 4 so you should be able to use Promises if you want to. |
@gaearon Issue is, webpack and vanilla Node API doesn't really expose Promises. I usually use some form of promisifier to handle Node API... I don't want to add more deps than useful. |
Okay, I checked, there are arrow functions elsewhere in this codebase, I'm going to need that as well! |
@gaearon It's way better now! I'm more satisfied with it... But I want to see what your review will show... Maybe one problem we may have here is that the flow check is global and not per-file. I can work on that maybe a bit later but I see one issue in not having the global output, we'd lose warnings in test files so I have to give it a few more thoughts before doing that. Thanks and good luck for the review! |
One thing to keep in mind is the scenario where changing file A adds or removes an error from file B. Does this work now? |
@gaearon As long as A is covered by flow, typechecking project-wide will be recomputed, so we'll see issues being propagated to B if this is the case. |
.then(newOutput => { | ||
flowOutput = newOutput; | ||
// Output a warning if flow failed | ||
if (flowOutput.indexOf('No errors!') < 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does Flow have IDE-friendly mode outputting JSON or something else parseable so that you don't need to search strings? How does Nuclide Flow integration work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can output JSON with flow status --json
. Drawback is, I have to redo the output that is already nice and colored. However, I agree comparing with "No errors!" is bad. Maybe I should use the standard error code, which represents a better feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, makes sense!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concerning Nuclide, they use a non documented package that handles the process lifecycle that is, by the way, pretty cool. However, as said before, it is not documented and may be pretty unstable, the advantage here is that we only depend on flow-bin
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea, definitely want to go with a lighter way to do it for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Return code-based solution works super well!
@gaearon Well, I think it's quite complete now, I heavily tested it and covered many edge cases... I'll see how we can add this to the e2e test process... and after that, I think we're good for a final review! |
Well the addition to the e2e tests pass locally, just waiting for the CI! |
a41b5b6
to
8b79f87
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fantastic! Thanks for building this!
Small note: an empty .flowconfig
file should be sufficient! I think the README
is just a little out of date. Nowadays, if you run create-react-app
and just do
flow init && flow check
you should get 0 errors :)
'<PROJECT_ROOT>/node_modules/fbjs/.*', | ||
'', | ||
'[libs]', | ||
'./flow-typed' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't be necessary - Flow automatically treats the <PROJECT_ROOT>/flow-typed
directory as a lib directory :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ignored that, and this is pretty cool, that'll go as well!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Arr, I still see issues as of flow 0.36.0, here's my output on a jest test:
src/App.test.js:6
6: it('renders without crashing', () => {
^^ identifier `it`. Could not resolve name
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, lemme retry 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nah, sorry, I'll have to let that for now...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, modifying that file doesn't seem to trigger a rebuild.
Likely because it's not part of webpack flow (it's a test after all). So it looks like this integration is a bit limited by not working with test files. Not sure if it's easily fixable or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, yea, unfortunately, for now, we don't have any way to trigger on App.test.js
alone. You have to add it toApp.js
. However, once you change App.js
, a rebuild will be retriggered including the test. In this case, it's random, sometimes flow-typed is correctly seen, sometimes not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gaearon By the way, linting in test files will not run as well... I think we need to find a way to run eslint+flow during the test watching... I don't exactly know just yet how to do that but I can always take a look...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rricard I agree, it would be nice to figure out a way to do this. As a separate action item :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@gabelevi don't ask me why, it now works every time with an empty .flowconfig
new FlowTypecheckPlugin({ | ||
flowconfig: [ | ||
'[ignore]', | ||
'<PROJECT_ROOT>/node_modules/fbjs/.*', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After facebook/fbjs#182 (which was in fbjs 0.8.5) this shouldn't be necessary! And from testing out create-react-app right now, it seems to install 0.8.6 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is good news, I'll get that out.
|
||
```js | ||
node_modules/fbjs/lib/Deferred.js.flow:60 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah this might be a little out of date
@gabelevi Thank you for checking in! |
😁 😁 😁 Super excited for this! 😁 😁 😁 |
d5011d9
to
80bc2cb
Compare
6fe3848
to
46829e3
Compare
Thoughts on extracting all of these awesome webpack plugins into separate packages? I know I can just depend on EDIT: Not related to this PR at all, of course... Can open a separate issue if you guys are interested |
For now we don't want to add more packages because people will have expectations of a stable release cycle. Instead it is likely we'll need to iterate on them quite a bit before they settle down. We're also not quite ready to make them "proper" because people will start asking for configuration options, come with issues specific to those packages etc. If/when this gets really stable I'd be up for extracting it from |
This is pretty neat! I see that this PR is in good hands! |
@rricard we decided to chop the This PR should be good to go barring shutting down the flow server when the process exits (which I'm not even sure if that's a huge deal). |
@Timer good call, |
That, and until all of definitelytyped definitions make their way in (imo). |
What is missing here? |
I'm fine with keeping the server alive. |
Only thing missing is disabling this feature for Windows users. |
I'm not sure if that's a good idea. Different projects may use different versions of flow, so the global version may not be correct for the project.
The server might not have been started by this, and even if it was, flow might still be used by other processes, so I don't think it should be shut down. |
Is this feature slow for Windows users or Flow itself?
|
@gaearon flow itself is slow on windows, but I had my VSCode's "Run flow while editing" option ticked, which made my system virtually unusable. I don't want to disable it because the "feature" is slow, just because it can freeze up your system for periods of time if you have certain options turned on in your editor. I'll have to do some more testing to see what the best path is going forward, however, I'm windows-machine-less right now. |
) { | ||
return; | ||
} | ||
const contents = loaderContext.fs.readFileSync(module.resource, 'utf8'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this not slowing down the build? Seems suspicious to read every file if Webpack also does it by itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
loaderContext.fs.readFileSync is webpack's memory file system, not the real filesystem.
We're basically doing cache[key].
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aaaah.
After some discussion we're pushing this back to 0.11. In particular, it doesn't seem right to wait for Flow to declare the build to be complete. In the UI, we will probably show Flow check and Webpack compilation as two separate "panes" that don't wait for each other. |
any updates? |
@@ -16,6 +16,7 @@ const HtmlWebpackPlugin = require('html-webpack-plugin'); | |||
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin'); | |||
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin'); | |||
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin'); | |||
var FlowTypecheckPlugin = require('react-dev-utils/FlowTypecheckPlugin'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the other imports uses const
, so this not also? :)
Really sorry about this—it has gotten stale and I think we won't be pursuing this further ourselves. The Flow team is not focused on supported integrations right now so we'd always have to be playing catch-up. That said if you're interested in reviving this on top of an API used by Nuclide, and solve the wait-before-build problem then we can revisit this. Thanks a lot for prototyping it! |
This will only run if a @flow annotation is seen in an user's file:
Followup goals:
.gitignore
during the first runFollowup of a discussion in #72