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

前端 未结 6 1937
孤街浪徒
孤街浪徒 2020-12-05 06:51

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



        
相关标签:
6条回答
  • 2020-12-05 07:00

    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).

    0 讨论(0)
  • 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).

    • https://github.com/apollographql/graphql-tools/issues/913

    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.

    0 讨论(0)
  • 2020-12-05 07:06

    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.

    0 讨论(0)
  • 2020-12-05 07:11

    @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

    0 讨论(0)
  • 2020-12-05 07:16

    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';
    
    0 讨论(0)
  • 2020-12-05 07:17

    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()
    
    0 讨论(0)
提交回复
热议问题