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:导入声明可能仅出现在模块的顶层”-但我不确定import语句可以在此处获得多少顶层。此错误是红色鲱鱼吗,并且尚不支持导入/导出吗?


2
浏览器尚不支持ES6模块。
菲利克斯·克林

2
不是真的菲利克斯。甚至在2016年也不会。“所有”浏览器不支持会更准确。
Andrew S

Answers:


128

实际上,您得到的错误是因为您需要明确声明您正在加载模块-只有在这种情况下,才允许使用模块:

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

我在本文档中找到有关在浏览器中使用ES6导入的信息。推荐阅读。

这些浏览器版本(及更高版本;在caniuse.com上的完整列表)完全受支持:

  • Firefox 60
  • Chrome(台式机)65
  • 铬(android)66
  • Safari 1.1

在较旧的浏览器中,您可能需要在浏览器中启用一些标志:

  • Chrome Canary 60-在中的“实验性网络平台”标志后面chrome:flags
  • Firefox 54 –中的dom.moduleScripts.enabled设置about:config
  • Edge 15 –在中的“实验JavaScript功能”设置之后about:flags

1
谢谢; 这似乎是新信息(将先前答案的浏览器支持表与developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…进行比较),所以我切换到您的答案,因为import不再支持。
Christoph Burschka '17

1
现在可以正常工作,在边缘16299和chrome 64中没有任何标志/设置。一个警告需要导入路径,而不是文件,因此在t1.js中: import Test from './t2.js';
Catweazle

@Catweazle您确定吗?'./t2.js'不是'./t2'没有.js吗?
fredoverflow

@fredoverflow是的,必须指定全名,这与Node.js不同。
托马什Zato -恢复莫妮卡

需要一个完整的例子,而不仅仅是进口
巴尔(Bharal)18-10-10

14

这不再准确了。 现在所有当前的浏览器都支持ES6模块

下面的原始答案

来自importMDN

目前,任何本地浏览器均未实现此功能。它在许多编译器中实现,例如Traceur编译器,Babel或Rollup。

浏览器不支持import

这是浏览器支持表:

在此处输入图片说明

如果要导入ES6模块,建议使用编译器(例如babel)。


您可以使用标志(例如Chrome)打开这些功能吗?
evolutionxbox

4
@evolutionxbox:如果功能存在,则也没有标志。
Bergi 2016年

1
如果未实现功能,为什么我没有收到语法错误或错误提示我未实现这些功能?这是没有道理的。
托马什Zato -恢复莫妮卡

@TomášZato,仅取决于您使用的浏览器决定如何处理它
Josh Beam

1
实际上,我的代码中有一个错误,并且工作正常。不知道为什么您的答案被否决了。不支持导入的浏览器会报告。像所讨论的那样的错误是使用导入的实际错误。
托马什Zato -恢复莫妮卡

2

在导入文件时仅使用.js文件扩展名即可解决相同的问题(请不要忘记type="module在script标签中进行设置)。

只需写:

import foo from 'foo.js';

代替

import foo from 'foo';


0

您必须在脚本中指定其类型,并且导出必须默认为..for,例如,

<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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.