Импорт ES2015 не работает (даже на верхнем уровне) в Firefox


90

Это мои образцы файлов:

<!DOCTYPE html>
<html>
<head>
  <title>Test</title>
  <script src="t1.js"></script>
</head>
<body></body>
</html>

t1.js:

import Test from 't2.js';

t2.js:

export const Test = console.log("Hello world");

Когда я загружаю страницу в Firefox 46, она возвращает «SyntaxError: объявления импорта могут появляться только на верхнем уровне модуля», но я не уверен, насколько более высокоуровневый оператор импорта может здесь получить. Является ли эта ошибка отвлекающим маневром, а импорт / экспорт еще просто не поддерживается?


2
Модули ES6 пока не поддерживаются в браузерах.
Felix Kling

2
Не верный Феликс. Даже в 2016 году. Не поддерживается всеми браузерами, точнее.
Andrew S

Ответы:


128

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

<script src="t1.js" type="module"></script>

Я нашел в этом документе об использовании импорта ES6 в браузере . Рекомендуемая литература.

Полностью поддерживается в этих версиях браузеров (и более поздних; полный список на caniuse.com ):

  • Firefox 60
  • Chrome (рабочий стол) 65
  • Chrome (android) 66
  • Safari 1.1

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

  • Chrome Canary 60 - за флагом Experimental Web Platform в chrome:flags.
  • Firefox 54 - dom.moduleScripts.enabledустановка в about:config.
  • Edge 15 - за настройкой Experimental JavaScript Features в about:flags.

1
Благодарность; похоже, это новая информация (сравните таблицу поддержки браузера в предыдущем ответе с developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ), поэтому я переключаюсь на ваш ответ, поскольку importон больше не поддерживается.
Christoph Burschka

1
теперь работает без каких-либо флагов / настроек в edge 16299 и chrome 64. Одно предостережение: нужно импортировать путь, а не файл, поэтому в t1.js: import Test from './t2.js';
Catweazle

@Catweazle Вы уверены, что это './t2.js'не './t2'без .js?
fredoverflow

@fredoverflow Да, необходимо указать полное имя, в отличие от Node.js.
Томаш Зато - Восстановите Монику

нужен полный пример, а не только импорт
bharal

14

Это уже не так. Все текущие браузеры теперь поддерживают модули ES6

Оригинальный ответ ниже

С importMDN :

В настоящее время эта функция изначально не реализована ни в каких браузерах. Он реализован во многих транспиляторах, таких как Traceur Compiler, Babel или Rollup.

Браузеры не поддерживают import.

Вот таблица поддержки браузера:

введите описание изображения здесь

Если вы хотите импортировать модули ES6, я бы посоветовал использовать транспилятор (например, babel ).


Можно ли включить эти функции с помощью флага (например, в Chrome)?
evolutionxbox

4
@evolutionxbox: Если функции не реализованы , то флага тоже нет.
Берги

1
Если функции не реализованы, почему я не получаю синтаксическую ошибку или ошибку, сообщающую мне, что они не реализованы? Это не имеет никакого смысла.
Томаш Зато - Восстановить Монику

@ TomášZato, просто зависит от того, какой браузер, который вы используете, решил справиться с этим
Джош Бим

1
На самом деле в моем коде была ошибка, и он работает нормально. Не знаю, почему за ваш ответ проголосовали. Браузеры, не поддерживающие импорт, сообщают об этом. Ошибки, подобные рассматриваемой, являются фактическими ошибками при использовании импорта.
Tomáš Zato - Reinstate Monica

2

Простое использование расширения файла .js при импорте файлов решило ту же проблему (не забудьте указать type="moduleв теге скрипта).

Просто напишите:

import foo from 'foo.js';

вместо того

import foo from 'foo';

1

Добавьте type=moduleскрипты, которые импортируют и экспортируют модули, чтобы решить эту проблему.


0

вы должны указать его тип в скрипте, и экспорт должен быть по умолчанию .. например, в вашем случае это должно быть,

<script src='t1.js' type='module'>

для t2.js используйте значение по умолчанию после такого экспорта , экспортируйте значение по умолчанию «здесь ваше выражение» (здесь нельзя использовать переменную) . вы можете использовать такую ​​функцию,

export default function print(){ return console.log('hello world');}

а для импорта ваш синтаксис импорта должен быть таким: импортируйте печать из './t2.js' (используйте расширение файла и ./ для того же каталога) .. Надеюсь, это будет полезно для вас!


0

Ради аргумента ...

Можно добавить пользовательский интерфейс модуля к глобальному объекту окна. Хотя это не рекомендуется. С другой стороны, DOM уже сломан и ничего не сохраняется. Я все время использую это для перекрестной загрузки динамических модулей и подписки на пользовательских слушателей. Вероятно, это не ответ, но он работает. У переполнения стека теперь есть module.export, который вызывает событие под названием Spork - по крайней мере, до обновления ...

//  spam the global window with a custom method with a private get/set-interface and     error handler... 

window.modules = function(){
  window.exports = {
    get(modName) {
      return window.exports[modName] ? window.exports[modName] : new Error(`ERRMODGLOBALNOTFOUND [${modName}]`)
    },
    set(type, modDeclaration){
      window.exports[type] = window.exports[type] || []
      window.exports[type].push(modDeclaration)

    }
  }

}

//  Call the method
window.modules()

//  assign a custom type and function
window.exports.set('Spork', () => console.log('SporkSporSpork!!!'))


// Give your export a ridiculous event subscription chain type...
const foofaalala = window.exports.get('Spork')

// Iterate and call (for a mock-event chain)
foofaalala.forEach(m => m.apply(this))

//  Show and tell...
window
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.