ES modules ES10 - garevna/js-course GitHub Wiki

Теперь у нас есть выбор между статическим ( import ) и динамическим ( import() ) импортом

🎓 Dynamic import

ES10 ( 2019 )

Динамический импорт представлен новой функцией import(), возвращающей промис

Строго говоря, import() не является функцией в смысле наследования от Function, это вообще не объект

☕ 1

Запустите в консоли Chrome следующий код:

document.body.onclick = async () => {
    const module = await import(`https://garevna.github.io/js-samples/js/index12.js`)
}

📌 Примечательно то, что в файле index12.js нет директивы export

Однако импорт сработал, и скрипт запустился

☕ 2

В этом примере скрипты импортируются динамически, последовательно, с задержкой в несколько секунд

let scriptFile = 'https://garevna.github.io/js-samples/js/index'

import ( `${scriptFile}12.js` )
    .then( module => {
        setTimeout (
            () => import ( `${scriptFile}21.js` )
                .then (
                    setTimeout (
                        () => import ( `${scriptFile}22.js` ),
                        10000
                    ),
                    20000
                ),
            10000
        )
    })

Используем асинхронную функцию для упрощения кода:

const scriptImports = async moduleFile => {
    const timeOut = timeInterval => new Promise (
        resolve => setTimeout ( () => resolve(), timeInterval )
    )
    await import ( `${moduleFile}12.js` )
    await timeOut ( 8000 )
    await import ( `${moduleFile}21.js` )
    await timeOut ( 12000 )
    await import ( `${moduleFile}22.js` )
}

scriptImports ( 'https://garevna.github.io/js-samples/js/index' )

☕ 3

Предположим, в разметке мы подключили скрипт index.js

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ES Modules</title>
</head>

<body>
    <script src = "js/index.js"></script>
</body>

</html>

Код файла index.js создает элемент <script> с атрибутом type = "module" и вставляет его на страницу

let mod = document.body.appendChild (
  document.createElement ( "script" )
)
mod.type = "module"

В элемент <script> помещается код, который импортирует функцию showMessage из файла js/testESModules.js

и вызывает ее с текстом "Hi, students! Welcome to new age of ES Modules!"

mod.textContent = `
    import {showMessage} from './js/testESModules.js';
    showMessage ( "Hi, students! Welcome to new age of ES Modules!" )
`

Полный код:

js/index.js
let mod = document.body.appendChild (
  document.createElement ( "script" )
)
mod.type = "module"
mod.textContent = `
    import {showMessage} from './js/testESModules.js';
    showMessage ( "Hi, students! Welcome to new age of ES Modules!" )
`

Именованый экспорт в файле js/testESModules.js

js/testESModules.js
export function showMessage ( message ) {
    var demo = document.createElement ( 'div' )
    demo.style = `
        position: fixed;
        top: 15%; left: 15%;
        bottom: 15%; right: 15%;
        box-shadow: 10px 10px 16px #00000090;
        border: solid 0.5px #bbb;
        padding: 30px;
        z-index: 300;
        background-color: #000;
    `
    document.body.appendChild ( demo )
    demo.innerHTML = `
        <h2 style='color: #789'>Module was successfully imported</h2>
        <p style='color: #fa0'>Now you can see how it works :)</p>
        <hr>
        <p style='color: #dde'>${message}</p>
    `
    setTimeout ( () => {
        document.body.removeChild ( demo )
    }, 10000 )
}

⚠️ При импорте модулей следует указывать или полный путь

import {showMessage} from 'https://example.com/js/testESModules.js';

или относительный путь, начинающийся с /, ./ или ../

import {showMessage} from './js/testESModules.js';

В противном случае импорт завершится неудачей

☕ Live demo

⚠️ **GitHub.com Fallback** ⚠️