node --experimental-modules, requested module does not provide an export named

Viewed 64057

I've installed Node 8.9.1 (same problem happens in v10.5.0).

I'm trying to use named imports from npm packages in a file with the .mjs

import { throttle } from lodash;

I run:

node --experimental-modules index.mjs

and I get:

SyntaxError: The requested module 'lodash' does not provide an export named 'throttle' at ModuleJob._instantiate (internal/modules/esm/module_job.js:80:21)

--experimental-modules are supposed to stop being experimental in v10 LTS, so why haven't more module authors jumped on the bandwagon?

6 Answers

EDITED NEW (AND MUCH BETTER) ANSWER

The Node team is ... slow. Meanwhile, the same guy who brought us Lodash (John-David Dalton) imagined a brilliant solution, and his idea is the best way to get full ES6 module support in 2019.

(In fact, I want to delete my earlier answer, but I've left it for historical purposes.)

The new solution is SUPER simple.

Step #1:

npm i esm

(https://www.npmjs.com/package/esm for package details)

Step #2:

node -r esm yourApp.js

That's the entirety of it: it's really just that easy. Just add -r esm as a Node arg, and everything just magically works (it's even less typing than --experimental-modules!) Thank you John-David Dalton!!!

As I said in my original answer, presumably someday Node will finally release full ES6 support, but when that happens adopting it will be as easy as removing "-r esm" from a few scripts :D

Finally, to give credit where due, while I didn't find it through his answer, @Divyanshu Rawat actually provided an answer with the precursor to this library long before I made this update.

ORIGINAL ANSWER

--experimental-modules does not have support for named exports yet:

--experimental-modules doesn't support importing named exports from a commonjs module (except node's own built-ins).

This is why you are unable to use the syntax:

 import { throttle } from 'lodash';

Instead (for now at least) you have to destruct what you need:

 import lodash from 'lodash';
 const { throttle } = lodash;

Presumably someday Node will add support for all of the ES Module features.

I just had this error with nodejs express *.mjs file and --experimental-modules flag enabled for googleapis.

import { google } from "googleapis";

SyntaxError: The requested module 'googleapis' does not provide an export named 'google'

Solution

//not working!
//import { google } from "googleapis";

//working
import googleapis from "googleapis";
const { google } = googleapis;

I do not understand why this is the case; if anyone knows why, please comment.

You have to use .mjs extension.

Once this has been set, files ending with .mjs will be able to be loaded as ES Modules.

reference: https://nodejs.org/api/esm.html

Update:

Looks like you haven't export the method yet.

Suppose i have hello.mjs with content

export function sayHello() {
    console.log('hello')
}

i can use it in index.mjs like this

import {sayHello} from './hello.mjs'
sayHello()

For me loading lodash as ES Library did the job, here is the NPM Package for the same.

The Lodash library exported as ES modules. https://www.npmjs.com/package/lodash-es

Then you can import utils in normal way.

import { shuffle } from 'lodash-es';

If lodash had been written as modules, and lodash/index.mjs exported throttle: export const throttle = ...;, then you'd be able to import { throttle } from lodash;

The problem here is that in commonjs there's no such thing as a named export. Which means that in commonjs modules export one thing only.

So think that lodash exports an object containing a property named throttle.

For the second part of the question, I believe people will slowly start adopting ES Modules once it's not experimental anymore. At the time of this writing, it still is (Node.js v11.14).

@machineghost answer works. I remember also adding 'type':'module' to package.json along with using esm with node v12(LTS) and it worked fine.## Heading ##

I updated my node to v14(current) and I got an error

C:\Users\andey\Documents\Project\src\app.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: 
C:\Users\andey\Documents\Project\src\app.js
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1217:13) {
code: 'ERR_REQUIRE_ESM'
}

To fix it I had to remove 'type':'module' from package.json.

source

Related