next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Parsing error: Cannot find module 'next/babel' in Visual Studio Code

Open ceIia opened this issue 2 years ago • 4 comments

What version of Turborepo are you using?

1.4.7

What package manager are you using / does the bug impact?

pnpm

What operating system are you using?

Mac

Describe the Bug

Hi! I just created a turborepo project using npx, and VSCode throws the following error:

Parsing error: Cannot find module 'next/babel'
Require stack:
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]_ir3quccc6i62x6qn6jjhyjjiey/node_modules/next/dist/compiled/babel/bundle.js
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]_ir3quccc6i62x6qn6jjhyjjiey/node_modules/next/dist/compiled/babel/eslint-parser.js
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]_dyxdave6dwjbccc5dgiifcmuza/node_modules/eslint-config-next/parser.js
- /Users/celia/.dev/flex/node_modules/.pnpm/@[email protected]/node_modules/@eslint/eslintrc/lib/config-array-factory.js
- /Users/celia/.dev/flex/node_modules/.pnpm/@[email protected]/node_modules/@eslint/eslintrc/lib/index.js
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/cli-engine/cli-engine.js
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/cli-engine/index.js
- /Users/celia/.dev/flex/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/api.js
- /Users/celia/.vscode-insiders/extensions/dbaeumer.vscode-eslint-2.2.6/server/out/eslintServer.jseslint

This is from a project out-of-the-box, created with npx create-turbo. I haven't made any changes to the bootstrapped files.

I have tried a few solutions:

  1. This workaround suggested by Saral Karki: basically adding "next/babel" in the list of extends, inside of eslint-config-custom. It does "fix" the error inside VSCode, making it stop yelling at me.
  2. However, with this change, pnpm run lint breaks throwing the following error: Failed to load config "next/babel" to extend from.. I then found this thread, where Domi said the first fix I tried is basically a "hack". I then tried tinkering around with Akasha's answer, with no success.
  3. Setting up eslint.workingDirectories to my packages/ and apps/ folders in my .vscode/settings.json (making sure I had no conflict in my personal settings.json, no success here either.
  4. Setting up eslint.packageManager to pnpm, nothing here.
  5. Installing @babel/eslint-parser, nothing either.

Note: the issue does not appear when using npm or yarn as the default package manager, configured in the create-turbo CLI.

Expected Behavior

VSCode doesn't throw an error about a parsing error, and the build runs correctly.

To Reproduce

  1. Run pnpx create-turbo or npx create-turbo
  2. Setup using CLI as normal, and select pnpm as the package manager.
  3. Open Visual Studio Code with the ESLint extension code installed.
  4. Open any .eslintrc.js or any next.config.js file in the default project.
  5. The error will be visible at the top of the IDE window.

ceIia avatar Sep 18 '22 16:09 ceIia

The root problem in this stack is that one of these four modules:

[email protected]_ir3quccc6i62x6qn6jjhyjjiey
[email protected]_dyxdave6dwjbccc5dgiifcmuza
@[email protected]
[email protected]

In one of these files:

next/dist/compiled/babel/bundle.js
next/dist/compiled/babel/eslint-parser.js
eslint-config-next/parser.js
@eslint/eslintrc/lib/config-array-factory.js
@eslint/eslintrc/lib/index.js
eslint/lib/cli-engine/cli-engine.js
eslint/lib/cli-engine/index.js
eslint/lib/api.js

Something depends on next/babel. Given just naming, that rules out basically everything south of:

I'm going to transfer this issue over to Next.js for more help!

nathanhammond avatar Sep 19 '22 17:09 nathanhammond

Based on this line: https://github.com/vercel/next.js/blob/35098a1477752e06030afa2555023138b772c4a4/packages/eslint-config-next/parser.js#L4

I believe next should be added to peerDependencies here: https://github.com/vercel/next.js/blob/canary/packages/eslint-config-next/package.json

balazsorban44 avatar Sep 19 '22 19:09 balazsorban44

@balazsorban44 next was removed from eslint-config-next's peer dependencies in https://github.com/vercel/next.js/pull/38009 because npm simply won't resolve next@canary in this case. And we can do nothing about this...

More details: https://github.com/npm/cli/issues/4958

SukkaW avatar Sep 20 '22 03:09 SukkaW

Is there any "solution" or "workaround" for this? I am unsure as to what can be done at this point.

image

handletastic avatar Sep 20 '22 21:09 handletastic

Is there any "solution" or "workaround" for this? I am unsure as to what can be done at this point.

image

My not-so-optimal workaround for this has been installing Next on the root workspace, i.e., pnpm install -Dw next@<x.y.z>. Makes the whole error go away. It's been beneficial too in working with packages where I need types from Next.

jayg-hive avatar Sep 26 '22 08:09 jayg-hive

I was able to get this working also by installing next in the root of my pnpm workspace. I was curious to see if there was a better way and I managed to come up with a workaround I haven't seen yet, maybe it would be useful to someone else.

I'm not sure where the above mentioned line comes into play, but I found the problematic part of the config for me was this line:

https://github.com/vercel/next.js/blob/cae96f27ec53cd42e992a748b9727852df9247c5/packages/eslint-config-next/index.js#L85

Which makes total sense because I only experience this issue in certain js config files, not in typescript because that uses the typescript parser rather than the babel one.

In order to workaround this, I installed next in the eslint config package within my workspace and I used require.resolve to supply the babel parser with an absolute path to next/babel within my sharable config. It looks like this:

/**
 * @type {import('eslint').Linter.Config}
 */
module.exports = {
  extends: ['next/core-web-vitals', 'turbo', 'prettier'],
  ignorePatterns: ['node_modules', 'dist'],
  parserOptions: {
    babelOptions: {
      presets: [require.resolve('next/babel')],
    },
  },
};

So far, I haven't found any unintended side-effects. I still have some testing to do in order to be certain.

zmrl010 avatar Oct 01 '22 00:10 zmrl010

I have been dealing with this issue off and on as well for months. I have a main 'react' folder with a lot of projects in that I like to have open as workspace so I can easily dig up solutions from other projects wh ilst working. Whenever I setup a new Next JS (npx create-next-app) with the default linting settings I ALWAYS have this issue and I have yet to find a workable solution. If I open just one project in VS Code then it is fine. Also if I remove Next's default linting and use say, Airbnb then that also doesn't throw this error.

The issue clearly stems from having a root folder with multiple different react projects open as workspace in VS Code.

If anyone gets a working solution then I would love to know. For now its easy enough to just remove the default linting setup from each new Next project and replace it with my customized Airbnb one.

EDIT: To piggyback @zmrl010 comments above, I also dug into next.js/packages/eslint-config-next/index.js and just simply commented out presets: ['next/babel'], to see what would happen and it gets rid of the error, but also gets rid of live linting. I am far from a coding expert but even I know that this isn't really solution....

PaulHaze avatar Oct 08 '22 06:10 PaulHaze

I have been dealing with this issue off and on as well for months. I have a main 'react' folder with a lot of projects in that I like to have open as workspace so I can easily dig up solutions from other projects wh ilst working. Whenever I setup a new Next JS (npx create-next-app) with the default linting settings I ALWAYS have this issue and I have yet to find a workable solution. If I open just one project in VS Code then it is fine. Also if I remove Next's default linting and use say, Airbnb then that also doesn't throw this error.

The issue clearly stems from having a root folder with multiple different react projects open as workspace in VS Code.

If anyone gets a working solution then I would love to know. For now its easy enough to just remove the default linting setup from each new Next project and replace it with my customized Airbnb one.

EDIT: To piggyback @zmrl010 comments above, I also dug into next.js/packages/eslint-config-next/index.js and just simply commented out presets: ['next/babel'], to see what would happen and it gets rid of the error, but also gets rid of live linting. I am far from a coding expert but even I know that this isn't really solution....

I'm not sure if you misunderstood my comment, or if I am misunderstanding yours. With eslint-config-next, any package that is linting but doesn't have next installed will try to access the module next/babel. If next isn't installed in that package, then it throws this error because next/babel won't be resolved. My suggestion was to use a eslint-config-custom (or w/e you call it) where you have next installed as a dependency, then you require.resolve the next package from eslint-config-custom. I haven't thoroughly tested this but it seems to work and the logic adds up. The only problem I see with this is now all your linted packages depend on next for development.

Removing the presets: ['next/babel'], line showed you behavior that I would expect from doing something like that. Since eslint-config-next relies on next/babel for eslint parsing, removing that line would remove the dependency on next, thus getting rid of the error. But it would no longer have configuration for parsing non-TypeScript files, which is what next/babel is for. You could definitely apply your own presets in extended config, but definitely don't do this in your node_modules.

So there is my approach I outlined here, or the one found above that was to install next in the root workspace. Both seem like reasonable workarounds to me.

zmrl010 avatar Oct 10 '22 16:10 zmrl010

I was able to get this working also by installing ...

This helped, thanks 🙏

tlays avatar Oct 11 '22 08:10 tlays

So there is my approach I outlined here, or the one found above that was to install next in the root workspace. Both seem like reasonable workarounds to me.

@zmrl010 So yes there may be some confusion. I was just wondering, so the error comes up because as I think I mentioned, I have a main folder on my computer called 'react' which has EVERY react project that I have started. So lots and LOTS of projects. This main react folder is saved as a workspace in VS Code as I often like to work with easy access to lots of projects so I can find solutions for problems in a new project in older code bases.

The ROOT of this project ('/react') doesn't have anything in it. Are you suggesting I install 'next' somewhere in this root folder? Would that solve the error? My Next Js projects live in /react/nextjs/some_project folder, so having NextJs installed into react would solve the eslint error?

As I mentioned, it doesn't occur when I have JUST the project open on its own in VS Code, and it doesn't occur if I use other linting presets...

PaulHaze avatar Oct 11 '22 19:10 PaulHaze

I think I understand. The discussions here have all been focused around monorepo or multi-package repo setup. Are you currently using a package manager to leverage this functionality? All the major players have support now, but I use pnpm. When I refer to root, I am saying at the very base directory of my project, there is a file called pnpm-workspace.yaml and this tells me where I have subpackages or projects installed. In yarn or npm this will be workspaces property in package.json. If you are not using these features, you might check it out to see if it would be good for your way of doing things.

The reason why it works correctly when you open a project in VSCode directly is because often times extensions use default install locations and since you have an unusual layout, VSCode just gets confused. The ESLint setting "eslint.workingDirectories" is an important setting for this type of scenario. One of my next projects is setup like this:

// .vscode/settings.json

{
  "eslint.workingDirectories": [
    { "pattern": "apps/*/" },
    { "pattern": "packages/*/" }
  ]
}

This allows each project in apps/ or packages/ to supply their own linting config and the extension should read from the config of the project you're in. Hopefully that helps!

zmrl010 avatar Oct 11 '22 19:10 zmrl010

The reason why it works correctly when you open a project in VSCode directly is because often times extensions use default install locations and since you have an unusual layout, VSCode just gets confused. The ESLint setting "eslint.workingDirectories" is an important setting for this type of scenario.

Note: I did try using eslint.workingDirectories with pnpm, which did not fix the issue (cf. the original message).

ceIia avatar Oct 12 '22 12:10 ceIia

@zmrl010 Well I think there was maybe some confusion going on, but I sort of followed your advice and ran pnpm init in my top level react folder, and then installed Next into this folder (even though it really does not need be here) and voila, the errors are all gone.....

PaulHaze avatar Oct 12 '22 23:10 PaulHaze

If you install the project with pnpm this error will appear. I tried adding public-hoist-pattern[]=next* to the .npmrc in the root project, reinstall and this error no longer appears.

thevuong avatar Jan 04 '23 10:01 thevuong

A somehow cleaner fix for this is to not let ESLint use the next/core-web-vitals extension for linting non-jsx / tsx files in the first place:

{
  // You might want to additionally set this in monorepos where Next.js app is in a subdir
  "root": true,
  "extends": ["next/core-web-vitals"],
  "overrides": [
    {
      // Adapt to your needs (e.g. some might want to only override "next.config.js")
      "files": ["*.js"],
      // This is the default parser of ESLint
      "parser": "espree",
      "parserOptions": {
        "ecmaVersion": 2020
      }
    }
  ]
}

paescuj avatar Jan 11 '23 14:01 paescuj

Hi all ☀️, I just found a very simple fix for that bug in this Stack Overflow answer 👉 https://stackoverflow.com/a/70421220/7103634

In eslint.json, we just need to replace "extends": "next/core-web-vitals" by "extends": ["next/babel","next/core-web-vitals"]

@JanKaifer I can make a PR if you think the fix is right. Let me know 🙏

DavNej avatar Jan 17 '23 09:01 DavNej

The SO post looks solid, but I'm not able to reproduce the issue. I understood that this issue is present in all next projects using pnpm but when I create-next-app it works fine.

jankaifer avatar Jan 17 '23 09:01 jankaifer

As mentioned by the author this problem occurs when creating the project with turborepo.

npx create-turbo@latest

thevuong avatar Jan 17 '23 10:01 thevuong

Hi all ☀️, I just found a very simple fix for that bug in this Stack Overflow answer 👉 https://stackoverflow.com/a/70421220/7103634

In eslint.json, we just need to replace "extends": "next/core-web-vitals" by "extends": ["next/babel","next/core-web-vitals"]

@JanKaifer I can make a PR if you think the fix is right. Let me know 🙏

This workaround isn't effective in all cases - just look at the full thread on Stack Overflow. That's why I came up with https://github.com/vercel/next.js/issues/40687#issuecomment-1378845989 which is a bit more sensible workaround in my opinion.

Ultimately, I think we should tackle the problem at source (I feel like https://github.com/vercel/next.js/issues/40687#issuecomment-1251451833 & https://github.com/vercel/next.js/issues/40687#issuecomment-1251778801 are going into the right direction) instead of applying some pseudo workarounds.

paescuj avatar Jan 17 '23 10:01 paescuj

Thanks for pointing out the issues with the SO solution

I tried the second solution in that SO thread: add "eslint.packageManager": "pnpm" into vscode config It seems to work fine: https://github.com/JanKaifer/next-repro-40687/blob/ea5ec944e827ff3e2498b7dc5407ffa61eff8732/.vscode/settings.json#L2

jankaifer avatar Jan 17 '23 10:01 jankaifer

So this seems to be an issue with eslint vscode extension? I'll close this because there is not much we can do.

But it will be probably good to open a relevant issue with eslint vscode extension maintainers.

jankaifer avatar Jan 19 '23 09:01 jankaifer

I think I understand. The discussions here have all been focused around monorepo or multi-package repo setup. Are you currently using a package manager to leverage this functionality? All the major players have support now, but I use pnpm. When I refer to root, I am saying at the very base directory of my project, there is a file called pnpm-workspace.yaml and this tells me where I have subpackages or projects installed. In yarn or npm this will be workspaces property in package.json. If you are not using these features, you might check it out to see if it would be good for your way of doing things.

The reason why it works correctly when you open a project in VSCode directly is because often times extensions use default install locations and since you have an unusual layout, VSCode just gets confused. The ESLint setting "eslint.workingDirectories" is an important setting for this type of scenario. One of my next projects is setup like this:

// .vscode/settings.json

{
  "eslint.workingDirectories": [
    { "pattern": "apps/*/" },
    { "pattern": "packages/*/" }
  ]
}

This allows each project in apps/ or packages/ to supply their own linting config and the extension should read from the config of the project you're in. Hopefully that helps!

@zmrl010 Gonna ask the dumbest question here. Did you change your vscode settings.json or did you add a folder called .vscode and a file called settings.json in the root of your monorepo? I assumed the former, but not 100% sure

paulwongx avatar Jan 22 '23 00:01 paulwongx

My Problem

I found this error in project with PNPM, ESLint, and Monorepo architecture using Turborepo.

My Solution

add this into the ESLint config file:

parserOptions: {
    babelOptions: {
      presets: [require.resolve('next/babel')],
    },
  },

ImBIOS avatar Jan 26 '23 06:01 ImBIOS

My Problem

I found this error in project with PNPM, ESLint, and Monorepo architecture using Turborepo.

My Solution

add this into the ESLint config file:

parserOptions: {
    babelOptions: {
      presets: [require.resolve('next/babel')],
    },
  },

in all (.eslintrc.js) files ??

Learning-X avatar Jan 26 '23 13:01 Learning-X

in all (.eslintrc.js) files ??

@Learning-X I'm using a Monorepo architecture, so I only need to implement it in the parent or the main ESLint Config file.

ImBIOS avatar Jan 26 '23 13:01 ImBIOS

@zmrl010 Gonna ask the dumbest question here. Did you change your vscode settings.json or did you add a folder called .vscode and a file called settings.json in the root of your monorepo? I assumed the former, but not 100% sure

Not dumb at all, relative paths can be ambiguous. In my example above, I am referring to the settings file <projectRootDir>/.vscode/settings.json. This is where vscode saves and loads workspace-specific settings, at least by default.

in all (.eslintrc.js) files ??

As @ImBIOS said, you only need to do this once in the main eslint config that you extend. I've only done this in a monorepo setup with a separate eslint-config-{PROJECT_NAME} package and next listed as a dependency for that package. The reason why this works is because require.resolve uses node's module resolution to return the absolute path to a module and since this package has next as a top-level dependency, it can provide that absolute path to any importing modules.

If that sounds hacky, its because it is. I would opt for a different solution if you can find something, but this works as a bandaid fix.

zmrl010 avatar Jan 26 '23 15:01 zmrl010

A somehow cleaner fix for this is to not let ESLint use the next/core-web-vitals extension for linting non-jsx / tsx files in the first place:

{
  // You might want to additionally set this in monorepos where Next.js app is in a subdir
  "root": true,
  "extends": ["next/core-web-vitals"],
  "overrides": [
    {
      // Adapt to your needs (e.g. some might want to only override "next.config.js")
      "files": ["*.js"],
      // This is the default parser of ESLint
      "parser": "espree",
      "parserOptions": {
        "ecmaVersion": 2020
      }
    }
  ]
}

IMO, this is the cleanest solution with no hacks:

  • no global .vscode settings for workspaces (yet another source of truth for workspaces)
  • no next/babel addition that causes build issues (swc incompatible)
  • no require.resolve for those using .json eslint files instead of .js

tkodev avatar Feb 07 '23 22:02 tkodev

Hi all ☀️, I just found a very simple fix for that bug in this Stack Overflow answer 👉 https://stackoverflow.com/a/70421220/7103634

In eslint.json, we just need to replace "extends": "next/core-web-vitals" by "extends": ["next/babel","next/core-web-vitals"]

@JanKaifer I can make a PR if you think the fix is right. Let me know 🙏

Just wanted to point out that this requires a VS Code restart to take effect. Worked great for me.

mattbartley avatar Feb 11 '23 19:02 mattbartley

@DavNej, Thanks for the suggestion. Further issue not observed.

77pintu avatar Feb 15 '23 15:02 77pintu

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Mar 18 '23 00:03 github-actions[bot]