Painless Paths with Webpack and VSC

Painless Paths with Webpack and VSC

Written by Andrew Del Prete and edited by TJ Miller and David Hemphill

Earlier this month a good friend of mine, @tjmiller, tweeted a tweet I found quite helpful so I thought I'd share the wealth.

webpack Aliases

We don't use VueJS at my day job, but I try to take every opportunity I can to get my hands dirty with it on side projects and for fun.

After generating a vue-cli webpack project you'll notice that the ES6 import statements begin with the @ in the provided example components.

import HelloWorld from "@/components/HelloWorld";

The @ symbol in this case references the ./src directory. So instead of having to use ../ to eventually find the module we're looking for, we get this nice little @lias to do the monotonous work for us. Nice and clean!

We use React heavily at Musicbed and love it to pieces. Our application is fairly robust and I felt something like this could be really helpful to our team. I began digging into ways to introduce aliases into our custom webpack config.

The first place I looked was in the webpack boilerplate vue-cli provides and found this little bit of code in webpack.base.conf.js:

    // webpack code from vue-cli webpack template
    resolve: {
      extensions: ['.js', '.vue', '.json'],
      alias: {
        'vue$': 'vue/dist/vue.esm.js',
        '@': resolve('src'),

The code above essentially tells webpack that when it's doing it's business and comes across an import with the @ symbol, look in the src directory and continue doing it's thing.

This got me thinking about our codebase and how I could leverage aliases even more than just the one for src. Along with React components, we also use Redux actions, reducers, and have a handful of other things I thought would be nice to have easier access to.

    // custom webpack build
    resolve: {
      extensions: [".js"],
      alias: {
        "@actions": path.join(__dirname, "/src/redux/actions"),
        "@components": path.join(__dirname, "/src/components"),
        "@helpers": path.join(__dirname, "/src/helpers"),
        "@reducers": path.join(__dirname, "/src/redux/reducers"),
        "@services": path.join(__dirname, "/src/services"),
        "@tests": path.join(__dirname, "/src/tests")

Now if I wanted to reference a component or helper from anywhere in our codebase it's as simple as:

    import HelloWorld from "@components/HelloWorld";
    import helpfulFunction from "@helpers/helpfulFunction";

Pretty slick!

For more information about webpack aliases, check out the official docs:

What about VSC?

Let's circle back around to my buddy Tj's original tweet. The code I've shown above is for webpack to understand what to do with our aliases. Our editor is pretty clueless so we have to tell it as well.

In VSC we can add a file called jsconfig.js to our project root and do some config'n.

    // jsconfig.js
      "compilerOptions": {
        "baseUrl": ".",
        "paths": {
          "@components/*": ["./src/components/*"],
          "@actions/*": ["./src/redux/actions/*"],
          "@reducers/*": ["./src/redux/reducers/*"],
          "@services/*": ["./src/services/*"],
          "@tests/*": ["./src/tests/*"]
      "include": ["src"]

This gives us three benefits I'm aware of:

  1. Now VSC won't gripe at us for not being able to find the module.
  2. You can now cmd+click the aliesed module to open the file directly.
  3. IntelliSense now works as it should and your editor can see what's inside the imported file and do it's auto-complete magic.

This solution also comes with one caveat I'm aware of. At the time I'm writing this, VSC won't auto-complete the imported path while you're typing it. Bummer! I believe there is an issue to hopefully fix this in upcoming builds so we should be okay!


For more information about jsconfig.js, check out the official docs:

But now ESLint complains

If you're using eslint-import-plugin, it will most likely complain at you about not knowing what to do with your beautiful aliesed imports. This is okay, we have a solution!

Follow the installation instructions for eslint-import-resolver-webpack

And add the following to your .eslintrc file:

    // .eslintrc
    "settings": {
      "import/resolver": "webpack"

And that's it!

I hope you find some great use cases for webpack aliases in your codebase and also find the corresponding VSC settings helpful.

About Andrew

Andrew Del Prete is the Lead Engineer at Musicbed. He also records screencasts at and co-hosts the podcast You can follow him on Twitter and/or Medium.

The contributors to JavaScript January are passionate engineers, designers and teachers. Emily Freeman is a developer advocate at Kickbox and curates the articles for JavaScript January.