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

Not working with Next.js >= 10.2.x (probably because of webpack 5, dynamic imports are handled differently) #1202

Closed
adrai opened this issue May 16, 2021 · 35 comments · Fixed by #1302

Comments

@adrai
Copy link
Member

adrai commented May 16, 2021

Describe the bug

Seems with the update to Next.js 10.2, Next.js is by default using webpack 5: https://nextjs.org/blog/next-10-2#webpack-5
image

Occurs in next-i18next version

next-i18next: v8.5.1
Next.js: >= v10.2.x

Steps to reproduce

Just update the next version in the simple example: https://github.com/isaachinman/next-i18next/blob/master/examples/simple/package.json#L12

Error

I have no idea on how this works behind the scene, it may be Next.js itself needs to do something.
Currently an error like this is occurred:
Error: Cannot find module '/Users/user/Projects/next-i18next/examples/simple/next-i18next.config.js'
MODULE_NOT_FOUND
(happens on dev)

Additional context

I'm not very familiar with Next.js and/or webpack 5, so if someone wants to invest a bit of time to investigate, this would be really good.

Currently next-i18next only works with Next.js <= v10.1.x if not passing the userConfig in explicitely

There is also an issue in the Next.js repo: vercel/next.js#24729

➡️ Seems like this is breaking because webpack 5 is handling dynamic imports differently: vercel/next.js#25077

https://nextjs.org/docs/advanced-features/dynamic-import
image

@vexxvakan
Copy link

Yea, this seems to be the case as I can't get it working either. It just keeps on loading my localhost page and does NOT throw any error. As soon as I run "yarn build" it builds perfectly fine and the production build also does work, at least semi good. it seems to be loading for forever until it finally works. 10 seconds loading for a <100kb website is just not acceptable.

Can we get any support from anyone knowledgeable, maybe even the creator?

@isaachinman
Copy link
Contributor

The code block in question is here. It seems like fs.existsSync is returning true, and then await import is failing. Changing it to a require doesn't solve the issue.

I am not sure what exactly the root cause is, but I do know the Vercel team had to do a lot of webpack trickery to get this v5 release stable enough. I assume they are manipulating the fs in an unexpected way.

I won't have much time to debug this for the next week or so, and would appreciate if any contributor wants to help out.

@adrai
Copy link
Member Author

adrai commented May 16, 2021

I am not sure what exactly the root cause is, but I do know the Vercel team had to do a lot of webpack trickery to get this v5 release stable enough. I assume they are manipulating the fs in an unexpected way.

this may be related: vercel/next.js#24700

@adrai adrai changed the title Not working with Next.js 10.2 (probably because of webpack 5) Not working with Next.js 10.2.x (probably because of webpack 5) May 26, 2021
@RA80533
Copy link

RA80533 commented Jun 12, 2021

It may have been that the snippet in question was previously transpiled by Webpack in order for it to work. I believe this to be the case.

@isaachinman import is used to load modules. In this case, it's being used to load what appears to be a user configuration file (likely formatted in JSON). While the asynchrony of the import is correct, import import expects modules rather than arbitrary files.

That being said, it is possible for the environment to add module loaders capable of handling, for example, JSON files. It's likely that Webpack injected this behavior before because import is often treated as synonymous with require which does natively support loading JSON files (this is functionality that Node.js provides for code running in CommonJS environments).

I suggest the snippet is refactored to use readFile from "fs/promises" the very same way import was used. Additionally, the conditional block in which the file is loaded in from should also be removed. Technically, existsSync is used to simply check for the existence of a file and then report back the result. It is not intended to be used in a "check if the file exists then try to open it" workflow; in fact, that sort of workflow should directly attempt to read the file. Errors pertaining the file existing, the user not having permissions to read it, the file having a lock on it, etc., are all reported back to the caller accordingly.

EDIT: It doesn't appear to be as simple as editing the lines. Whatever is read in from the file must be validated in order to determine its type.

@isaachinman
Copy link
Contributor

Yes, we should refactor to only rely on the built-in fs module. Not sure what you meant in your edit.

@RA80533
Copy link

RA80533 commented Jun 12, 2021

It's not as simple as replacing import with readFile.

let userConfig: UserConfig | null;

userConfig = readFileSync(DEFAULT_CONFIG_PATH, "utf8");
//           ^
//           Contains "asdfasdfasdfasfd"

@dohomi
Copy link

dohomi commented Jun 18, 2021

I tried out to upgrade to NextJS v11 and set {webpack5:false}
I still don't get a successful build, next dev works but next build fails with https://reactjs.org/docs/error-decoder.html/?invariant=294
Any idea how to get next-18next running on latest NextJS version? Which is the latest NextJS version which is supported?

@adrai adrai changed the title Not working with Next.js 10.2.x (probably because of webpack 5) Not working with Next.js >10.2.x (probably because of webpack 5) Jun 27, 2021
@adrai adrai changed the title Not working with Next.js >10.2.x (probably because of webpack 5) Not working with Next.js >= 10.2.x (probably because of webpack 5) Jun 27, 2021
@adrai
Copy link
Member Author

adrai commented Jun 27, 2021

I found a temporary fix until vercel/next.js#24700 gets addressed in Next.js Iteration 22 or 23, 24, 25, etc...

  1. in next-i18next: serverSideTranslations.ts line 42, check for !userConfig before importing from DEFAULT_CONFIG_PATH
  2. in userland: for every serverSideTranslations() call, import nextI18NextConfig from '../next-i18next.config.js' and pass it as last argument to serverSideTranslations => await serverSideTranslations(locale, ['common', 'footer'], nextI18NextConfig)

I just tested this on Next.js v11.0.1 and it seems to work.

serverSideTranslations.ts
image

i.e. second-page.js
image

@natterstefan
Copy link
Contributor

The last 7.x release of this package does not work with Next.js >= 10.2.x as well. When I run our app on Vercel with next@10.2.x we got this error

TypeError: Cannot destructure property 'components' of 'object null' as it is null.
at DevServer.renderToHTMLWithComponents ...

That one is also mentioned here #661 (comment).

And it is not related to the folders missing, mentioned in that issue. When I downgrade to next@10.1.3 it works w/o further changes to my files or source code.

@paneidos
Copy link

paneidos commented Jul 1, 2021

I found a temporary fix until vercel/next.js#24700 gets addressed in Next.js Iteration 22 or 23, 24, 25, etc...

1. in next-i18next: `serverSideTranslations.ts` [line 42](https://github.com/isaachinman/next-i18next/blob/master/src/serverSideTranslations.ts#L46), check for `!userConfig` before importing from `DEFAULT_CONFIG_PATH`

2. in userland: for every `serverSideTranslations()` call, `import nextI18NextConfig from '../next-i18next.config.js'` and pass it as last argument to `serverSideTranslations` => `await serverSideTranslations(locale, ['common', 'footer'], nextI18NextConfig)`

I just tested this on Next.js v11.0.1 and it seems to work.

serverSideTranslations.ts
image

i.e. second-page.js
image

We did something similar to get it working: rename the config file and pass the config in manually.

@natterstefan
Copy link
Contributor

Hi @paneidos,

thanks for the update. But this only works with next-i18next@8.x and not the old version, right? Because due to some changes in the latest major version we can't use it at the moment...

@paneidos
Copy link

paneidos commented Jul 1, 2021

@natterstefan we're using 8.5.1 indeed

@natterstefan
Copy link
Contributor

@natterstefan we're using 8.5.1 indeed

Thanks for the info. Too bad, as this solution will probably not work with 7.x. Let's see.

@isaachinman
Copy link
Contributor

@adrai Would you be willing to open a PR with that quick fix on the next-i18next side?

isaachinman pushed a commit that referenced this issue Jul 6, 2021
* only import default config if no userConfig is passed

#1202

* test: only import default config if no userConfig is passed
@isaachinman
Copy link
Contributor

Thanks @adrai. I believe this is simply a NextJs bug at this point – passing your config into serverSideTranslations should work as a workaround until they fix it upstream.

@RA80533
Copy link

RA80533 commented Jul 6, 2021

@isaachinman, the issue is described with full context in #1202 (comment). It does not exist upstream.

Next.js (through Webpack) was transpiling the incorrect usage of import to something along the lines of readFile. To quote my original comment:

[…] It's likely that Webpack injected this behavior before because import is often treated as synonymous with require which does natively support loading JSON files (this is functionality that Node.js provides for code running in CommonJS environments).

This issue should be reopened to better guide a future PR.

@isaachinman isaachinman reopened this Jul 6, 2021
@cvrlnolan
Copy link

Thanks @adrai. I believe this is simply a NextJs bug at this point – passing your config into serverSideTranslations should work as a workaround until they fix it upstream.

ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/vercel/path0/node_modules/next-i18next/dist/commonjs'

I get this webpack error upon production build on Vercel unfortunately. I can't downgrade to webpack4 because my project is already complex & uses a lot of webpack5 features. The funny thing is everything works well in development environment

@adrai
Copy link
Member Author

adrai commented Aug 9, 2021

Thanks @adrai. I believe this is simply a NextJs bug at this point – passing your config into serverSideTranslations should work as a workaround until they fix it upstream.

ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/vercel/path0/node_modules/next-i18next/dist/commonjs'

I get this webpack error upon production build on Vercel unfortunately. I can't downgrade to webpack4 because my project is already complex & uses a lot of webpack5 features. The funny thing is everything works well in development environment

@cvrlnolan are you sure? did you change your code like this?
image
image

@cvrlnolan
Copy link

cvrlnolan commented Aug 9, 2021

Thanks @adrai. I believe this is simply a NextJs bug at this point – passing your config into serverSideTranslations should work as a workaround until they fix it upstream.

ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/vercel/path0/node_modules/next-i18next/dist/commonjs'
I get this webpack error upon production build on Vercel unfortunately. I can't downgrade to webpack4 because my project is already complex & uses a lot of webpack5 features. The funny thing is everything works well in development environment

@cvrlnolan are you sure? did you change your code like this?
image
image

Yes I did all the basic steps & it ran twice on development. But on deployment it causes that error, maybe I omitted something but I don't think so. I had to look for another solution. Forgot to mention I'm working with next >= 11

@adrai
Copy link
Member Author

adrai commented Aug 9, 2021

Thanks @adrai. I believe this is simply a NextJs bug at this point – passing your config into serverSideTranslations should work as a workaround until they fix it upstream.

ModuleNotFoundError: Module not found: Error: Can't resolve 'fs' in '/vercel/path0/node_modules/next-i18next/dist/commonjs'

I get this webpack error upon production build on Vercel unfortunately. I can't downgrade to webpack4 because my project is already complex & uses a lot of webpack5 features. The funny thing is everything works well in development environment

@cvrlnolan are you sure? did you change your code like this?

image

image

Yes I did all the basic steps & it ran twice on development. But on deployment it causes that error, maybe I omitted something but I don't think so. I had to look for another solution. Forgot to mention I'm working with next >= 11

@cvrlnolan just tried it again on the provided simple example and it worked... so must be something on your code... 🤷‍♂️

@adrai
Copy link
Member Author

adrai commented Aug 12, 2021

fyi: still no luck with next.js v11.1.0 😢

@adrai
Copy link
Member Author

adrai commented Aug 13, 2021

I have good news:
Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example
You see here, it is not using the in-built next.js i18n feature.
with a new language-detector module: https://github.com/adrai/next-language-detector/tree/main/example

@isaachinman
Copy link
Contributor

Just want to be clear that next export is not SSG in the context of NextJs, and does not have first-class support anymore. Use of getStaticProps is SSG, and is the recommended approach.

@adrai
Copy link
Member Author

adrai commented Aug 13, 2021

Just want to be clear that next export is not SSG in the context of NextJs, and does not have first-class support anymore. Use of getStaticProps is SSG, and is the recommended approach.

sorry, not a Next pro ;-)
it's using getStaticProps => https://github.com/adrai/next-i18next-static-example/blob/main/pages/%5Blocale%5D/second-page.js#L37

@isaachinman
Copy link
Contributor

No worries! As long as users are implementing getStaticProps, they can simply run next build && next start, and content will be served fully statically. No need to use next export.

@adrai adrai changed the title Not working with Next.js >= 10.2.x (probably because of webpack 5) Not working with Next.js >= 10.2.x (probably because of webpack 5, dynamic imports are handled differently) Aug 30, 2021
@SSylvain1989
Copy link

I have good news:
Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example
You see here, it is not using the in-built next.js i18n feature.

Hello , seems to me that your trick for langage detection doesn't work . I have clone your project , build it
No problem , with the script npm run build ( so with next export) , but when i run the project , i arrive on a empty page :)
Need to put /en or /de on my url for arriving at the landing page.

  "scripts": {
    "dev": "next",
    "build": "next build && next export",
    "export": "next export",
    "out": "npm run build && npm run export",
    "start": "next start -p ${PORT:=3000}"
  },

@adrai
Copy link
Member Author

adrai commented Sep 8, 2021

I have good news:

Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example

You see here, it is not using the in-built next.js i18n feature.

Hello , seems to me that your trick for langage detection doesn't work . I have clone your project , build it

No problem , with the script npm run build ( so with next export) , but when i run the project , i arrive on a empty page :)

Need to put /en or /de on my url for arriving at the landing page.

  "scripts": {

    "dev": "next",

    "build": "next build && next export",

    "export": "next export",

    "out": "npm run build && npm run export",

    "start": "next start -p ${PORT:=3000}"

  },

It's just an example...
Here is also another one: https://github.com/adrai/next-static-i18n-test

@judewang
Copy link

judewang commented Sep 8, 2021

I have good news:

Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example

You see here, it is not using the in-built next.js i18n feature.

Hello , seems to me that your trick for langage detection doesn't work . I have clone your project , build it

No problem , with the script npm run build ( so with next export) , but when i run the project , i arrive on a empty page :)

Need to put /en or /de on my url for arriving at the landing page.

  "scripts": {

    "dev": "next",

    "build": "next build && next export",

    "export": "next export",

    "out": "npm run build && npm run export",

    "start": "next start -p ${PORT:=3000}"

  },

@SSylvain1989 Internationalized Routing does not integrate with next export
https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation

@SSylvain1989
Copy link

I have good news:

Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example

You see here, it is not using the in-built next.js i18n feature.

Hello , seems to me that your trick for langage detection doesn't work . I have clone your project , build it
No problem , with the script npm run build ( so with next export) , but when i run the project , i arrive on a empty page :)
Need to put /en or /de on my url for arriving at the landing page.

  "scripts": {

    "dev": "next",

    "build": "next build && next export",

    "export": "next export",

    "out": "npm run build && npm run export",

    "start": "next start -p ${PORT:=3000}"

  },

@SSylvain1989 Internationalized Routing does not integrate with next export
https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation
Ok .
I try to find a solution for using translation of my website and detect langage preference of the user ... with next export since i don't deploy my website on vercel but cloudflare .

@adrai
Copy link
Member Author

adrai commented Sep 8, 2021

I have good news:

Based on @myWsq's discussion and example I've created a simple next-i18next example that works with SSG: https://github.com/adrai/next-i18next-static-example

You see here, it is not using the in-built next.js i18n feature.

Hello , seems to me that your trick for langage detection doesn't work . I have clone your project , build it

No problem , with the script npm run build ( so with next export) , but when i run the project , i arrive on a empty page :)

Need to put /en or /de on my url for arriving at the landing page.

"scripts": {

"dev": "next",
"build": "next build && next export",
"export": "next export",
"out": "npm run build && npm run export",
"start": "next start -p ${PORT:=3000}"

},

@SSylvain1989 Internationalized Routing does not integrate with next export

https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation

Ok .

I try to find a solution for using translation of my website and detect langage preference of the user ... with next export since i don't deploy my website on vercel but cloudflare .

for me this works good: https://github.com/adrai/next-static-i18n-test/blob/01bd6d2a3ed610ef21202479779ff65c69d439d7/pages/index.js#L25

@Howard86
Copy link

First of all, thanks for sharing all of these!
I found the same solution as @dohomi 's to work with latest next without manually adding nextI18NextConfig, which is just adding {webpack5: false}

The caveat is that, after turning off webpack5, a new next build or deleting existed .next folder is required, even to get next dev working

Reference:

"next": "^11.1.2",
"next-i18next": "^8.8.0"

Downside

The only downside of this approach is we have to disable webpack5 until nextjs mentioned issues are resolved

Original comment

I tried out to upgrade to NextJS v11 and set {webpack5:false}
I still don't get a successful build, next dev works but next build fails with https://reactjs.org/docs/error-decoder.html/?invariant=294
Any idea how to get next-18next running on latest NextJS version? Which is the latest NextJS version which is supported?

@isaachinman
Copy link
Contributor

For those not following #1384, this has been linked to a bug in NextJs: vercel/next.js#24700

@ijjk
Copy link

ijjk commented Oct 20, 2021

Hi, I took another look at this and it seems loading the config file is resolved in the latest canary of Next.js v11.1.3-canary.86 with experimental.outputFileTracing although it fails to detect the locales being loaded from public correctly because these fs calls aren't statically analyzable.

Changing these lines to below should resolve this:

const namespacesByLocale = Object.keys(initialI18nStore)
  .map(locale => {
    return fs.readdirSync(
      path.join(process.cwd(), `public/locales/${locale}`)
    )
    .map(file => file.replace(`.${localeExtension}`, ''))
  })

I would recommend against allowing a custom localePath as this makes it not able to be statically analyzable and it will not be able to detect the files being needed automatically.

@adrai
Copy link
Member Author

adrai commented Oct 20, 2021

if not linking next-i18next this issue does not seem to occur anymore: vercel/next.js#24700 (comment)

@isaachinman
Copy link
Contributor

isaachinman commented Oct 21, 2021

Can confirm that the issue seems resolved in next@v11.1.3-canary.86 with experimental.outputFileTracing.

Once this lands in a stable NextJs release, I'll make a few changes to the next-i18next repo, and likely release a new major version.

If end users are happy to install next@canary, they should now be unblocked. Here is an example, deployed on Vercel.

Thanks both @ijjk and @adrai!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.