mui / material-ui

Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.
https://mui.com/material-ui/
MIT License
93.76k stars 32.24k forks source link

[usePagination] - Babel error (Cannot use import statement outside a module) #33501

Closed Kyhaiu closed 2 years ago

Kyhaiu commented 2 years ago

Duplicates

Latest version

Current behavior 😯

When I create a DataGrid component using a custom pagination with the usePagination hook and run with storybook everything seems ok, and work as I expected. But when I try to use into my code. Things dosen't work fine. I get this annoying error.

Screen error stack

image

Console error stack

image

Terminal error stack

/home/operador/projetos/gestor-clinicas-next/node_modules/@mui/material/usePagination/usePagination.js:1
import _extends from "@babel/runtime/helpers/esm/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.@mui/material/usePagination/usePagination (/home/operador/projetos/gestor-clinicas-next/packages/web/app/.next/server/pages/_app.js:4793:18)
event - build page: /
wait  - compiling...
event - compiled successfully
/home/operador/projetos/gestor-clinicas-next/node_modules/@mui/material/usePagination/usePagination.js:1
import _extends from "@babel/runtime/helpers/esm/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.@mui/material/usePagination/usePagination (/home/operador/projetos/gestor-clinicas-next/packages/web/app/.next/server/pages/_app.js:4793:18)
error - /home/operador/projetos/gestor-clinicas-next/node_modules/@mui/material/usePagination/usePagination.js:1
import _extends from "@babel/runtime/helpers/esm/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.@mui/material/usePagination/usePagination (/home/operador/projetos/gestor-clinicas-next/packages/web/app/.next/server/pages/_app.js:4793:18) {
  page: '/'
}
/home/operador/projetos/gestor-clinicas-next/node_modules/@mui/material/usePagination/usePagination.js:1
import _extends from "@babel/runtime/helpers/esm/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.@mui/material/usePagination/usePagination (/home/operador/projetos/gestor-clinicas-next/packages/web/app/.next/server/pages/_app.js:4793:18)
/home/operador/projetos/gestor-clinicas-next/node_modules/@mui/material/usePagination/usePagination.js:1
import _extends from "@babel/runtime/helpers/esm/extends";
^^^^^^

SyntaxError: Cannot use import statement outside a module
    at compileFunction (<anonymous>)
    at Object.compileFunction (node:vm:352:18)
    at wrapSafe (node:internal/modules/cjs/loader:1033:15)
    at Module._compile (node:internal/modules/cjs/loader:1069:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Function.Module._load (node:internal/modules/cjs/loader:822:12)
    at Module.require (node:internal/modules/cjs/loader:1005:19)
    at require (node:internal/modules/cjs/helpers:102:18)
    at Object.@mui/material/usePagination/usePagination (/home/operador/projetos/gestor-clinicas-next/packages/web/app/.next/server/pages/_app.js:4793:18)

Expected behavior πŸ€”

Work similarly to the behavior that we achieve on storybook.

Steps to reproduce πŸ•Ή

I've tried to reproduce it on blitzstack, but unsuccessfully. Because when I trying to replicate the structure that we have on storybook an different error appears and I couldn't solve it.

Context πŸ”¦

We are working with MFE (Microfrontend) structure using webpack module federation, thus we believe the error might be on the transpilation process as the babel error suggest.

package.json ```json { "name": "@clinical/ui", "version": "1.0.0", "main": "dist/index", "types": "dist/index.d.ts", "license": "MIT", "private": true, "scripts": { "build": "babel --root-mode upward src/ --extensions '.tsx,.ts' --out-dir dist && tsc", "build-storybook": "build-storybook", "clean": "rm -fr dist", "clean:all": "yarn workspace @clinical/ui clean && rm -fr node_modules", "storybook": "start-storybook -p 6006", "test": "jest --config=../../../jest.config.js" }, "dependencies": { "@clinical/core": "1.0.0", "@date-io/dayjs": "^2.14.0", "@emotion/react": "^11.9.0", "@emotion/styled": "^11.8.1", "@mui/material": "^5.9.0", "@mui/x-data-grid": "^5.12.1", "@mui/x-date-pickers": "^5.0.0-alpha.5", "grommet": "^2.24.0", "grommet-icons": "^4.7.0", "react-feather": "^2.0.10" }, "devDependencies": { "@storybook/addon-essentials": "^6.4.22", "@storybook/react": "^6.4.22" } } ```
tsconfig.json ```json { "compileOnSave": true, "compilerOptions": { // Extendends start here "baseUrl": ".", "target": "es2017", "module": "commonjs", "lib": ["es6", "dom", "es2016", "es2017"], "jsx": "react", "removeComments": true, "esModuleInterop": true, "resolveJsonModule": true, "experimentalDecorators": true, "emitDecoratorMetadata": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "declaration": true, "allowJs": true, "moduleResolution": "node", "noUnusedLocals": true, "noUnusedParameters": true, "noImplicitReturns": true, "noImplicitThis": true, "noImplicitAny": true, "strictNullChecks": true, "suppressImplicitAnyIndexErrors": true, "allowSyntheticDefaultImports": true, // Extends end here "module": "ESNext", "declarationMap": true, "outDir": "dist", "baseUrl": "./src", "typeRoots": ["node_modules/@types", "src/@types", "../../../node_modules/@types"], "jsx": "preserve" }, "include": ["src/**/*.tsx", "src/**/*.ts"], "exclude": [ "node_modules", ".storybook", "dist", "*.tsbuildinfo", "**/*.stories.tsx", "**/*.test.tsx", "test-helpers" ] } ```

Observation: The tsconfig is extended from another one.

Your environment 🌎

npx @mui/envinfo ``` System: OS: Linux 5.13 Ubuntu 20.04.4 LTS (Focal Fossa) CPU: (8) x64 Intel(R) Core(TM) i5-10300H CPU @ 2.50GHz Memory: 16.37 GB / 31.19 GB Container: Yes Shell: 5.8 - /bin/zsh Binaries: Node: 16.15.1 - ~/.nvm/versions/node/v16.15.1/bin/node Yarn: 1.22.19 - ~/.nvm/versions/node/v16.15.1/bin/yarn npm: 8.11.0 - ~/.nvm/versions/node/v16.15.1/bin/npm Managers: Apt: 2.0.9 - /bin/apt Utilities: CMake: 3.16.3 - /bin/cmake Make: 4.2.1 - /bin/make GCC: 9.4.0 - /bin/gcc Git: 2.25.1 - /bin/git Ninja: 1.10.0 - /bin/ninja Servers: Nginx: 1.18.0 - /usr/sbin/nginx Virtualization: Docker: 20.10.17 - /bin/docker IDEs: Emacs: 26.3 - /bin/emacs Nano: 4.8 - /bin/nano VSCode: 1.69.1 - /snap/bin/code Vim: 8.1 - /bin/vim Languages: Bash: 5.0.17 - /bin/bash Java: 17.0.3 - /bin/javac Perl: 5.30.0 - /bin/perl Python: 2.7.18 - /bin/python Python3: 3.8.10 - /bin/python3 Browsers: Chrome: 103.0.5060.114 Firefox: 102.0 Vivaldi 5.3.2679.68 stable Brave 103.1.40.113 Monorepos: Yarn Workspaces: 1.22.19 ```
Daniel-Boll commented 2 years ago

Any updates on this issue? Is this a babel problem?

Kyhaiu commented 2 years ago

Any updates on this issue? Is this a babel problem?

I solve this error with a work-arround. Basicly I copy the entire code of usePagination and paste in my project. Also I change the transpiler engine from Babel to SWC. That solves my problem, but it's a terrible work-arround.

Observation: I'm not sure about changing the transpiler engine.

github-actions[bot] commented 2 years ago

πŸ‘‹ Thanks for using MUI Core!

We use GitHub issues exclusively as a bug and feature requests tracker, however, this issue appears to be a support request.

For support, please check out https://mui.com/getting-started/support/. Thanks!

If you have a question on Stack Overflow, you are welcome to link to it here, it might help others. If your issue is subsequently confirmed as a bug, and the report follows the issue template, it can be reopened.

builtbyproxy commented 2 years ago

I'm getting the same error when using MUI in NextJS. I'm experiencing it with createTheme instead of usePagination @Kyhaiu did you get any closer to solving this?

Kyhaiu commented 2 years ago

I'm getting the same error when using MUI in NextJS. I'm experiencing it with createTheme instead of usePagination @Kyhaiu did you get any closer to solving this?

Unfortunately I don't know how to solve this without copying the entire code of usePagination in my case. But, maybe I can help you, if you provide an example with error on codesandbox

Jonathan-Hofmann commented 1 year ago

I also get this error while using Mui Joy...

Where does the error come from

It appears to be an error inside the @mui/joy/styles/extendTheme (in my case). There seems to be an import outside of the module -> Babel Error? Why? I don't know. Maybe it is some error appearing only in combination with NextJS and Mui (Joy) (In my case).

My current Workaround

Working with NextJS and Mui Joy

My current Work-around is (as stupid as it sounds) to:

  1. Cut out all content related to Mui Joy.
  2. Save the page (in my case the .tsx file)
  3. Pasting the content back in
  4. Save again.

Voila it works again - Like Black magic πŸͺ„


Hope this error gets fixed at some point 🀫

TurtIeSocks commented 1 year ago

I believe this error is still happening.

Simple reproduction repo: https://github.com/TurtIeSocks/nextjs-mui-5.11

TurtIeSocks commented 1 year ago

@siriwatknp apologies if you're not the correct person to tag, just noticed that you're answering a lot of the MUI issues these days. Should I open a separate issue with the reproduction repo I posted above or keep it to this one?

Studio384 commented 1 year ago

I'm facing the same problem as @Jonathan-Hofmann mentions but with Vite/SSR. Their workaround is not a valid solution to me.

Kyhaiu commented 1 year ago

I apologize for the delay in responding. But so far, I am still using my workaround mentioned in my response to @daniel-boll. The last time I worked on this issue, I discovered that it may be related to the way Next 12 transpiles monorepos. However, even after migrating to version 13 and configuring external dependencies correctly (https://nextjs.org/docs/advanced-features/compiler#module-transpilation), I was unable to get rid of the error. However, as I mentioned earlier, the way I found to solve this problem was by copying the entire usePagination into the project. Below are the copied codes:

... I know the implications of doing this terrible work around, but idk how to solve this ;-; I hope that someday some good samaritan help us with this.

usePagination.js ```jsx import { unstable_useControlled as useControlled } from '@mui/utils'; const _excluded = [ 'boundaryCount', 'componentName', 'count', 'defaultPage', 'disabled', 'hideNextButton', 'hidePrevButton', 'onChange', 'page', 'showFirstButton', 'showLastButton', 'siblingCount', ]; function _extends() { // eslint-disable-next-line no-func-assign _extends = Object.assign ? Object.assign.bind() : function (target) { for (let i = 1; i < arguments.length; i++) { const source = arguments[i]; for (const key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; const target = {}; const sourceKeys = Object.keys(source); let key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } export default function usePagination(props = {}) { // keep default values in sync with @default tags in Pagination.propTypes const { boundaryCount = 1, componentName = 'usePagination', count = 1, defaultPage = 1, disabled = false, hideNextButton = false, hidePrevButton = false, onChange: handleChange, page: pageProp, showFirstButton = false, showLastButton = false, siblingCount = 1, } = props, other = _objectWithoutPropertiesLoose(props, _excluded); const [page, setPageState] = useControlled({ controlled: pageProp, default: defaultPage, name: componentName, state: 'page', }); const handleClick = (event, value) => { if (!pageProp) { setPageState(value); } if (handleChange) { handleChange(event, value); } }; // https://dev.to/namirsab/comment/2050 const range = (start, end) => { const length = end - start + 1; return Array.from( { length, }, (_, i) => start + i, ); }; const startPages = range(1, Math.min(boundaryCount, count)); const endPages = range(Math.max(count - boundaryCount + 1, boundaryCount + 1), count); const siblingsStart = Math.max( Math.min( // Natural start page - siblingCount, // Lower boundary when page is high count - boundaryCount - siblingCount * 2 - 1, ), // Greater than startPages boundaryCount + 2, ); const siblingsEnd = Math.min( Math.max( // Natural end page + siblingCount, // Upper boundary when page is low boundaryCount + siblingCount * 2 + 2, ), // Less than endPages endPages.length > 0 ? endPages[0] - 2 : count - 1, ); // Basic list of items to render // e.g. itemList = ['first', 'previous', 1, 'ellipsis', 4, 5, 6, 'ellipsis', 10, 'next', 'last'] const itemList = [ ...(showFirstButton ? ['first'] : []), ...(hidePrevButton ? [] : ['previous']), ...startPages, // Start ellipsis // eslint-disable-next-line no-nested-ternary ...(siblingsStart > boundaryCount + 2 ? ['start-ellipsis'] : boundaryCount + 1 < count - boundaryCount ? [boundaryCount + 1] : []), // Sibling pages ...range(siblingsStart, siblingsEnd), // End ellipsis // eslint-disable-next-line no-nested-ternary ...(siblingsEnd < count - boundaryCount - 1 ? ['end-ellipsis'] : count - boundaryCount > boundaryCount ? [count - boundaryCount] : []), ...endPages, ...(hideNextButton ? [] : ['next']), ...(showLastButton ? ['last'] : []), ]; // Map the button type to its page number const buttonPage = (type) => { switch (type) { case 'first': return 1; case 'previous': return page - 1; case 'next': return page + 1; case 'last': return count; default: return null; } }; // Convert the basic item list to PaginationItem props objects const items = itemList.map((item) => { return typeof item === 'number' ? { onClick: (event) => { handleClick(event, item); }, type: 'page', page: item, selected: item === page, disabled, 'aria-current': item === page ? 'true' : undefined, } : { onClick: (event) => { handleClick(event, buttonPage(item)); }, type: item, page: buttonPage(item), selected: false, disabled: disabled || (item.indexOf('ellipsis') === -1 && (item === 'next' || item === 'last' ? page >= count : page <= 1)), }; }); return _extends( { items, }, other, ); } ```
usePagination.d.ts ```ts import * as React from 'react'; export interface UsePaginationProps { /** * Number of always visible pages at the beginning and end. * @default 1 */ boundaryCount?: number; /** * The name of the component where this hook is used. */ componentName?: string; /** * The total number of pages. * @default 1 */ count?: number; /** * The page selected by default when the component is uncontrolled. * @default 1 */ defaultPage?: number; /** * If `true`, the component is disabled. * @default false */ disabled?: boolean; /** * If `true`, hide the next-page button. * @default false */ hideNextButton?: boolean; /** * If `true`, hide the previous-page button. * @default false */ hidePrevButton?: boolean; /** * Callback fired when the page is changed. * * @param {React.ChangeEvent} event The event source of the callback. * @param {number} page The page selected. */ onChange?: (event: React.ChangeEvent, page: number) => void; /** * The current page. */ page?: number; /** * If `true`, show the first-page button. * @default false */ showFirstButton?: boolean; /** * If `true`, show the last-page button. * @default false */ showLastButton?: boolean; /** * Number of always visible pages before and after the current page. * @default 1 */ siblingCount?: number; } export interface UsePaginationItem { onClick: React.ReactEventHandler; type: 'page' | 'first' | 'last' | 'next' | 'previous' | 'start-ellipsis' | 'end-ellipsis'; page: number | null; selected: boolean; disabled: boolean; } export interface UsePaginationResult { items: UsePaginationItem[]; } export default function usePagination(props: UsePaginationProps): UsePaginationResult; ```
ItsumoSeito commented 1 year ago

I was facing the same issue while using the MUI Joy library in Next.js

I tried adding the transpilePackages: ['@mui/muiComponentPackage'] config option in next.config.js but this didn't help.

What solved the issue for me was making sure I am importing the MUI components as named imports from the general @mui/joy package and not do default exports from e.g. @mui/joy/Select/Select

Guess the component packages (CommonJS) are exposed as ES modules in the higher packages and this removes the need for Babel to compile to older syntax which seems problematic here