gatsby: gatsby-node.js doesn't allow ES6 import
Description
gatsby-node.js doesn’t allow ES6 javascript.
Steps to reproduce
gatsby-node.js:
import myOnCreatePage from './gatsby/node/onCreatePage';
export const onCreatePage = myOnCreatePage;
Expected result
gatsby-node.js should be transpiled and allow ES6 like gatsby-ssr.js or gatsby-browser.js.
Actual result
Error
Error: <root>/gatsby-node.js:1
SyntaxError: Unexpected token import
Environment
System:
OS: macOS High Sierra 10.13.6
CPU: x64 Intel(R) Core(TM) i7-6567U CPU @ 3.30GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 8.10.0 - ~/.nvm/versions/node/v8.10.0/bin/node
Yarn: 1.9.4 - /usr/local/bin/yarn
npm: 6.4.1 - ~/.nvm/versions/node/v8.10.0/bin/npm
Browsers:
Chrome: 68.0.3440.106
Firefox: 61.0.2
Safari: 11.1.2
npmPackages:
gatsby: next => 2.0.0-rc.5
gatsby-source-filesystem: next => 2.0.1-rc.1
npmGlobalPackages:
gatsby-cli: 1.1.58
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 13
- Comments: 52 (23 by maintainers)
Commits related to this issue
- Enable importing ESM modules from gatsby-node.js See https://github.com/gatsbyjs/gatsby/issues/7810#issuecomment-449741977 — committed to erikthedeveloper/erikaybar.name-gatsby by erikthedeveloper 5 years ago
- Añade compatibilidad con ES6 Gatsby no permite incluir importaciones en su fichero Node. Esta solucíón está sacada de un hilo de Github https://github.com/gatsbyjs/gatsby/issues/7810#issuecomment-449... — committed to ardillan/torlavega by ardillan 5 years ago
I use esm for this and it works so far. Here’s what I did:
esm(npm i esm)gatsby-node.esm.jsin your root folder (the same folder that containsgatsby-node.js)gatsby-node.jstogatsby-node.esm.jsgatsby-node.jswith the following:importingatsby-node.esm.jsall you want 🎉@KyleAMathews Is there anything dangerous about doing it this way? Because if it’s safe I could add it to the docs 😃
It’s kind of a different debate, but any chance using
importcould be supported out of the box? I feel like for larger Gatsby projects, what happens ingatsby-node.jsis almost as important as your actual front-end and it sucks not to be able to code in a modern way withimport,async/await, etc. without extra hacks.Now that ES modules are no longer experimental, should this issue be reopened?
npm i esmand then modify your commands to look like this:
https://github.com/wesbos/awesome-uses/blob/master/package.json#L39-L42
I was able to resolve my issue by using ES5 in my
src/utils/article.jsfile, like so:and then
gatsby-node.js, like this:I can also import
createArticleUrllike normal in ES6 files,import { createArticleUrl } from '../utils/article'.They are still experimental and not quite finished. Just the flag has been removed
I dove deep into this, and imo it’s not worth the pain yet. Wait for loaders to be implemented or use
esmpackage.I would strongly consider adding that esm approach to documentation, since Gatsby is indicating es6 modules should work inside gatsby-node.js file. This error message is printed, when you mix modules:
error This plugin file is using both CommonJS and ES6 module systems together which we don't support. You'll need to edit the file to use just one or the other.It clearly indicates, you CAN use es6 modules.
Can someone provide a final solution and lock this thread?
Hate doing this dance of skimming all comments in really important but seemingly closed issues where conversation is still happening and trying to sift through all comments to see which one has the most thumbs ups and is likely to be the best solution 😔
As an alternative, you may want to use TypeScript for
gatsby-*files.Is there a way to use
babel-nodeinstead ofnode?Man, what a welcoming community Gatsby has. A user asks for something basic (like support for the JS language) and this is the response they get.
Sure, but asking a fully working ESM-using app to rename all its files just to use modern JS syntax is complete idiocy.
Again, the Node org provided options for a reason, and my only concern was making sure Gatsby supports those options (or better yet, supports the
esmpackage … but that doesn’t sound like it’s happening). And again, I only said anything because you yourself carved out the possibility of not doing so:(which clearly implies not supporting the other option)
Another way I found this to work was by updated your package.json with the following:
No need to create new files
Just got bitten by this but in
gatsby-node.js. I am not a javascript developer so I don’t care much about ideology, but the ESM import syntax seemed so natural to me (I’m more experienced in Python, which has a very close import syntax) that I thought it was native to modern JS. I just want to extend Gatsby to my needs, and it feels very weird when you can use ESM everywhere in Gatsby (it’s even the format used in the documentation) but not in some specific files at the root.Whatever is your ideology, I think we can agree consistency is always a good practice. And here the import format is inconsistent within gatsby.
The
.mjsextension is hot garbage. Please don’t force every Gatsby developer to use it: the Node org added the other options precisely because of all of the fallback from the Node’ orgs misguided attempt to make everyone use “Michael Jackson Script”.P.S. A few relevant details that you might not be aware of …
package.jsonentry for theesmpackage, and the lines:This module is already widely used in major libraries like Knex. There are literally 135 … thousand libraries depending on it already!
It was written by the creator of Lodash, so this is not some Junior Engineer’s first NPM project: it’s a serious library written by a seasoned professional
It’s completely backwards-compatible: unless someone uses
importorexportin their non-ES Module code (and I’m pretty sure those have been JS banned keywords since the dawn of time) all existing code will continue working the sameif there was any kind of performance concern it’s trivially easy to “gate keep” this feature with a command line argument (
knexopted to go this route, for instance)So it’s “gain modern Javascript language features with three lines of code” or … fight it for ? benefit.
If there’s interest, I’d be more than happy to submit a PR 😃
Wow, I understand change is hard, but ES Modules are Javascript now, so it’s really disappointing to see (for whatever totally valid reasons) the maintainers fighting against supporting Javascript … especially when JDalton and his
esmpackage makes it so easy!mjs is going to be needed in some cases where you have a massive commonjs project. You can’t just snap your fingers and have the thing swich over. you need to do it bit by bit, and opting into esm on a per file basis is a good solution until you can get there.
I realize it’s an ugly extension (?) and it’s funny to say michael jackson script, but that is a good option going forward
@wesbos @reaktivo are you able to use that fix still with the latest gatsby (2.22.17 in my case)?
I’ve had it working without any issues using that solution, but updated gatsby today and started getting the import errors again:
I’m also running into this. I need to use
gatsby-mdx/mdx-renderer, and even if Irequireit, the required file itself uses ES6 module syntax and breaks. Is there a way to change configuration to havegatsby-node.jsgo through babel? It would be cool to be able to use JSX inside it as well, though less urgent for me.It’s not worth implementing the esm module into Gatsby - that is a great solution for now, but the future is using native esm in Node by either:
"type": "module"inpackage.json, allowing up to use the import syntax in gatsby-node.mjsfor gatsby-node.jsWe will have some growing pains as node moves to esm and we wait for lots of packages to catch up, but as long as authors know that as well at the node version limitations, we should be able to at least use
.mjsAny word from maintainers on this subject, please?
Just a heads up that I struggled with this for an hour and finally figured out that no matter what I put in my package.json for build, the Netlify UI configuration was taking precedence. It wasn’t until I added a netlify.toml that this became apparent. Moral of the story, edit your Netlify UI build settings, or clear them out and toss it in the config. I prefer the latter. 😄
It’s worth noting that yes, this worked for me:
Please have in mind that we don’t officially support it and the workarounds mentioned here can only go so far. Maybe some of our packages are not yet compatible with this experimental node feature or it just won’t work. We can revisit this topic when things are stable.
@rotexhawk Just pushed an example and it worked fine:
https://github.com/reaktivo/gatsby-esm/ https://gatsby-esm-example.netlify.com/
Make sure you’re running
npm install --save-dev esmbefore and that your build config runsnpm run buildinstead ofgatsby buildCheck out this commit: https://github.com/reaktivo/gatsby-esm/commit/cf620259ac8b118dea38b99409963cb26bf1b240
this also worked for me!
make sure to install the package first:
yarn add esmpackage.json
gatsby-config
gatsby-node
Like I said, the hard part is not making the
esmmodule work: it’s designed to make things extremely simple. I would submit a PR myself if I knew anything about the Gatsby architecture (and again, to see another major library use it just look at Knex).The hard part is just getting a maintainer with that knowledge to care 😦
You’d think that even if every maintainer had a personal hated for modern JS module syntax, they still could at least appreciate their users’ desire for it … but the refusal to even re-open this issue, let alone fix it (again, possibly with only two lines of code) suggests otherwise. Given how great this team has been with other issues, it’s honestly confusing to me.
@rotexhawk That’s really weird, considering the project that I sent you was deployed to Netlify… anyway, if you need to avoid
npx, the following might work:oops @alishaevn did you mean
yarn add esm? It’s cool that I learned about https://www.npmjs.com/package/ems though.@wesbos I ended up reverting back to es5 require for now 😦
EDIT: I just noticed your latest fix here https://github.com/gatsbyjs/gatsby/issues/24925 … I’ll give that a try!
my esm trick above just stopped working. I even rolled back gatsby and node version and it persists.
Detailed it here if anyone has the same issue: https://github.com/reaktivo/gatsby-esm/issues/1
@caycecollins did you find a fix?
@rotexhawk Got in touch with the Netlify team, you might also need to specify the NPM_VERSION, see https://www.netlify.com/docs/build-settings/#node-npm-and-yarn
@reaktivo your scripts work locally but I wasn’t able to get it to work with netlify. Are u able to deploy your site to netlify with
npx?