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

SyntaxError: Cannot use import statement outside a module #4

Closed
deadcoder0904 opened this issue Aug 16, 2021 · 12 comments
Closed

SyntaxError: Cannot use import statement outside a module #4

deadcoder0904 opened this issue Aug 16, 2021 · 12 comments

Comments

@deadcoder0904
Copy link

I am trying to use fast-image-zoom in my React/Next.js app & I get the following error:

SyntaxError: Cannot use import statement outside a module
    at Object.compileFunction (node:vm:353:18)
    at wrapSafe (node:internal/modules/cjs/loader:1039:15)
    at Module._compile (node:internal/modules/cjs/loader:1073:27)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1138:10)
    at Module.load (node:internal/modules/cjs/loader:989:32)
    at Function.Module._load (node:internal/modules/cjs/loader:829:14)
    at Module.require (node:internal/modules/cjs/loader:1013:19)
    at require (node:internal/modules/cjs/helpers:93:18)
    at Object.fast-image-zoom (my-app\.next\server\pages\_app.js:20969:18)
    at __webpack_require__ (my-app\.next\server\webpack-runtime.js:25:42)
my-app\node_modules\fast-image-zoom\src\index.js:1
import styles from './styles'
^^^^^^

I've made a reproduction here -> https://stackblitz.com/edit/nextjs-edw9pk?file=pages%2F_app.js

You can uncomment the 2 lines in pages/_app.js to see the errors.

How can I solve it?

@miloxeon
Copy link
Owner

It's because of nextjs ssr. Fast-image-zoom is not a node module — it's a proper ES module, and nextjs lags behind.

You can solve it with a client-side import as you don't really need fast-image-zoom in ssr process in the first place — it solely relies on user interaction, and those don't occur during ssr.

@deadcoder0904
Copy link
Author

@mvoloskov I think Next solved ESM problem in the latest version v11.1.0 but I'll take a look :)

@deadcoder0904
Copy link
Author

@mvoloskov Can you give an example, how to solve it? I did stumble upon the same issue but as there are no examples I couldn't solve it :(

@miloxeon
Copy link
Owner

@deadcoder0904
Copy link
Author

Nope, I tried that it didn't work. Then I tried putting this code in _document.tsx:

async componentDidMount() {
	dynamic(() => import('fast-image-zoom').then((mod) => mod.imageZoom), { ssr: false })
}

But no luck :(

@miloxeon
Copy link
Owner

then just include fast-image-zoom as a script tag and call imageZoom() from the global namespace. It will work

@deadcoder0904
Copy link
Author

If I don't figure it out, I'll go that way. Personally, I like to keep all my code outside of index.html as I forget to check that file often :)

@miloxeon
Copy link
Owner

me too, but the only thing I can do is to provide a perfectly valid, standardized ES module. I'm willing to compile it to IIFE, because that's an old standard that is still alive, but I won't be making a separate version especially for nextjs ssr. It's their responsibility to make valid ES modules work, and it's a risk you take adopting nextjs.

@deadcoder0904
Copy link
Author

@mvoloskov will IIFE work? if so, then would love it as it would make the process easier but they just released ESM support so it should work. I'm not sure where to put it though so I'd wait a week before I find the answer :)

If I don't find it by then, I'll ping you to add CJS support :)

@miloxeon
Copy link
Owner

it's a purely frontend lib. CJS is not only a NodeJS defacto ad hoc, but an obsolete one, as modern NodeJS, as well as Deno, natively supports ES modules, which is a proper standard.

There will be no CJS support. ES modules are the way to go, though I keep IIFE around because including libs in script tags into global namespace is a standard too, and it's not yet obsolete.

When script type="module" support improves, I'll deprecate IIFE as well as Cosmopolite boilerplate, the one that fast-image-zoom is built upon.

@deadcoder0904
Copy link
Author

Oh yeah, got it. IIFE support would allow me to just import the library & it will work which is cool.

@deadcoder0904
Copy link
Author

Found the solution. Had to put this in _app.tsx:

import React from 'react';

function MyApp({ Component, pageProps }) {
  React.useEffect(() => {
    const loadImageZoom = async () => {
      const imageZoom = await import('fast-image-zoom').then(
        mod => mod.default
      );
      imageZoom();
    };
    loadImageZoom();
  }, []);
  return <Component {...pageProps} />;
}

export default MyApp;

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

No branches or pull requests

2 participants