Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio Code "Cick-Through / Go-To" does not work with path aliases in jsconfig.json (and Next.js)

I am running a next.js project, as the project grew my imports became harder and harder to read.

Which is why I really love the path aliasing in jsconfig.json. Makes everything so much cleaner.

However, and that's a big however, I used to be able to click on any variable (or import) holding cmd and would be directly taken to the final definition. Same with getting a peek ("Code Peek") into the module/variable that I was importing.

This functionality did not seem to work with aliases. Installing module-resolver helped on the top level. I.e. click-through through is now possible for everything starting with @/Components but not the lower level aliases. Any Idea how to fix that?

Caveats:

  • I know I should, but I am currently not yet using es-lint,
  • nor am I explicitly using webpack (I know next.js uses it under the hood)
  • Plain Javascript (no typescript)

Those tools are surely useful, but I want to keep the additional tooling to a minimum right now.

Configs:

This is my jsconfig.json

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@/Components/*": ["components/*"],
            "@/Concepts/*": ["components/Concepts/*"],
            ...
        }
    }
}

this is my .babelrc

{
  "presets": ["next/babel"],
  "plugins": [
    ["styled-components", { "ssr": true }],
    ["module-resolver", {
      "root": ["."],
      "alias": {
        "@/Components": "components",
        "@/Concepts": "components/Concepts",
        ...
      }
    }]
  ]
}

I am importing like this (both imports work):

Click-through works:
import { Bold } from "@/Components/styles";

Click-through does not work:
import { DefaultMarginSlider, Formula } from "@/Concepts/utils";

for completeness sake here is my package.json

like image 568
Fabian Bosler Avatar asked Oct 15 '22 02:10

Fabian Bosler


1 Answers

I got it working with the following config settings

jsconfig.json

{
  "compilerOptions": {
    "target": "es2020",
    "module": "commonjs",
    "allowSyntheticDefaultImports": true,
    "baseUrl": "src",
    "jsx": "react",
    "noImplicitAny": false,
    "paths": {
      "components/*": [
        "./components/*"
      ],
      "utils/*": [
        "./utils/*"
      ],
      "UI/*": [
        "./UI/*"
      ],
      "assets/*": [
        "./assets/*"
      ]
    }
  },
  "exclude": ["node_modules"]
}

my .eslintec file looks like

{
  "env": {
    "browser": true,
    "es6": true
  },
  "extends": [
    "plugin:import/react",
    "airbnb"
  ],
  "globals": {
    "Atomics": "readonly",
    "SharedArrayBuffer": "readonly"
  },
  "settings": {
    "import/resolver": {
      "alias": {
        "map": [
          [
            "UI",
            "./src/UI"
          ],
          [
            "components",
            "./src/components"
          ],
          [
            "assets",
            "./src/assets"
          ]
        ],
        "extensions": [
          ".js",
          ".jsx",
          ".svg",
          ".png"
        ]
      },
      "webpack": {
        "config": "config/webpack.config.js"
      }
    }
  },
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2018,
    "sourceType": "module"
  },
  "parser": "babel-eslint",
  "plugins": [
    "react",
    "react-hooks",
     "import",
     "resolver-alias"
  ],
  "rules": {}
}

And there are the extra plugins I installed to get it working

eslint-import-resolver-alias
eslint-import-resolver-webpack
eslint-plugin-import

And this is my webpack config to resolve while building

resolve: {
  modules: ['node_modules', paths.appNodeModules].concat(
    modules.additionalModulePaths || []
  ),
  extensions: paths.moduleFileExtensions
    .map(ext => `.${ext}`)
    .filter(ext => useTypeScript || !ext.includes('ts')),
  alias: {
    // Support React Native Web
    // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
    'react-dom': '@hot-loader/react-dom',
    'components': path.resolve(__dirname, '../src/components'),
    'assets': path.resolve(__dirname, '../src/assets'),
    'UI': path.resolve(__dirname, '../src/UI'),
    'utils': path.resolve(__dirname, '../src/utils'),
    ...(isEnvProductionProfile && {
      'react-dom$': 'react-dom/profiling',
      'scheduler/tracing': 'scheduler/tracing-profiling',
    }),
    ...(modules.webpackAliases || {}),
  },
  plugins: [
    PnpWebpackPlugin,
    new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
  ],
},

For next.js you can skip the above webpack config and eslint-import-resolver-webpack npm package. It will work fine.

like image 170
warl0ck Avatar answered Nov 15 '22 09:11

warl0ck