Using Node.js require vs. ES6 import/export

后端 未结 10 787
醉酒成梦
醉酒成梦 2020-11-22 05:19

In a project I\'m collaborating on, we have two choices on which module system we can use:

  1. Importing modules using require, and exporting using
相关标签:
10条回答
  • 2020-11-22 05:34

    There are several usage / capabilities you might want to consider:

    Require:

    • You can have dynamic loading where the loaded module name isn't predefined /static, or where you conditionally load a module only if it's "truly required" (depending on certain code flow).
    • Loading is synchronous. That means if you have multiple requires, they are loaded and processed one by one.

    ES6 Imports:

    • You can use named imports to selectively load only the pieces you need. That can save memory.
    • Import can be asynchronous (and in current ES6 Module Loader, it in fact is) and can perform a little better.

    Also, the Require module system isn't standard based. It's is highly unlikely to become standard now that ES6 modules exist. In the future there will be native support for ES6 Modules in various implementations which will be advantageous in terms of performance.

    0 讨论(0)
  • 2020-11-22 05:34

    Not sure why (probably optimization - lazy loading?) is it working like that, but I have noticed that import may not parse code if imported modules are not used.
    Which may not be expected behaviour in some cases.

    Take hated Foo class as our sample dependency.

    foo.ts

    export default class Foo {}
    console.log('Foo loaded');
    

    For example:

    index.ts

    import Foo from './foo'
    // prints nothing
    

    index.ts

    const Foo = require('./foo').default;
    // prints "Foo loaded"
    

    index.ts

    (async () => {
        const FooPack = await import('./foo');
        // prints "Foo loaded"
    })();
    

    On the other hand:

    index.ts

    import Foo from './foo'
    typeof Foo; // any use case
    // prints "Foo loaded"
    
    0 讨论(0)
  • 2020-11-22 05:44

    When it comes to async or maybe lazy loading, then import () is much more powerful. See when we require the component in asynchronous way, then we use import it in some async manner as in const variable using await.

    const module = await import('./module.js');
    

    Or if you want to use require() then,

    const converter = require('./converter');
    

    Thing is import() is actually async in nature. As mentioned by neehar venugopal in ReactConf, you can use it to dynamically load react components for client side architecture.

    Also it is way better when it comes to Routing. That is the one special thing that makes network log to download a necessary part when user connects to specific website to its specific component. e.g. login page before dashboard wouldn't download all components of dashboard. Because what is needed current i.e. login component, that only will be downloaded.

    Same goes for export : ES6 export are exactly same as for CommonJS module.exports.

    NOTE - If you are developing a node.js project, then you have to strictly use require() as node will throw exception error as invalid token 'import' if you will use import . So node does not support import statements.

    UPDATE - As suggested by Dan Dascalescu: Since v8.5.0 (released Sep 2017), node --experimental-modules index.mjs lets you use import without Babel. You can (and should) also publish your npm packages as native ESModule, with backwards compatibility for the old require way.

    See this for more clearance where to use async imports - https://www.youtube.com/watch?v=bb6RCrDaxhw

    0 讨论(0)
  • 2020-11-22 05:45

    Are there any performance benefits to using one over the other?

    Keep in mind that there is no JavaScript engine yet that natively supports ES6 modules. You said yourself that you are using Babel. Babel converts import and export declaration to CommonJS (require/module.exports) by default anyway. So even if you use ES6 module syntax, you will be using CommonJS under the hood if you run the code in Node.

    There are technical differences between CommonJS and ES6 modules, e.g. CommonJS allows you to load modules dynamically. ES6 doesn't allow this, but there is an API in development for that.

    Since ES6 modules are part of the standard, I would use them.


    Update 2020

    Since Node v12, support for ES modules is enabled by default, but it's still experimental at the time of writing this. Files including node modules must either end in .mjs or the nearest package.json file must contain "type": "module". The Node documentation has a ton more information, also about interop between CommonJS and ES modules.

    Performance-wise there is always the chance that newer features are not as well optimized as existing features. However, since module files are only evaluated once, the performance aspect can probably be ignored. In the end you have to run benchmarks to get a definite answer anyway.

    ES modules can be loaded dynamically via the import() function. Unlike require, this returns a promise.

    0 讨论(0)
提交回复
热议问题