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

Peek/Go To Definition & Click to Open do not work with Webpack alias #16320

Closed
damonbauer opened this issue Dec 1, 2016 · 62 comments
Closed
Assignees
Labels
feature-request Request for new features or functionality typescript Typescript support issues

Comments

@damonbauer
Copy link

damonbauer commented Dec 1, 2016

  • VSCode Version: 1.8.0-insider
  • OS Version: OSX El Capitan 10.11.6

Using normal, path based imports, Peek/Go To Definition and CMD+Click to open file from import work wonderfully. When using a Webpack alias, Peek/Go To no longer work. It kind of "fails silently" in that nothing appears (not even an error message).

Steps to Reproduce:

  1. Add an alias to a webpack config file
  2. Import a file using an ES6 import with the path to the file that includes the Webpack alias

Desired Behavior:

  1. Using a Webpack alias inside an ES6 import, Peek/Go To Definition display in the same manner as when using a full path inside an import.
  2. CMD+Click to Open File from import statement works with both full paths and webpack aliases

I've created a reduced repo that demonstrates the behavior: https://github.com/damonbauer/webpack-alias-demo/

I'm setting an alias in the webpack config to map the word app to the path of /src. Then in a file, I'm importing another with ES6 imports.

Edit: I'm also using the PathIntellisense extension with custom mappings so I can get path autocompletion when using an alias in an import. Perhaps there could be something helpful in that repo?

@chrmarti chrmarti added feature-request Request for new features or functionality typescript Typescript support issues labels Dec 1, 2016
@wanecek
Copy link

wanecek commented Jun 12, 2017

EDIT: I only seem to be able to get path autocompletion, not "peek" or "Go to definition" with the feature described below. I've recently switched computers (from a PC to a Mac), and could have sworn it worked on the PC. Will investigate and update once I know more.


It may be of interest to note that the latest release of WebStorm brings this feature. I mention this not to suggest making the switch, but rather to further underline that this could be a very useful feature :)

I'd like to clarify what @damonbauer states above: the feature can be achieved manually with the Path Intellisense extension, by defining path-intellisense.mappings in your vscode settings. The example they provide in the documentation is as follows:

{
    "path-intellisense.mappings": {
        "/": "${workspaceRoot}",
        "lib": "${workspaceRoot}/lib",
        "global": "/Users/dummy/globalLibs"
    },
}

@hronro
Copy link

hronro commented Jun 13, 2017

+1 Very useful to me.

@developering
Copy link

@wanecek Were you able to get Peek Definition and CMD+Click working with the path-intellisense.mappings? Adding those mappings did allow for suggestions as I'm typing an import statement and using a webpack alias, but didn't seem to change the functionality at all with Peek Definition or CMD+Click. If you were able to get that working somehow, I'd love to see more details on your setup.

@abhilash27n
Copy link

+1 would be super awesome to have this. We just moved all the import paths in our project to use webpack aliases and I miss the command clicking. I can only get the autocomplete to work with path-intellisense.mappings.

@AndrewRayCode
Copy link

AndrewRayCode commented Aug 7, 2017

You can accomplish this using the "paths" option. Full writeup here. TL;DR add

{
  "compilerOptions": {
    // This must be specified if "paths" is set
    "baseUrl": ".",
    // Relative to "baseUrl"
    "paths": {
      "*": [
        "*",
        "mypath/*"
      ]
    }
  }
}

to your jsconfig.json or tsconfig.json in your project's root.

@chocopowwwa
Copy link

Link to official docs https://code.visualstudio.com/docs/languages/jsconfig

@wesleymostien
Copy link

wesleymostien commented Oct 13, 2017

can't get this to work :

"path-intellisense.mappings": {
"/": "${workspaceRoot}",
"components": "${workspaceRoot}/src/components"
},

OR / AND

{
"compilerOptions": {
"target": "es2015",
"lib": ["dom", "es2015", "es2017"],
"module": "commonjs",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true
"baseUrl": ".",
"paths": {
"components/": ["", "src/components/"]
}
},
"exclude": ["./node_modules/**/
"]
}

@wanecek
Copy link

wanecek commented Oct 13, 2017

Hey @wesleymostien, I ended up solving it by putting a jsconfig.json in the root of my project, with the following content:

{
  // This file is required for VSCode to understand webpack aliases
  "compilerOptions": {
    // This must be specified if "paths" is set
    "baseUrl": ".",
    // Relative to "baseUrl"
    "paths": {
      "@/*": ["./src/*"],
    }
  }
}

which works fine for me. I think you might be missing the asterix (*) in your example :)

@wesleymostien
Copy link

@wanecek doesn't seem to matter

now I have this :

"baseUrl": "./src",
"paths": {
  "components": ["./components/*"]
}

so, I can import absolute mapping with 'components/....' . That part works!

But the problem is, Intellisense doesn't show me *.vue files, can this be fixed?

@wanecek
Copy link

wanecek commented Oct 13, 2017

so, I can import absolute mapping with 'components/....' . That part works!

Not sure I understand this... Did you get the Intellisense features (e.g. the type-hint tooltips on hover) working or not?

If not, you might want to give this a try as well.

"paths": {
  "components/*": ["./components/*"]
}

For the path-intellisense, I have the path-intellisense extension, and have extended it with this in the workspace settings:

"path-intellisense.mappings": {
  "@": "${workspaceRoot}/src"
},

@wesleymostien
Copy link

wesleymostien commented Oct 13, 2017 via email

@wanecek
Copy link

wanecek commented Oct 13, 2017

Yeah, I've got this working, not sure what's making it work though.
Try installing the veturextension if you haven't already.

However, I think this issue is getting out of topic. Send me an email instead (see my GH profile) and I'll try to help you :)

@plxel
Copy link

plxel commented Oct 31, 2017

tried all solutions provided here, no one is correctly working :( ctrl+click still no reaction

@xahon
Copy link

xahon commented Nov 5, 2017

I've found solution
I had import SomeComponent from '@/someComponent
Changing it into import SomeComponent from '@/someComponent/index made peek/goto definition working

I have jsconfig.json in my project root with these settings

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "~/*": ["./src/*"],
      "@/*": ["./src/components/*"]
    }
}

@xahon
Copy link

xahon commented Nov 5, 2017

in general it doesn't matter if there's index in that path. It's important to place another path level after @/something/...(here)...

If you have that file hierarchy Folder -> ComponentFolder -> index.js you can write import component from '@/Folder/ComponentFolder' and it will work if you paths is "@/*": ["./src/"] in this case

@leandrocrs
Copy link

Do not forget to make sure that in your visual studio code settings "javascript.validate.enable" is true.
In my case I disabled it it, thats why I didn't got intellisense.
Now everything is ok.

Sorry my improvised English

@nickngqs
Copy link

Somehow I still can't get this to work.

I've got a jsconfig.json

My webpak resolve config

let config = {
	...,
	resolve: {
		modules: [
			path.resolve(__dirname, './src/js'),
			'node_modules'
		]
	},
	...
}

My jsconfig.json

{
	"compilerOptions": {
		"baseUrl": "./",
		"paths": {
			"modules/*": ["./src/modules/*"]
		}
	}
}

@guilima
Copy link

guilima commented Jan 18, 2018

@nickngqs , don't know how it works but try this on jsconfig:
"modules/*": ["*", "./src/modules/*"]

I was having trouble and somehow the extra wildcard helped me. Maybe someone could add something about it.

@leandrocrs
Copy link

My .jsconfig looks like:

{
    "module": "es6",
    "compilerOptions": {
        "module": "es6",
        "target": "es5",
        "allowSyntheticDefaultImports": true,
        "baseUrl": "./source/",
        "paths": {
            "*": ["./assets/js/*"],
            "vendor/*": ["./vendors/js/*"]
        }
    },
    "exclude": [
        "node_modules"
    ],
    "compileOnSave": false
}

And works like a charm

@AO17
Copy link

AO17 commented Feb 6, 2018

I'm having the same problem, but I do not get any suggestions at all, as soon as I'm in the alias directory...

For Example if I am using:
import Button from 'third/Button'
the "Button" part I would have to type in manually, there is no suggestion.

I have followed this guide, but no success.

My jsconfig.json:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "paths": {
      "first": ["./src/first"],
      "second": ["./src/second"],
      "third": ["./src/style/css/home"],
    }
  },
  "exclude": [
    ".gitlab",
    ".storybook",
    ".vscode",
    "node_modules",
    "public"
  ]
}

Any ideas?

@bosung90
Copy link

If your project structure looks like

src
| Component
| | comp2.js
| hello.js

and you import your file like this

import hello from 'hello'
import comp2 from 'Component/comp2'

then your jsconfig.json should look like

{ "compilerOptions": { "baseUrl": ".", "paths": { "*": ["./src/*"] } } }

@aphillipo
Copy link

aphillipo commented Apr 12, 2018

Hello all,

 “moduleResolution”: “node”,

Seems to be necessary if you have your exports from your alias in an index.js file. Ta!

@AO17
Copy link

AO17 commented Apr 13, 2018

Both did not work for me. Here is a more detailed setup, can anyone point me to the right direction?

@tomaskikutis
Copy link

See #30290(Go to definition for .jsx does not work). I was trying all the snippets from this thread with no luck until I found that it worked on .js files, but not .jsx, where I did all the testing.

@ronjouch
Copy link

ronjouch commented Aug 14, 2018

I built a minimal broken test project (zip, 3kB) for my use case. Can anyone give a look at it? Ping @mjbvz

Extract the zip and see README.md: like other people, path autocompletion works, but not "peek" or "Go to definition".

  • npm install && npm run build && node dist/index.js
    → Install & build both succeed, indicating Webpack is happy. Run logs [1, 2, 3].
  • Now, run code /path/to/project and open src/index.js
    On line 5, try to F12 on getLinks
    No definition found for 'getLinks' 😢

Am I still doing something wrong in my jsconfig.json, or is this a bug? (the multiple levels of exports, maybe?)

@egucciar
Copy link

Is there no solution for this as of this time? I'm going crazy working in a new Vue project and i dont think i can handle it.

@twavis
Copy link

twavis commented Jan 15, 2019

For those that may still be having trouble with this issue, the location of the jsconfig file is important! I was trying to put it in the root of the repo and no combination of path/baseUrl would allow the Peek/Go To Definition to work. It was after I moved it into src that I could get it to work (The realization came from reading this issue microsoft/vscode-docs#119).

@jerrygreen
Copy link

this helped me a lot (jsconfig.json)

@suyi91
Copy link

suyi91 commented Apr 2, 2019

Setting "paths" in jsconfig.json can solve webpack alias problems.
But meanwhile, "Peek/Go To Definition" will not work for packages in node_modules with their own typing definition files(e.g. axios).

@beizhedenglong
Copy link

@suyi91 try remove target config, that should work

Setting "paths" in jsconfig.json can solve webpack alias problems.
But meanwhile, "Peek/Go To Definition" will not work for packages in node_modules with their own typing definition files(e.g. axios).

@zquancai
Copy link

zquancai commented Aug 6, 2019

this helped me a lot (jsconfig.json)

Me too, but it didn't solve my problems.

@juliogc
Copy link

juliogc commented Sep 8, 2019

I'm still into trouble with this 😢
I have already tried all workarounds on Github/Stackoverflow/Internet... and nothing solves the "Go to definition" issue.

The webpack build process and intellisense completion feature goes well, btw.

Screenshot from 2019-09-08 20-21-53

My configs:
webpack.config.js

module.exports = {
    ...
    resolve: {
        alias: {
            "~": path.resolve(__dirname, 'src'),
            Styles: path.resolve(__dirname, 'src', 'assets', 'styles'),
            Images: path.resolve(__dirname, 'src', 'assets', 'images'),
        }
    },
    ...
};

jsconfig.json

{
    "exclude": ["node_modules", "dist"],
    "compilerOptions": {
        "module": "es6",
        "allowSyntheticDefaultImports": false,
        "baseUrl": "./",
        "paths": {
            "~/*": ["src/*"],
            "Styles/*": ["src/assets/styles/*"],
            "Images/*": ["src/assets/images/*"]
        }
    }
}

@dnutels
Copy link

dnutels commented Oct 10, 2019

After dealing with this for a little bit:

{
    "compilerOptions": {
        "target": "esnext",
        "jsx": "preserve",
        "baseUrl": ".",
        "paths": {
            "@/*": ["src/*"]
        }
    }
}

resolve both Ctrl+Click, Peek, GoToDef and path completion for me. Specifically adding an undocumented "jsx": "preserve". Don't forget to restart VSC, as it had an impact in some cases...

What doesn't work is the import App from '@/modules' where the App is a module in src/modules/index.jsx.

@claudio-moya
Copy link

After dealing with this for a little bit:

{
    "compilerOptions": {
        "target": "esnext",
        "jsx": "preserve",
        "baseUrl": ".",
        "paths": {
            "@/*": ["src/*"]
        }
    }
}

resolve both Ctrl+Click, Peek, GoToDef and path completion for me. Specifically adding an undocumented "jsx": "preserve". Don't forget to restart VSC, as it had an impact in some cases...

What doesn't work is the import App from '@/modules' where the App is a module in src/modules/index.jsx.

you saved my day man! they key was the undocumented "jsx": "preserve", option.

It's working for me using React components and .JSX files:

  • Path completion / path-intellisense
  • Ctrl+Click and go to the JSX file
  • Right Click + Go to Definition
  • Right Click + Peek Definition
  • Right Click + Go to Type Definition

Here is my config file:

{
  "compilerOptions": {
    "jsx": "preserve",
    "baseUrl": ".",
    "paths": {
      "*": [
        "*",
        "src/*"
      ]
    }
  },
  "exclude": ["node_modules"]
}

@rw3iss
Copy link

rw3iss commented Nov 19, 2019

Finally got this working with React jsx, with go to definition and all. You need jsconfig.json, looking like this (note you need the "jsx": "react" property, and to specify the trailing 'index.jsx' in the aliases, if using the implicit class-as-folder-name paradigm):

{ 
    "compilerOptions": {
        "baseUrl": "./src",
        "paths": { 
            "shared/*":       ["./components/shared/*/index.jsx"],
            "components/*":   ["./components/*/index.jsx"],
            "stores/*":       ["./lib/stores/*"],
            "services/*":     ["./lib/services/*"],
            "utils/*":        ["./lib/utils/*"]
        },
        "module": "commonjs",
        "target": "es6",
        "moduleResolution": "classic",
        "jsx": "react"
    }
}

Then imports like this all work:

import UserApi from 'services/api/UserApi';
import EditArea from 'components/views/Blog/EditArea';
import EditableLabel from 'shared/EditableLabel';

Hope it helps!

@juliogc
Copy link

juliogc commented Dec 6, 2019

Hey, @claudio-moya / @rw3iss! I really appreciate your help!
I made it work with a simpler version than that was suggested, but it is working perfectly. The "jsx": "react" do the trick!

{
    "exclude": ["node_modules", "dist"],
    "compilerOptions": {
        "jsx": "react",
        "baseUrl": "./src",
        "paths": {
            "~/*": ["./*"]
        }
    }
}

Here is a working example view from a simple CRA that I tested right now!

Peek 2019-12-06 14-59

@techsin
Copy link

techsin commented Dec 9, 2019

If your project structure looks like

src
| Component
| | comp2.js
| hello.js

and you import your file like this

import hello from 'hello'
import comp2 from 'Component/comp2'

then your jsconfig.json should look like

{ "compilerOptions": { "baseUrl": ".", "paths": { "*": ["./src/*"] } } }

I was defining all properties OUTSIDE of compilerOptions and therefore it wasn't working. The dumbest thing I've wasted time on.

@Yegorich555
Copy link

Yegorich555 commented Dec 12, 2019

Peek to definition works fine just only with js-ts-tsx-jsx files.
You can recheck correct configuration here: https://github.com/Yegorich555/WebpackMustHave/tree/vscode-peek-definition
But it doesn't work at all with images, fonts etc.

I configured path-intellisense.mappings in .vscode/settings.json and it affects on path_autocomplete but peek-definition doesn't work at the same time. What is solution can be for this???

@troglotit
Copy link

@Yegorich555 I don't think TS can or should complete images, fonts, etc. All of them have a behaviour defined only in webpack loaders' sense (or other bundler). They don't make sense as ES or TS modules at all. So TS can't and shouldn't hook into bundlers's compilation process

@Yegorich555
Copy link

@troglotit I see your point and it makes sense. But I would like to see organic and cohesive system for frontend-development. Vue is a good extension for developing *.vue on VSCode but it's related to vue and unfortunately webpack doesn't provide anything similar for native js and ts...

@techsin
Copy link

techsin commented Dec 12, 2019

we should have an extension that can automatically tap into webpack config bridge vscode gap

@Yegorich555
Copy link

Yes. It makes sense.

@troglotit
Copy link

troglotit commented Dec 13, 2019

Vue uses Vetur which itself is an LSP server. Maybe more sound architectural solution would be "Webpack LSP server" which uses tsserver as a library for js/ts, and with additional servers for other kinds of artifacts.

@enuchi
Copy link

enuchi commented Dec 13, 2019

Finally got this working with React jsx, with go to definition and all. You need jsconfig.json, looking like this (note you need the "jsx": "react" property, and to specify the trailing 'index.jsx' in the aliases, if using the implicit class-as-folder-name paradigm):

{ 
    "compilerOptions": {
        "baseUrl": "./src",
        "paths": { 
            "shared/*":       ["./components/shared/*/index.jsx"],
            "components/*":   ["./components/*/index.jsx"],
            "stores/*":       ["./lib/stores/*"],
            "services/*":     ["./lib/services/*"],
            "utils/*":        ["./lib/utils/*"]
        },
        "module": "commonjs",
        "target": "es6",
        "moduleResolution": "classic",
        "jsx": "react"
    }
}

Then imports like this all work:

import UserApi from 'services/api/UserApi';
import EditArea from 'components/views/Blog/EditArea';
import EditableLabel from 'shared/EditableLabel';

Hope it helps!

Thanks for this @rw3iss, super helpful. Also had trouble with baseUrl as ./src and getting go-to-definition to work. Got this to work without defining all subpaths after src using the following, in case it helps anyone:

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "classic",
    "jsx": "preserve",
    "baseUrl": "./src",
    "paths": {
      "*": ["./*/index"]
    }
  },
}

@rw3iss
Copy link

rw3iss commented Dec 13, 2019

"paths": {
  "*": ["./*/index"]
}

Cool, nice way to avoid all the aliases! Thanks for sharing.

@pankajsoni91
Copy link

Yep, I got it working using this jsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "jsx": "preserve",
        "paths": {
            "apps/*": [
                "./scripts/apps/*",
            ],
            "core/*": [
                "./scripts/core/*",
            ],
        },
        "baseUrl": ".",
    },
    "exclude": [
        "node_modules",
        "bower_components",
        "po",
    ]
}

Here's an example of a working import

import {Modal} from 'core/ui/components/Modal/Modal';

If you're interested, you can try it out here: https://github.com/superdesk/superdesk-client-core/tree/9072076

See /scripts/apps/authoring/authoring/previewModal.jsx or any other *.jsx file

Did Command Click work for you?

@wachidmudi
Copy link

Hey @wesleymostien, I ended up solving it by putting a jsconfig.json in the root of my project, with the following content:

{
  // This file is required for VSCode to understand webpack aliases
  "compilerOptions": {
    // This must be specified if "paths" is set
    "baseUrl": ".",
    // Relative to "baseUrl"
    "paths": {
      "@/*": ["./src/*"],
    }
  }
}

which works fine for me. I think you might be missing the asterix (*) in your example :)

Totally forgot about (*) asterisk thing, thanks

@ShamansCoding
Copy link

Hey, @claudio-moya / @rw3iss! I really appreciate your help!
I made it work with a simpler version than that was suggested, but it is working perfectly. The "jsx": "react" do the trick!

{
    "exclude": ["node_modules", "dist"],
    "compilerOptions": {
        "jsx": "react",
        "baseUrl": "./src",
        "paths": {
            "~/*": ["./*"]
        }
    }
}

Here is a working example view from a simple CRA that I tested right now!

Peek 2019-12-06 14-59

Thanks! It is working with CRA as expected!

Sad to see this issue to be still open for so many years. I hope it will be fixed someday soon.

@igor-opticks
Copy link

After a lot of attempts, this worked in my case:

{
  "compilerOptions": {
    "baseUrl": ".",
    "allowJs": true,
    "resolveJsonModule": true,
    "jsx": "preserve",
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true,
    "paths": {
      "$root/*": ["./*"],
      "@/*": ["src/*"]
    }
  },
  "include": [
    "**/*",
    "**/*.json"
  ],
  "exclude": [
    "node_modules"
  ]
}

@wesleymostien
Copy link

I still can not get CTRL + CLICK working for absolute paths.

I have tried every setting in jsconfig, webpacking resolve, path intellisene plugin for VSCode... nothing changes.

@rw3iss
Copy link

rw3iss commented Jul 10, 2020 via email

@adamjarling
Copy link

I've been wrestling with not being able to "click open Component files" for a month since implementing webpack aliases, and found the solution from this thread.

"jsx": "react" did the trick for my simple configuration. Thanks everyone.

{
  "compilerOptions": {
    "jsx": "react", // This was the fix
    "baseUrl": ".",
    "paths": {
      "@js/*": ["js/*"]
    }
  },
  "exclude": ["node_modules", "static"]
}

@EmilyRosina
Copy link

EmilyRosina commented Nov 13, 2020

For anyone still struggling, I created a gist of my config that FINALLY works, without any errors etc after a few hours of googling.
It's so so slick, I adore it! It takes a few seconds to "warm up" and index everything, but once it has.. it's like night and day 🎉

It's likely I have redundancies in there.. but it's Friday evening and I am just glad it works 😅

@github-actions github-actions bot locked and limited conversation to collaborators Dec 5, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature-request Request for new features or functionality typescript Typescript support issues
Projects
None yet
Development

No branches or pull requests