Каков эффект ключевого слова await при импорте модулей ESM

#node.js #es6-modules

#node.js #es6-модули

Вопрос:

Node.js документация crypto module docs использует верхний уровень await для импорта, но это явно не динамический импорт

источник: https://nodejs.org/dist/latest-v15.x/docs/api/crypto.html#crypto_static_method_certificate_exportchallenge_spkac_encoding

В чем разница между приведенными ниже 2 утверждениями (похоже, они делают то же самое)

 import * as fs from 'fs'
const fs_ = await import('fs');        // why use this?
 

Комментарии:

1. » но это явно не динамический импорт «, что вы имеете в виду? import() всегда является динамическим.

2. import(lib) возвращает обещание await import(lib) , возвращает библиотеку (например import * as lib from 'lib' )

3. Я знаю. Вот почему я сказал, что import() это всегда динамично. Синтаксис, не похожий на функцию, всегда статичен.

4. Я полагаю, что это просто синтаксический сахар, чтобы иметь синтаксис, подобный модулю CJS, в ESM, но я действительно не уверен

5. Динамический импорт решается иначе, чем статический. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference /…

Ответ №1:

[Не дублировать]

  • Await import() импортирует модуль EC статически (вместо import() динамического импорта), он очень похож на синтаксис модуля CommonJS require() , это единственная цель ключевого слова await верхнего уровня

Поддерживается: (node.js 14.8.0) (chrome 89) (Firefox 89) на момент написания этой статьи

  • Так зачем его использовать, если у нас уже есть все эти красивые синтаксисы статического импорта? (например: import * as imp from './someModule.mjs )
  • Ну, его проще писать и легче запоминать (например: await import('./someModule.mjs') статически требуется ‘SomeModule’ и возвращает его экспортированные данные как {default:'someDefVal'[, ...]} объект
 // static import -----------------------------------// blocks this module untill './module1.mjs' is fully loaded 
  // traditional static import in EC modules 
    import * as imp from './module1.mjs'; 
    console.log( imp );                             // -> {default:'data from module-1'}
    
  // static import with await import() (does the same as above but is prettier) 
    console.log( await import('./module1.mjs') );   // -> {default:'data from module-1'}
    
    function importFn1(){                           // the await import() is a satic import so cannot be used in a function body
        // await import('./module1.mjs');           // this would throw a SyntaxError: Unexpected reserved word 
    }
    
    
// dynamic import ----------------------------------// does not block this module, the './module2.mjs' loads once this module is fully loaded (not asynchronous)
    import('./module2.mjs') 
        .then((res)=>{ console.log(res) })          // -> {default:'data from module-2'}
        .catch((err)=>{ console.log(err) });
        
    (function ImporFn2(){
        import('./module2.mjs')                     // dynamic import inside a function body 
            .then((res)=>{ console.log(res) })      // -> {default:'data from module-2'}
            .catch((err)=>{ console.log(err) });
    })();
    
    console.log( '----- MAIN MODULE END -----' );
 
  • результат в консоли
 { default: 'data from module-1' }
{ default: 'data from module-1' }
----- MAIN MODULE END -----
{ default: 'data from module-2' }
{ default: 'data from module-2' }