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

Add support for ES module syntax in next-i18next.config.js #1505

Closed
trezy opened this issue Nov 8, 2021 · 25 comments
Closed

Add support for ES module syntax in next-i18next.config.js #1505

trezy opened this issue Nov 8, 2021 · 25 comments
Labels

Comments

@trezy
Copy link

trezy commented Nov 8, 2021

Is your feature request related to a problem? Please describe.

Next.js 12 supports ES module syntax for the next.config file if the file extension is .mjs. Creating next-i18next.config.mjs doesn't work, however, since next-i18next looks specifically for a next-i18next.config.js file.

Describe the solution you'd like

next-i18next should support ES module syntax for the next-i18next.config.js file.

Describe alternatives you've considered

I can achieve this by manually importing a next-i18next.config.js file and passing it to serverSideTranslations, but this is burdensome to do for apps with lots of pages.

Additional context

It was very surprising to me that next-i18next requires the existence of a next-i18next.config.js file. It'd be cool if in addition to adding ES modules support, next-i18next would grab its settings from the next.config.js file in the absence of a next-i18next.config.js file.

@isaachinman
Copy link
Contributor

We can release this in the v9.0.0 major. I'd certainly appreciate help if you have time to look into it.

It was very surprising to me that next-i18next requires the existence of a next-i18next.config.js file

The next-i18next package requires additional configuration on top of the NextJs i18n config object. It's not easy/advisable to try and "share" the next.config.js file as it is handled in a very specific way by the NextJs framework and Vercel platform. That is why we need a separate file.

If we standardise/force the localePath option (effectively removing it) as per #1202 (comment), we may also be able to drop the requirement of a config file, however we'd need to test filesystem issues on Vercel and other serverless platforms.

@LaCocoRoco
Copy link

Is there an update to this issue? The last time i tried to use "next-i18next.config.mjs" in combination with "next.config.mjs" i got some problems.

@isaachinman
Copy link
Contributor

No update. @LaCocoRoco Would you like to look into it and contribute?

@LaCocoRoco
Copy link

This is probably way out of my league. If i got some free time i will take a look into it and if i have a solution i will give a response regarding the problem.

@jlarmstrongiv
Copy link

Supporting the cjs syntax would be a nice stopgap next-i18next.config.cjs

@isaachinman
Copy link
Contributor

@jlarmstrongiv PRs welcome.

@GabenGar
Copy link

@isaachinman
The issue at hand is the usage of cjs imports within createConfig() which gets passed as is into esm bundle and thus resulting into invalid ESM module code. No idea how to fix it, especially since with require() rewritten as top level imports it builds just fine with yarn build and the test for it works too when ran standalone as yarn jest ./src/config/createConfig.test.ts.
However when running the package with the changes above I get this error:

error - ../next-i18next/dist/esm/config/createConfig.js:19:0
Module not found: Can't resolve 'fs'
  17 | 
  18 | import { defaultConfig } from './defaultConfig';
> 19 | import fs from 'fs';
  20 | import path from 'path';
  21 | var deepMergeObjects = ['backend', 'detection'];
  22 | export var createConfig = function createConfig(userConfig) {

Import trace for requested module:
../next-i18next/dist/esm/appWithTranslation.js
../next-i18next/dist/esm/index.js
./src/pages/_app.tsx

https://nextjs.org/docs/messages/module-not-found

appWithTranslation() in the logs suggests the bundler is confused about the environment this function is ran at and doesn't code-split it properly.

@stale
Copy link

stale bot commented Jul 10, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added stale and removed stale labels Jul 10, 2022
@stale
Copy link

stale bot commented Jul 30, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 30, 2022
@tkrotoff
Copy link

I hate bots

@stale stale bot removed the stale label Jul 30, 2022
@AhmedBHameed
Copy link

AhmedBHameed commented Aug 10, 2022

Hey everyone.

Before opening a PR to support cjs, I want to double check if this is the only part needed to be added here or?

const DEFAULT_CONFIG_PATH = './next-i18next.config.js'
const DEFAULT_CONFIG_PATH_CJS = './next-i18next.config.cjs'

[...]

  if (!userConfig) {
    if (fs.existsSync(path.resolve(DEFAULT_CONFIG_PATH))) {
      userConfig = await import(path.resolve(DEFAULT_CONFIG_PATH))
    } else if (fs.existsSync(path.resolve(DEFAULT_CONFIG_PATH_CJS))) {
      userConfig = await import(path.resolve(DEFAULT_CONFIG_PATH_CJS))
    }
  }
  
  [...]

I added it locally but I don't understand how the testing works?

@otterDeveloper
Copy link

otterDeveloper commented Aug 15, 2022

What about mjs? @AhmedBHameed

@otterDeveloper
Copy link

Well I made an attempt at https://github.com/otterDeveloper/next-i18next/tree/esm-config-support-1

Importing cjs works but I didn't have any luck with mjs.

It either cant find the mjs file: Error: Cannot find module next-i18next.config.mjs

or because the package has support for CommonJS, in another test project, it throws an error about importing an ESM module using require
Error: require() of ES Module next-i18next.config.mjs not supported.

Even Jest doesn't like importing mjs

So I think this is a no go right now

A mitigation would be to make it clear in the Readme that the config must be named exactly next-i18next.config.js and add an example in on how to import from a mjs next config, next.config.mjs

@jlarmstrongiv
Copy link

jlarmstrongiv commented Aug 16, 2022

@otterDeveloper have you tried the await import("/path/to/next-i18next.config.mjs") syntax when the package has support for CommonJS? (may not work in jest)

@Elindorath
Copy link

Elindorath commented Sep 1, 2022

Maybe I should open another issue for this but just to add to the conversation:
Since Next.js now supports having the config as a function (even an async one since v12.1.0) it would be very nice to have the same for next-i18next.config.js.

For a use case example, as I tried to have only one source of truth for the list of supported locales, I used to do something like this in my next.config.js (with support for prefixing the default locale):

// @ts-check

const fs = require('fs/promises');

module.exports = async (/* phase, { defaultConfig } */) => {
  const locales = await fs.readdir('./public/locales');
  const defaultLocale = 'default';

  /**
   * @type {import('next').NextConfig}
   */
  const nextConfig = {
    i18n: {
      locales: [defaultLocale, ...locales],
      defaultLocale,
      localeDetection: false,
    },
  };
}

@stale
Copy link

stale bot commented Sep 9, 2022

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Sep 9, 2022
@stale stale bot closed this as completed Sep 22, 2022
@techquestions
Copy link

not stale

@Sevi7
Copy link

Sevi7 commented Jan 20, 2023

this issue should be open

@mattp0123
Copy link

Any workaround?

@Simvolick
Copy link

This is still an issue that is not addressed. There are too many benefits to using mjs to not have a work around for this.

@mustafamoe
Copy link

Almost 2 years still nothing! yikes

@adrai
Copy link
Member

adrai commented Apr 4, 2023

feel free to provide a PR if you like it

@Quietly-20201113
Copy link

Quietly-20201113 commented Jun 28, 2023

不使用mjs也不使用cjs后缀就直接写成js即可
// next-i18next.config.js

// eslint-disable-next-line @typescript-eslint/no-var-requires
const path = require('path');
const languagesConfig = [
    {
        label: 'English',
        value: 'EN',
    },
    {
        label: '中文',
        value: 'ZH_CN',
    },
];

const i18n = {
    defaultLocale: 'ZH_CN',
    locales: languagesConfig.map((language) => language.value),
    localePath: path.resolve('./public/locales'),
};

module.exports = {
    i18n,
    languagesConfig,
};
import withBundleAnalyzer from "@next/bundle-analyzer"
import withPlugins from "next-compose-plugins"
import { env } from "./env.mjs"
import { i18n  } from "./next-i18next.config.js";
/**
 * @type {import('next').NextConfig}
 */
const config = withPlugins([[withBundleAnalyzer({ enabled: env.ANALYZE })]], {
  reactStrictMode: true,
  experimental: { instrumentationHook: true },
  rewrites() {
    return [
      { source: "/healthz", destination: "/api/health" },
      { source: "/api/healthz", destination: "/api/health" },
      { source: "/health", destination: "/api/health" },
      { source: "/ping", destination: "/api/health" },
    ]
  },
  head: {
    link: [
      {
        rel: 'icon',
        href: '/favicon.ico',
      },
    ],
  },
  i18n
})

export default config

我这样写可以使用

@nick4fake
Copy link

Why isn't this reopened?

@perezpefaur
Copy link

reopen

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

No branches or pull requests