IntelliJ 2017.3 does not resolve imported Flow type
I have two IntelliJ modules using ES6 + Flow. One module exports some things, the other imports them. The code works in CLI babel-node, but IntelliJ underlines one of the imports and says "Cannot resolve symbol." I think it is because IntelliJ's Flow support does not recognize the ".js.flow" extension, see Flow version-0.19.0 release notes, which explains that if Flow is trying to load something.js, it will prefer something.js.flow if a file by that name exists. And yes I have the IntelliJ project setting Languages & Frameworks - Javascript - Language Version = Flow.
// @flow
// First module: index.js.flow
export type Obj1 = {|
name: string
|};
export const foo = (o: Obj1): Obj1 => {
return {
name: "The name is '" + o.name + "'"
};
};
// @flow
// Second module: driver.js
import type { Obj1 } from 'firstmodule'; // Cannot resolve symbol 'Obj1'
import { foo } from 'firstmodule';
const obj1: Obj1 = { name: "John Doe" };
const obj2: Obj1 = foo(obj1);
console.log("obj1", obj1);
console.log("obj2", obj2);
Running "flow" on the two JS files shows "No errors!"
Build and compile on the CLI:
//In firstmodule
babel index.js.flow -o index.js
//In secondmodule
babel-node driver.js
Note: IntelliJ does not complain if the import side uses star rename syntax:
import * as blah from 'firstmodule';
const obj1: blah.Obj1 = { name: "John Doe" };
//etc
Please sign in to leave a comment.
not sure I understand your setup... Is
a directory import (i.e. you have index.js.flow located in firstmodule folder)?
To me, such imports are correctly resolved (WebStorm 2017.3.1):
My setup has two modules not one. My IntelliJ module names are flowtiny1 and flowtiny2. (I was previously calling them 'firstmodule' and 'secondmodule'.) Here is the IntelliJ project structure:
flowtiny1/package.json:
{"name": "flowtiny1",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "babel index.js.flow -o index.js",
"flow": "flow"
},
"babel": {
"presets": [
"flow",
"env"
]
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-flow": "6.23.0",
"flow-bin": "0.61.0"
},
"author": "",
"license": "MIT"
}
flowtiny2/package.json:
{"name": "flowtiny2",
"version": "1.0.0",
"description": "",
"main": "driver.js",
"scripts": {
"flow": "flow",
"driver": "babel-node driver.js"
},
"babel": {
"presets": [
"flow",
"env"
]
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-flow": "6.23.0",
"flow-bin": "0.61.0",
"flowtiny1": "file:../flowtiny1"
},
"author": "",
"license": "MIT"
}
Notice flowtiny2 uses a file: dependency on flowtiny1 (local-paths syntax), which is supported by yarn.
flowtiny1/index.js.flow:
flowtiny2/driver.js:
Thank you!
(BTW I chose "IntelliJ IDEA Users" when filing this ticket but this support site changed it to "Webstorm" community. That happened with my other support ticket too.)
recreated; when importing from node_modules, IDEA looks for index.js unless the main file is specified in package.json. So, to get imports working, you need to either specify index.js.flow as main file in flowtiny1/package.json:
or specify the file name in import
Please follow https://youtrack.jetbrains.com/issue/WEB-28856 for updates
>BTW I chose "IntelliJ IDEA Users" when filing this ticket but this support site changed it to "Webstorm" community. That happened with my other support ticket too.
It's normal - the host project for Flow support is WebStorm, that's why the tickets are moved to appropriate forum/youtrack project/etc. to get them handled by WebStorm team
Thanks for the suggestions!
The first suggestion has an issue though. That package.json "main" setting makes IntelliJ's "Cannot resolve symbol" warning go away, but it also causes driver.js's import to load the source .js.flow instead of the compiled index.js and it breaks the runtime. So when I set "main":"index.js.flow" in flowtiny1/package.json, then flowtiny2 "yarn driver" (runs 'babel-node driver.js') fails:
export type Obj1 = {|^^^^^^
SyntaxError: Unexpected token export
The second suggestion to do "import from 'flowtiny1/index.js.flow'" fixes the IntelliJ warning and also works in babel-node. I will use this one.
When WEB-28856 is fixed, will I be able to go back to simply using "import from 'flowtiny1'" ? (i.e. no more need to specify /index.js.flow in the import?)
>When WEB-28856 is fixed, will I be able to go back to simply using "import from 'flowtiny1'" ? (i.e. no more need to specify /index.js.flow in the import?)
yes, sure:)
Thanks for all the help so far. I found another corner case where IntelliJ code assist does not work with Flow. If the first module does 'export * from' two levels deep, now - in the second module - IntelliJ complains "Cannot resolve symbol" on the import of non-type names (aka real exports). Adding "/index.js.flow" to the import target fixes code assist but breaks the runtime with the same "Unexpected token export" error reported earlier. Below is the new example:
flowsmall1/package.json:
{"name": "flowsmall1",
"version": "1.0.0",
"description": "",
"scripts": {
"build": "cd src && babel -d ../build *.js",
"flow": "flow"
},
"babel": {
"presets": [
"flow",
"env"
]
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-flow": "6.23.0",
"flow-bin": "0.61.0"
},
"author": "",
"license": "MIT"
}
flowsmall1/index.js:
module.exports = require('./build/exports.js');flowsmall1/index.js.flow:
flowsmall1/src/defs.js:
flowsmall1/src/exports.js:
flowsmall2/package.json:
{"name": "flowsmall2",
"version": "1.0.0",
"description": "",
"main": "driver.js",
"scripts": {
"flow": "flow",
"driver": "babel-node driver.js"
},
"babel": {
"presets": [
"flow",
"env"
]
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-preset-env": "1.6.1",
"babel-preset-flow": "6.23.0",
"flow-bin": "0.61.0",
"flowsmall1": "file:../flowsmall1"
},
"author": "",
"license": "MIT"
}
flowsmall2/driver.js
If we remove src/exports.js and have index.js.flow export * from src/defs.js, i.e. just one level of export star, then IntelliJ code assist works on import { foo }.
This is exactly the same issue as above: imports don't work, with or without src/exports.js, because the IDE doesn't see index.js.flow when importing from packaged module, it uses index.js
One more workaround (that allows using directory imports and won't likely break the runtime): instead of specifying index.js.flow as "main", add it as "jsnext:main" to flowsmall1/package.json:
The jsnext:main workaround is exactly what I need. Now IntelliJ no longer complains about unresolved symbols on imports from flow-enabled code. And the runtime is good because regular runtime ignores jsnext:main.
Thank you!