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

[esm] avoid depending on require.main #6718

Closed
b12f opened this issue Nov 22, 2019 · 22 comments
Closed

[esm] avoid depending on require.main #6718

b12f opened this issue Nov 22, 2019 · 22 comments

Comments

@b12f
Copy link

b12f commented Nov 22, 2019

What problem does this feature solve?

ESM support just dropped in node 13.2.0, removing the need for a lot of babel transpiling.

What does the proposed changes look like?

There is at least one problem right now that is preventing me from using nuxt with node ESM:

Here,

https://github.com/nuxt/nuxt.js/blob/dev/packages/utils/src/resolve.js#L109

nuxt is trying to access require.main, which is not defined when starting a process with esm modules. This throws an error later when trying to access require.main.paths.

Temporary workaround would be to change the line to the following:

const getMainModule = () => require.main || { paths: [] };

And making people explicitly supply the modulesDir option

@ghost ghost added the cmty:feature-request label Nov 22, 2019
@pi0
Copy link
Member

pi0 commented Nov 24, 2019

@b12f Thanks for opening this issue! Actually nuxt was not using babel for ESM support but standard-thing/esm which has almost the same runtime implementation of the node with few enhancements for backward compatibility.

ESM support is not still in LTS and not the entire ecosystem is prepared for that. But could be a good idea start experimenting behind a flag :)

@aldarund
Copy link

aldarund commented Nov 27, 2019

ESM support is not still in LTS

And it wont be for quite of a time, since node 13 not going to be LTS

@MylesBorins
Copy link

We are hoping to backport to 12.x but are not 100% if we'll be able to yet.

@Jamesernator
Copy link

As of 12.16.0 the esm library no longer functions due to some backported ES module changes, see here. The library itself seems to be no longer maintained so it's unlikely this'll be fixed upstream.

Because of this anyone using >=12.6.0 can no longer use Nuxt+ESM and must either downgrade their code to commonjs, or downgrade their node version (if their setup supports it, some server setups don't).

@pi0
Copy link
Member

pi0 commented Feb 28, 2020

@Jamesernator Both CI and locally using (v12.13.1) I can still use ESM syntax for nuxt.config and serverMiddleware. Would you please elaborate more what's not working for you?

@Jamesernator
Copy link

locally using (v12.13.1)

This only affects >=12.16, 12.15 and earlier are unaffected.

Would you please elaborate more what's not working for you?

I was helping a friend debug their setup, basically the host auto updated to Node 12.16 which broke the server due to the aformentioned esm issue.

Instead of rewriting to CJS, I suggested trying it with --experimental-modules + "type": "module" in package.json. But this causes an error in Nuxt in the usage of getMainModule (here).

This happens because when the entry point is loaded as ESM process.mainModule is not set and thus getMainModule fails.

Now it's not completely dire because I did manage to find a workaround using createRequire and manually setting process.mainModule to a dummy module.

Given ESM syntax is used in the docs for Nuxt, and standard-things/esm doesn't work in 12.16 and beyond, I think Nuxt should consider supporting the native ESM in Node instead.

@nwittwer
Copy link

nwittwer commented Apr 25, 2020

As @Jamesernator alluded to, after updating to Node v12.16.2 I'm seeing errors in my nuxt.config.js when trying to use export, import, etc. This is after a fresh install of Nuxt (2.12.2).

Configuration:

  • Programming language: Javascript
  • Package manager: NPM
  • UI framework: none
  • Server: Express
  • Nuxt.js modules: Axios, PWA
  • Linting: ESLint, Prettier
  • Testing: Jest
  • Rendering mode: Universal (SSR)
  • Dev tools: jsconfig.json

UPDATE: Actually I'm getting the same issues even with Node 10.x and 12.13.

  • Cannot use import statement outside a module
  • Unexpected token 'export'

@nwittwer
Copy link

Following up from above: in my case the setup was the issue, not Nuxt core.

When using create-nuxt-app with the Express server install option, I run into the aforementioned issues. The template with Express doesn't seem to support ES modules? The nuxt.config.js still uses module.exports and will throw errors if you try to use ES modules.

Anyways, re-installing npx create-nuxt-app without Express fixed it. Tested in multiple versions of Node.

@Tzahile
Copy link

Tzahile commented Nov 20, 2020

So after long time with this issue...
Node v14 is LTS since the end of October, and it has ESM support out-of-the-box (adding "type": "module" in your package.json).
Lacking support for ESM, I encounter a Nuxt Fatal Error when trying to run my nuxt application after adding my express server, which uses esm syntax.

@pi0
Copy link
Member

pi0 commented Nov 20, 2020

Hi. Just as an update, we are working on next gen server for nuxt3 (backported to nuxt2) which is using RollupJS to bundle server-middleware and natively supports mjs. In the meantime you can migrate from esm to jiti by setting this in nuxt.config:

export default {
  createRequire: 'jiti'
}

Supporting mjs by adding a fallback for require.main would be possible but for serverMiddleware and nuxt.config, we cannot do HMR anymore since esm cache is not exposed.

kana added a commit to kana/hatokurandom that referenced this issue Dec 29, 2020
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
@FloEdelmann
Copy link
Contributor

FloEdelmann commented Jan 2, 2021

I tried the jiti workaround mentioned by @pi0 in OpenLightingProject/open-fixture-library@8b725cb (#1626), but I still get the same error as before:

[fatal] Must use import to load ES Module: /home/runner/work/open-fixture-library/open-fixture-library/nuxt.config.js
require() of ES modules is not supported.
require() of /home/runner/work/open-fixture-library/open-fixture-library/nuxt.config.js from /home/runner/work/open-fixture-library/open-fixture-library/node_modules/@nuxt/config/dist/config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename nuxt.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /home/runner/work/open-fixture-library/open-fixture-library/package.json.

  Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: nuxt.config.js
  require() of ES modules is not supported.
  require() of nuxt.config.js from /home/runner/work/open-fixture-library/open-fixture-library/node_modules/@nuxt/config/dist/config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
  Instead rename nuxt.config.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from package.json.
  
  at Object.Module._extensions..js (internal/modules/cjs/loader.js:1080:13)

It seems that "type": "module" in package.json is still not supported?

@danielroe @b12f Your reactions suggest that you managed to get ESM working with the workaround. What is the value of the type field in your package.json?

Copy link
Member

@FloEdelmann It works for me with node 14, nuxt-edge and type: 'module' 🙂

@pi0
Copy link
Member

pi0 commented Jan 14, 2021

@FloEdelmann You might need to use latest nuxt-edge with jiti 1.x which leverages native resolve for exports field (and createRequire is no longer needed)

@FloEdelmann
Copy link
Contributor

FloEdelmann commented Jan 15, 2021

I tried with nuxt-edge now and indeed I get a step closer 😅

  1. I use import.meta.url inside nuxt.config.js and a module which is imported from there. I get this error: SyntaxError: Cannot use 'import.meta' outside a module
  2. After replacing that with __dirname, I get this error: Cannot import module '@nuxt/builder-edge'
  3. After running npm install @nuxt/builder-edge, I get this warning:
(node:13594) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at getCLI (…/node_modules/@nuxt/telemetry/dist/index.js:260:30)
    at createContext (…/node_modules/@nuxt/telemetry/dist/index.js:239:10)

Also, I get UnhandledPromiseRejectionWarning: ReferenceError: __dirname is not defined errors of course in the module mentioned in step 1.

But apart from that, it seems to work.

Copy link
Member

@FloEdelmann Is this still an open issue for you? Do make sure your jiti version is up-to-date. I'm able to use import.meta within nuxt.config and dependencies with no issues.

@FloEdelmann
Copy link
Contributor

FloEdelmann commented Mar 8, 2021

@danielroe import.meta.url works fine now, with jiti manually updated to v1.6.0.

The telemetry error still remains though:

(node:13594) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at getCLI (…/node_modules/@nuxt/telemetry/dist/index.js:260:30)
    at createContext (…/node_modules/@nuxt/telemetry/dist/index.js:239:10)

Copy link
Member

@FloEdelmann Could you provide a reproduction? I can't reproduce the telemetry error you're talking about.

@FloEdelmann
Copy link
Contributor

Could you provide a reproduction?

@danielroe It happens for me in https://github.com/OpenLightingProject/open-fixture-library/tree/esm, when running npm run dev, but not when running npm run build && npm run start.
I suspect it happens because Nuxt is used programmatically there: https://github.com/OpenLightingProject/open-fixture-library/blob/esm/main.js#L145-L159

Copy link
Member

@FloEdelmann Just checking out https://github.com/OpenLightingProject/open-fixture-library/tree/esm-2 - seems to be working now?

@FloEdelmann
Copy link
Contributor

@danielroe It is working, but it still gives the same warning:

(node:13594) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'filename' of undefined
    at getCLI (…/node_modules/@nuxt/telemetry/dist/index.js:260:30)
    at createContext (…/node_modules/@nuxt/telemetry/dist/index.js:239:10)

Copy link
Member

@FloEdelmann Ah. Looks like this is purely an issue with @nuxt/telemetry, not Nuxt itself. I'm closing this issue but raising an issue there instead: nuxt/telemetry#49. Thanks for your help finding this one out!

@pi0 pi0 changed the title Update nuxt to work with the new esm import syntax [esm] avoid depending on require.main May 17, 2021
@pi0
Copy link
Member

pi0 commented May 17, 2021

Issue with telemetry should be fixed in latest release (https://github.com/nuxt/telemetry/releases/tag/v1.3.4) you can update by recreating lockfile or npm up nuxt / yarn upgrade nuxt. Also created #9302 to track esm compatibility issues.

floresarmida added a commit to floresarmida/hatokurandom that referenced this issue Dec 22, 2021
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
redhawkIT added a commit to redhawkIT/hatokurandom that referenced this issue Dec 22, 2021
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
mixazizup added a commit to mixazizup/hatokurandom that referenced this issue Jul 13, 2022
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
tylerc2023 added a commit to tylerc2023/hatokurandom that referenced this issue Sep 8, 2022
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
stevanovicmilan839 added a commit to stevanovicmilan839/hatokurandom that referenced this issue Nov 2, 2022
The actual error message was:

>  ERROR  Must use import to load ES Module: /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js
> require() of ES modules is not supported.
> require() of /Users/kana/working/hatokurandom/node_modules/lodash-es/lodash.js from /Users/kana/working/hatokurandom/lib/utils.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
> Instead rename lodash.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/kana/working/hatokurandom/node_modules/lodash-es/package.json.

According to nuxt/nuxt#6718 (comment)

> Hi. Just as an update, we are working on next gen server for nuxt3
> (backported to nuxt2) which is using RollupJS to bundle
> server-middleware and natively supports mjs. In the meantime you can
> migrate from esm to jiti by setting this in nuxt.config:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants