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

 

 

 

 

9 comments
Comment actions Permalink

not sure I understand your setup... Is

import type {Obj1} from './firstmodule';

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):

0
Comment actions Permalink

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:

// @flow

export type Obj1 = {|
name: string
|};

export const foo = (o: Obj1): Obj1 => {
return {
name: "The name is '" + o.name + "'"
};
};

 

flowtiny2/driver.js:

// @flow

import type { Obj1 } from 'flowtiny1'; // Cannot resolve symbol 'Obj1'
import { foo } from 'flowtiny1';

const obj1: Obj1 = { name: "John Doe" };
const obj2: Obj1 = foo(obj1);

console.log("obj1", obj1);
console.log("obj2", obj2);

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.)

0
Comment actions Permalink

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:

"main"        : "index.js.flow",

or specify the file name in import

import type {Obj1} from 'flowtiny1/index.js.flow';

Please follow https://youtrack.jetbrains.com/issue/WEB-28856 for updates

0
Comment actions Permalink

>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

0
Comment actions Permalink

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?)

 

0
Comment actions Permalink

>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:)

0
Comment actions Permalink

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:

// @flow
export * from './src/exports.js';

flowsmall1/src/defs.js:

// @flow

export type Obj1 = {|
name: string
|};

export const foo = (o: Obj1): Obj1 => {
return {
name: "The name is '" + o.name + "'"
};
};

flowsmall1/src/exports.js:

// @flow
export * from './defs.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

// @flow
import type { Obj1 } from 'flowsmall1/index.js.flow'; //IntelliJ code assist works, and 'babel-node driver.js' runtime works too.
import { foo } from 'flowsmall1'; //Code assist broken, runtime is ok. "Cannot resolve symbol 'foo'". *THIS IS THE NEW ISSUE.*
//import { foo } from 'flowsmall1/index.js.flow'; //Code assist works, runtime breaks. "Unexpected token export" in index.js.flow.

const obj1: Obj1 = { name: "John Doe" };
const obj2: Obj1 = foo(obj1);

console.log("obj1", obj1);
console.log("obj2", obj2);

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 }.

 

0
Comment actions Permalink

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:

"jsnext:main": "index.js.flow"



0
Comment actions Permalink

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!

0

Please sign in to leave a comment.