Импорт JS из тега скрипта в HTML-файл. Возможный?

Я хочу получить доступ к данным из тега скрипта в HTML-файл, созданный с помощью CMS. Можно ли сделать это, не загрязняя глобальное пространство имен? Я пытался использовать модули es6, но мне не удалось, и я не мог найти информацию об этом.

    <script>
        let list = ['a','b','c'];
        export default list
    </script>
    //test.js
    import list from './index.html' 

Ошибка: ' http://localhost:8080/index.html net:: ERR_ABORTED 404' или: 'Не удалось загрузить скрипт модуля: сервер ответил не MIME-типом JavaScript-типа "text/html". Строгая проверка типов MIME обязательна для скриптов модулей в соответствии со спецификацией HTML. '

5 ответов

Нет, на это пока не распространяется спецификация HTML (и я подозреваю, что это никогда не будет). (Если бы это было, вам все равно нужно type="module" в вашем первом теге скрипта.) Там нет спецификатора модуля, который определяет элемент скрипта на странице HTML. На данный момент единственными спецификаторами модуля являются URL для файлов JavaScript. Подробности в спец.

Вместо этого вы, вероятно, хотите что-то вроде этого:

<script type="module">
import { setList } from "./test.js";
setList(['a', 'b', 'c']);
</script>

...где test.js экспортирует именованный экспорт, который позволяет указать, какой список использовать.

(Или, конечно, это может быть экспорт по умолчанию.)

В соответствии script type="module" теги могут import, но пока они могут использовать exportничто не может использовать экспорт, который они создают, потому что у них нет полезного спецификатора модуля.


Spec Это спецификация HTML, потому что форма и семантика спецификаторов модуля оставлены для хост-среды спецификацией JavaScript (подробности здесь). Все, что спецификация JavaScript говорит о них, это то, что они строковые литералы.

² Конечно, это может быть, например, использование идентификаторов фрагментов. Но благодаря мультиплексированию HTTP/2, делающему загрузку дискретных ресурсов столь быстрым по сравнению с HTTP/1.1 (и особенно против HTTP/1.0), стимул сделать все, что содержится в одном ресурсе, теперь значительно ниже, чем это было несколько лет назад.

Вы не можете экспортировать JS из HTML. Однако вы можете импортировать его, используя type="module" атрибут на <script> тег:

<script type="module">
  import list from "./test.js";
  //Use list
</script>

Я тоже задал себе тот же вопрос и нашел вашу тему. Но тут на ум пришло простое решение.

// buffer.js
    export default let buffer={};
// index.html
<script type="module">
    import buffer from './buffer.js';
    buffer.helloWorld='hello world';
</script>
....
<script type="module">
    import buffer from './buffer.js';
    console.log(buffer.helloWorld);
</script>

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

Тег сценария создает новый тег сценария в dom с помощьюtype = module, который импортирует объект, содержащий каждую функцию. Для каждой функции мы запускаем window.myFunction = myFunction, чтобы их можно было использовать из dom.

HTML:

      <script>
    ((path = "./importme.js", fileId = "importme") => {
        if (document.getElementById(fileId)) return;
        let tag = document.createElement("script");
        tag.type = "module";
        tag.id = fileId;
        tag.innerHTML =
            'import codeFromFile from "' +
            path +
            '"; Object.keys(codeFromFile).forEach(k => { window[k] = codeFromFile[k] });';
        document.body.appendChild(tag);
    })();
</script>
<button onclick="testFunction()">Click me</button>

./importme.js

      function testFunction() {
    alert("Test Function");
}

export default { testFunction };

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

HTML:

      <script>
    ((src = "/importme.js", fileId = "importme") => {
        if (document.getElementById(fileId)) return;
        let tag = document.createElement("script");
        tag.id = fileId;
        tag.src = src;
        document.body.appendChild(tag);
    })();
</script>
<button id="click">Click me</button>

./importme.js (оберните все в экспортированную анонимную функцию)

      window.onload = () => {
    document.getElementById('click').onclick = e => {
        alert('Element clicked!');
    };
};

Это плохой способ действий, только для наихудшего сценария. Этот ответ дает пищу для размышлений, пожалуйста, не делайте этого... В конце концов моя компания нашла способ обойти это.

Вы можете просто использовать глобальную переменную следующим образом:

  • В вашем HTML-файле:
       <script>var myGlobalVar = "foo";</script>
  • In your JS file before enqueuing your script:
      /* global myGlobalVar */

alert(myGlobalVar);

Затем вы можете использовать свою переменную в файле JS.

Другие вопросы по тегам