next.js: Next.js 12.0.2 + Framer 5.0.1 leading to errors in production

What version of Next.js are you using?

12.0.2

What version of Node.js are you using?

14.16.0

What browser are you using?

Chrome 95

What operating system are you using?

macOS

How are you deploying your application?

Vercel

Describe the Bug

Seeing a 500 application error when deploying app to Vercel with the following dependencies:

  • next: 12.0.2
  • framer: 5.0.1

App deploys fine with next: 12.0.1

Vercel error logs below:

2021-11-01T16:43:25.167Z	76a0eb5e-e736-404e-b454-15468c5f94c2	ERROR	file:///var/task/node_modules/framer-motion/dist/es/context/LazyContext.mjs:1
import { createContext } from 'react';
         ^^^^^^^^^^^^^
SyntaxError: Named export 'createContext' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'react';
const { createContext } = pkg;
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:97:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:142:20)
    at async Loader.import (internal/modules/esm/loader.js:182:24)
2021-11-01T16:43:25.168Z	76a0eb5e-e736-404e-b454-15468c5f94c2	ERROR	file:///var/task/node_modules/framer-motion/dist/es/context/LazyContext.mjs:1
import { createContext } from 'react';
         ^^^^^^^^^^^^^
SyntaxError: Named export 'createContext' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'react';
const { createContext } = pkg;
    at ModuleJob._instantiate (internal/modules/esm/module_job.js:97:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:142:20)
    at async Loader.import (internal/modules/esm/loader.js:182:24) {
  page: '/'
}
RequestId: 76a0eb5e-e736-404e-b454-15468c5f94c2 Error: Runtime exited with error: exit status 1
Runtime.ExitError

Expected Behavior

Production environment should mimic development, i.e., not crash

To Reproduce

Does not reproduce locally—only seeing on Vercel in production

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 16
  • Comments: 37 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Downgrading to 12.0.1 worked for me too. This was a nasty bug to ship, where a site completely fails but only in production. How can this type of error be caught in the future? What tests were missing that allowed it to ship? As someone whose business depends on NextJS & Vercel, I’d love to see a retrospective on this issue to identify the gap in quality control and the mitigation steps being put in place to prevent a re-occurrence.

@KevinShiCA Regarding @shopify/react-form:

It claims to provide a version compatible with Node.js ESM (it has an "exports" field that points to a .mjs file). But only most of the referenced files have the .mjs extension. The referenced file @shopify/react-form/build/esm/_virtual/_rollupPluginBabelHelpers.js doesn’t have the correct extension, so Node.js doesn’t treat it as ESM. That leads to this error:

$ node -e "import('@shopify/react-form')"
(node:30304) UnhandledPromiseRejectionWarning: file:///...@shopify/react-form/build/esm/hooks/field/reducer.mjs:1
import { objectSpread2 as _objectSpread2 } from '../../_virtual/_rollupPluginBabelHelpers.js';
         ^^^^^^^^^^^^^
SyntaxError: Named export 'objectSpread2' not found. The requested module '../../_virtual/_rollupPluginBabelHelpers.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '../../_virtual/_rollupPluginBabelHelpers.js';
const { objectSpread2: _objectSpread2 } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:124:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:179:5)
    at async Loader.import (internal/modules/esm/loader.js:178:24)
    at async importModuleDynamicallyWrapper (internal/vm/module.js:451:15)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:30304) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:30304) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

This should be fixed in the @shopify/react-form package. Please report it there. cc @michenly


import { createContext } from 'react' is fine instead, if it’s really react that is installed here. I have seen reports where react has been replaced with preact and that caused this error. @developit is working on that. If this is not related to preact, please provide a reproduction @sambecker


PS: Please try experimental.esmExternals: false as workaround.

https://github.com/react-hook-form/resolvers/issues/271 does not work with v12.0.3-canary.2. I get the error SyntaxError: Named export 'set' not found. The requested module 'react-hook-form' is a CommonJS module, which may not support all module.exports as named exports..

Changing the import from import { yupResolver } from '@hookform/resolvers/yup'; to import { yupResolver } from '@hookform/resolvers/yup/dist/yup'; is a workaround that fixes this issue.

Edit: v12.0.3-canary.5 also fails while collecting page data with the above error.

For note, with v12.0.4 & react-hook-form, it’s only ok with esmExternals: false

And to avoid issue with npm run dev (strange error about outdated code), I advice for now: esmExternals: process.env.NODE_ENV === 'DEVELOPEMENT'

I was also having the same errors in the production, then I changed the version of nextjs to next@12.0.1 and now it works perfectly I was also using framer-motion.

After upgrading to 12.0.3 I still see the issue that @amuttsch mentioned with no next config file. Adding experimental.esmExternals: false fixes the issue, but without I see the following error:

import{get as r,set as e}from"react-hook-form";var i=function(e,i){for(var a in i.fields){var f=i.fields[a];if(f&&f.ref&&"reportValidity"in f.ref){var t=r(e,a);f.ref.setCustomValidity(t&&t.message||""),f.ref.reportValidity()}}},a=function(a,f){f.shouldUseNativeValidation&&i(a,f);var t={};for(var o in a){var s=r(f.fields,o);e(t,o,Object.assign(a[o],{ref:s&&s.ref}))}return t};export{a as toNestError,i as validateFieldsNatively};
                ^^^
SyntaxError: Named export 'set' not found. The requested module 'react-hook-form' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react-hook-form';

Downgrading to 12.0.1 works. 12.0.2 was broken as discussed above, and 12.0.3 is broken without the experimental flag inclusion.

Just updated my example repo to v12.0.3-canary.2 and it works! https://github.com/sambecker/nexttest

Thanks @ijjk + @sokra!

I’m seeing similar errors in the latest version of zustand when combined with 12.0.2

file:///<project-path>/node_modules/zustand/esm/index.mjs:1
import { useReducer, useRef, useEffect, useLayoutEffect } from 'react';
                     ^^^^^^
SyntaxError: Named export 'useRef' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react';
const { useReducer, useRef, useEffect, useLayoutEffect } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:104:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:149:5)
    at async Loader.import (internal/modules/esm/loader.js:177:24)
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
file:///<project-path>/zustand/esm/index.mjs:1
import { useReducer, useRef, useEffect, useLayoutEffect } from 'react';
                     ^^^^^^
SyntaxError: Named export 'useRef' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react';
const { useReducer, useRef, useEffect, useLayoutEffect } = pkg;

    at ModuleJob._instantiate (internal/modules/esm/module_job.js:104:21)
    at async ModuleJob.run (internal/modules/esm/module_job.js:149:5)
    at async Loader.import (internal/modules/esm/loader.js:177:24)
error - unhandledRejection: SyntaxError: Named export 'useRef' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'react';
const { useReducer, useRef, useEffect, useLayoutEffect } = pkg;

Same kinds of errors here but happens when using next@12.0.2 with react-hook-form@7.12.1

Luckily it failed for me in local dev instead of in production. Also reverted to next@12.0.1 to resolve the issue for now.

Seeing this as well, there’s a “minimal” reproducible repository here: https://github.com/jokull/next12-react-form-test/blob/main/pages/index.js - this uses @shopify/react-form which also uses named imports from React, so not Framer exactly but the same idea (maybe change the title of the issue?).

I think any dependency that does things like import {useState} from 'react'; instead of import React from 'react'; React.useState(...); will see this on Next 12. It also doesn’t have to be 'react' specifically, any ESM module importing CJS modules using named imports will suffice.

Weirdly enough this doesn’t seem to have anything to do with SWC - I’ve tried this both with and without a custom babel config file (which disables SWC on Next@12) and the error is the same either way. Seems to be something else that happens behind the scenes in Next@12, I’m reverting to Next@11 for now.

I’ve also seen this sporadically in development (the above linked repo is consistent in development), I think it most likely works locally sometimes because of next’s build cache, though I’m not sure.

Potential issue: we have a user reported 12.0.9 (still in beta) is introducing a regression on this issue after the last patch which we made in hook form https://github.com/react-hook-form/resolvers/issues/337#issuecomment-1021706001 Curious to know what’s changing, what do we need to prepare for this?

I’m having the same problem with Zustand. I downgraded Next to 12.0.1 and it works now.

2021-11-04T09:56:47.575Z ERROR file:///var/task/node_modules/zustand/esm/index.mjs:1 import { useReducer, useRef, useDebugValue, useEffect, useLayoutEffect } from 'react'; ^^^^^^ SyntaxError: Named export 'useRef' not found. The requested module 'react' is a CommonJS module, which may not support all module.exports as named exports.

Same kinds of errors here but happens when using next@12.0.2 with react-hook-form@7.12.1

Luckily it failed for me in local dev instead of in production. Also reverted to next@12.0.1 to resolve the issue for now.

I had an issue, where Next.js built the code for Production just fine, but loading the page would seem to have no React components. Submitting the form would just do a simple HTML submit (reload the page, with form inputs as query string params).

Downgrading to v12.0.1 seems to fix the issue.

Thanks for the follow-up @balazsorban44. The original issue was posted and has not gotten any more response and we suspect it to do with his own setup. I am going to close that issue there and follow up if other issues related pop up again.

FYI, @BPScott had added fix to @shopify/react-form@1.1.8 + (you can now find @shopify/react-form/build/esm/_virtual/_rollupPluginBabelHelpers.mjs file)

cc @KevinShiCA @jokull

The fix from @daniel-stockman-lark for react-hook-form has been implemented the other day but rolled back because of compatibility issues with CRA. @yordis has summarized the problem here: https://github.com/react-hook-form/resolvers/issues/271#issuecomment-990733670

I was also having the same errors in the production, then I changed the version of nextjs to next@12.0.1 and now it works perfectly I was also using framer-motion.

Yesssssss, I’m facing this issue , but now it works when I downgrade to next@12.0.1. Thanks you and everyone in this conversation.

Hey @michenly

Internally we were just having a debate about if any of our open source packages are being use by folks outside of Shopify so this is very cool to see 😄

Just wanted to let you know we love @shopify/react-form. Use it extensively. Did a bunch of research for different forms library and have been very happy with picking this.

I’ll look into the repro.

If this is related to ESM externals, instead of downgrading Next.js you can temporary disable experimental.esmExternals: false to prefer the CommonJs version of node_modules like Next.js 11 did.

Hah, I actually never bothered trying 12.0.1. It works for me, thanks for that!

I’m convinced it’s this PR: https://github.com/vercel/next.js/pull/30427.

I tried out the various canary versions that led up to Next@12.0.2, and even Next@12.0.2-canary.0 will cause this. There are only 3 core changes that went in between 12.0.2-canary.0 and 12.0.1, and the other two are a tsconfig fix and a SWC bump, both of which should be unrelated. The above PR does indeed change a bunch of stuff in Next’s base webpack config relating to ESM loading.

/cc @sokra who authored that PR

Aren’t named (vs global) imports optimal?

Yes, but ESM and CJS have a hell of a time interoping together. Here’s a great article about it: https://simonplend.com/node-js-now-supports-named-imports-from-commonjs-modules-but-what-does-that-mean/

Unfortunately React only provides a CJS build. The community was hoping for an ESM build to come in React 18, but it sounds like it’s going to come in version 19 or later.

@KevinShiCA thanks for building on this. Are you saying if dependencies used import React from 'react' that would mitigate the issue? Aren’t named (vs global) imports optimal? Do you have a theory as to why this works in Next.js 12.0.1 but not 12.0.2?