Доступ к экспортированным функциям из HTML-файла - PullRequest
0 голосов
/ 04 мая 2018

Я играю с некоторыми ES6 функциями, используя Chrome v65

У меня есть следующие файлы:

base.js :

export function consoleLogger(message) {
    console.log(message);
}

main.js

import { consoleLogger } from './base.js';
consoleLogger('Some message');

utils.js

function sayMyName(name) {
    console.log(name);
}

imports.html

<!DOCTYPE html>
<html>
<head>
    <script src='./main.js' type='module'></script>
    <script src='./utils.js'></script>
</head>
<body>
    <script>
        sayMyName('Cool name');
    </script>
</body>
</html>

Используется вот так все вроде нормально, а в консоли я получаю

Классное имя utils.js: 2

Некоторые сообщения base.js: 2

Однако давайте представим сценарий, где мне нужны дополнительные данные, чтобы составить сообщение для метода consoleLogger. Тогда я хотел бы иметь что-то вроде этого в main.js

function logToConsole(msg) {
    consoleLogger(msg);
}

и import.html

<script>
    sayMyName('Cool name');
    logToConsole('Send from log to console');
</script>

затем для вызова logToConsole('Send from log to console'); в моем файле html в консоли я получаю:

Uncaught ReferenceError: logToConsole не определена at import.html: 10

Таким образом, нет проблем импортировать consoleLogger из base.js и вызывать его напрямую в main.js, нет проблем с включением другого файла .js (utils.js) и вызовом методов оттуда, но если Я пытаюсь вызвать метод, объявленный в main.js, который внутренне вызывает импортированный метод. Я получил ошибку сверху. Как кажется, даже не имеет значения, ссылается ли метод из main.js на импортированный метод или нет. Я просто все прокомментировал и оставил только один простой метод

main.js

import { consoleLogger } from './base.js';

/*function logToConsole(msg) {
    consoleLogger(msg);
}

consoleLogger('Some message');*/

function randomStuff() {
    console.log('random stuff');
}

и в консоли я получил эту ошибку:

import.html: 11 Uncaught ReferenceError: randomStuff не определен at import.html: 11

Может кто-нибудь объяснить мне причину такого поведения?

Ответы [ 4 ]

0 голосов
/ 04 мая 2018

Вы должны экспортировать функцию в main.js следующим образом:

export function logToConsole(msg) {

и затем вы можете импортировать его, используя

<script type="module"> встроенный скрипт с импортом внутри

см. https://jakearchibald.com/2017/es-modules-in-browsers/

будет выглядеть так:

<script type="module">
    import { logToConsole } from "./main.js";
    sayMyName('Cool name');
    logToConsole('Send from log to console');
</script>
0 голосов
/ 04 мая 2018

Одной из целей модулей ES (и модулей JS в целом) является предотвращение загрязнения глобального масштаба.

Экспорт модулей не должен попадать в глобальные рамки. Использование модулей обычно предполагает, что весь сторонний код находится в модулях. logToConsole('Send from log to console') идет к основному модулю.

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

window.logToConsole = function (msg) {
    consoleLogger(msg);
}

Как уже упоминалось в другом ответе, все еще может быть состояние гонки, потому что модули загружаются асинхронно. Скрипт следует отложить до тех пор, пока документ не будет готов - событие jQuery ready или собственный аналог:

<script>
document.addEventListener('DOMContentLoaded', () => {
    logToConsole('Send from log to console');
});
<script>
0 голосов
/ 04 мая 2018

Браузер интерпретирует logToConsole в imports.html как window.logToConsole, то есть ожидает, что эта функция существует в глобальном пространстве имен.

По умолчанию объекты в модуле es6 не помещаются в глобальное пространство имен при добавлении на страницу HTML.

Вы можете получить доступ к logToConsole, импортировав его явно в HTML:

<script type="module">
    import { logToConsole } from './main.js';

    sayMyName('Cool name');
    logToConsole('Got it');
</script>
0 голосов
/ 04 мая 2018

Вот из-за этой строки -

<script src='./main.js' type='module'></script>

скрипты с type="module" откладывают выполнение до тех пор, пока их зависимости не будут выполнены. А тем временем. Другие сценарии будут просто выполняться.

Что означает, что ваш

<script>
    sayMyName('Cool name');
    logToConsole('Send from log to console');
</script>

выполнится до того, как файл-скрипт модуля main.js будет разрешен и оценен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...