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: Unexpected token 'export' #31518
Comments
This comment has been minimized.
This comment has been minimized.
The package is using ESModules which Next.js 12 supports out of the box, but it's probably missing something, maybe You should reach out to the third party package so they can investigate their bundling. |
@balazsorban44 I am speaking on behalf of amCharts. Our package does indeed use ES6 modules, and it works perfectly everywhere else: Webpack, Rollup, React, Angular, Vue, etc. This problem is exclusively with Next.js. It's possible to workaround it by transpiling amCharts like this: const withTM = require('next-transpile-modules')(['@amcharts/amcharts5'])
module.exports = withTM({}); But that shouldn't be necessary, everything should work out of the box. |
Check out our blog post https://nextjs.org/blog/next-12#es-modules-support-and-url-imports Next 12 prefers the standardized method. I can also recommend the Node.js docs around ESM: https://nodejs.org/docs/latest/api/esm.html If you are not ready yet, you can try to temporarily switch back to prefer CJS, using experimental: {
esmExternals: false
} in |
@balazsorban44 I don't see anything in that blog about Using As I said, if you are requiring This has nothing to do with ES6 vs CommonJS, our code uses 100% standard ES6 modules and has worked for years in every other build system. This is a Next.js specific issue. |
Next.js (in all versions) uses Node.js to execute code for SSR or in API routes. User code (code not in
Here is how to try itNeither
nor
It's not difficult to be Node.js compatible. You either write CommonJS modules or EcmaScript modules (ESM). To use ESM you need to follow the Node.js documentation here: https://nodejs.org/api/esm.html Build tools are usually less restrictive, as they want to be backward-compatible to ESM code that was written before the spec has been fully completed. Node.js follows the spec more strictly, similar to browsers where similar restrictions apply (
I can see that here: https://nextjs.org/blog/next-11-1#es-modules-support
Yep that notation origins from Node.js, but at least webpack also supports it to flag modules as ESM. Probably other tools too. Note that the HTML spec has something similar with
Next.js never supported ESM-only packages without
If you look at ESM in browsers (not sure which spec, probably HTML integration and Web APIs), they actually require to specified which resources are scripts and which are modules. And they also require file extensions. TL'DR: Next.js doesn't bundle node_modules before execution them on server side. They must be executable in Node.js. For ESM follow the Node.js ESM documentation.
|
Our code will never work in Node, because (like many thousands of other npm packages) it uses browser APIs like the DOM. It is a browser-only library. Next.js is a React framework, it is expected that most of the npm dependencies will be browser-only.
As you are aware, Webpack works perfectly fine without
That is up to the user, but
An ES6 module that does not use
Yes, but they do not use
Perhaps that makes sense for SSR, but if you require that for all npm packages (including browser-only npm packages) then you will break and fragment the entire ecosystem, because the vast majority of packages do not use And if you go even further and require strict Node.js compatibility (such as mandating a file extension) then you will break even more code, for example all TypeScript projects (because TypeScript has quite bad handling for file extensions). This will require massive changes to an incredible number of packages, despite those packages working perfectly fine in Webpack. In many cases it's not even possible to fix the problem, because the library author is no longer maintaining the package. Or perhaps the problem is in a dependency of a dependency of a dependency of a dependency. This "boil the ocean" strategy of trying to force everybody to change was tried before (with the |
To be clear, migrating to
This is a very large amount of work. None of our dependencies use Hypothetically, let's say we somehow manage to Nodeify our library and all our dependencies. If we add a new dependency, and that dependency isn't Nodeified, then it breaks all of our Next.js users. And if one of our dependencies adds a new transitive dependency which isn't Nodefied, it breaks all of our Next.js users. So in practice Next.js users will need to transpile almost every npm package, because most npm packages do not use This is a horrible user experience, and a horrible library author experience. None of the other frameworks have this problem: React, Angular, Vue, Svelte, Snowpack, Webpack, Rollup, etc. etc. etc. Here is one possible solution to this: when importing an npm package, check if it has a
Automatically transpiling packages is a far better experience compared to giving an error and forcing the user to manually transpile. |
If you don't want to or can't provide a Node.js compatible version of the library that's fine. There is a way to opt-out of SSR for parts of a Next.js application via
Maybe that wasn't clear from my first comment, but you can use ESM or CommonJS in Node.js. So there is no need to migrate all dependencies to ESM. They can also be in CommonJS. It's only a problem if they are only in ESM which is not Node.js compatible. Even if your library is ESM, your dependencies can be CommonJS. |
Just to chime in on this the build still failed for me even when dynamically importing. |
I tried it. Works fine for me. // pages/index.js
import dynamic from 'next/dynamic';
const Chart = dynamic(() => import('../components/Chart'), { ssr: false });
export default () => {
return (
<div>
<Chart />
</div>
);
}; and for |
I did try that initially and it was failing with the original error posted here, but tried again and seems to be working now, thank you |
You are misunderstanding the situation. This was never about ES6 vs CommonJS. All of our dependencies use ES6 modules. Our own code uses ES6 modules. We have used ES6 modules for several years. We have many years of experience with many build systems, because our customers use our library in many different situations. But because we don't use ES6 modules are very common on npm (I have personally seen far more ES6 libraries on npm compared to CommonJS libraries), and yet they do not work in Next.js (even though they work in every other build system). If Next.js is choosing to break 99+% of ES6 libraries on npm, that is something that really needs to be explained clearly in the documentation, or else you will get many complaints from users. Right now the documentation makes it seem like ES6 modules should work, even though they don't.
That is good to know, we will inform our customers about that. |
Actually that made me curious what the real numbers are here. So I wrote a script to run over the top 1000 most depended on packages with the following results: (The script isn't perfect, and might have a few false postive/negatives)
So the vast majority are CommonJs libraries. Only 110 packages contain ESM at all. For these 110 packages 65 of them also provide a CommonJS alternative. So only 45 packages are "only ESM". From that 45 packages 39 have indeed a
So there is only a single packages that will break |
I think you should run the script over the top 1000 most depended upon browser libraries. Next.js is a React framework, it is expected that most of the bundled dependencies would be browser-based libraries (such as React libraries). Most of the things you mentioned are build tools that are run at compile time, not code which is bundled with the application. You will need to exclude things which are put into devDependencies (like webpack) because they aren't bundled with the application. Of course devDependencies will be primarily CommonJS, because they're Node programs that are intended to be run in Node. But those are not the sorts of things which are being bundled by Next.js That's why I was speaking from my personal experience working on many npm projects, because I was taking into account which dependencies are actually being bundled with the package (and not just being run during compile time, like CLI tools). Those are the packages which actually cause build errors in Next.js, not the compile-time tools. So perhaps the most fair comparison in this situation would be to look at the top 100+ React libraries. That is extremely relevant for Next.js, because it is a React framework. And those libraries are usually bundled with the application. |
This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
What version of Next.js are you using?
12.0.4
What version of Node.js are you using?
12.22.0
What browser are you using?
Chrome @latest
What operating system are you using?
Windows 10
How are you deploying your application?
Manual
Describe the Bug
Nextjs is failing on build of a third party package. The third party package is using ES6 syntax for exports.
I appreciate this is perhaps more of an issue with the third party package but interested to know if there's a way I can support it in my build ?
Expected Behavior
Expectation is a smooth build regardless of syntax used
To Reproduce
Install latest nextjs and amcharts5 and run build
The text was updated successfully, but these errors were encountered: