Импорт 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.