Babel.js使用导入和导出无法正常工作

时间:2017-05-09 00:31:32

标签: javascript import export babeljs

我尝试使用导入和导出来创建模块,但它无法正常工作。

我将https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js添加到index.html标头并尝试导入js文件并收到一条错误消息,指出SyntaxError:import声明可能只出现在模块的顶层。我可能做错了什么?

我知道我可以使用require.js,而是使用import和export。

HTML

 script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js"></script

JS档案

  import Mymodule from './modules/mymodule';

2 个答案:

答案 0 :(得分:3)

Babel不能执行模块的客户端转换,或者说它不是浏览器普遍支持的。事实上,除非您使用插件,否则Babel会将import转换为require()

如果我运行以下代码:

<head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.js"></script>
    <script defer type="text/babel" data-presets="es2015">
        import Mymod from './modules/module';
        Mymod();
    </script>
</head>

我收到以下错误:

  

未捕获的ReferenceError:未定义require

来自Babel Docs

  

在浏览器中进行编译的用例相当有限,因此如果您在生产站点上工作,则应该在服务器端预编译脚本。有关详细信息,请参阅setup build systems。

大多数人选择预编译的模块捆绑器,如WebpackRollup

如果您确实想要执行此客户端,请使用RequireJS与Babel通过plugin运行,但您可能需要使用AMD语法。

ES6模块的原生浏览器支持仍在early stages中。但据我所知,还没有一个预设/插件可供Babel告诉它不要转换import/export语句。

答案 1 :(得分:2)

babel-standalone转换的脚本默认在全局范围内执行,因此由它们定义的任何符号都可自动用于其他每个模块。从这个角度来看,您不需要在模块中导入/导出语句。

但是,您可能正在尝试维护可以由babel-standalone(例如,用于快速测试环境,功能演示等)以及通过诸如webpack之类的捆绑器使用的源文件。在这种情况下,您需要保留导入和导出语句以实现兼容性。

使其工作的一种方法是在全局范围中添加额外的符号,这会导致babel生成的导入和导出代码无效(而不是像通常那样导致错误)。例如,export语句被编译成如下所示的代码:

Object.defineProperty (exports, "__esModule", {
   value: true
});
exports.default = MyDefaultExportedClass;

如果没有名为&#34; exports&#34;的现有对象,则会失败。所以给它一个:我只是给它一个window对象的副本,这样任何有趣的东西仍然可以访问:

 <script>
     // this must run before any babel-compiled modules, so should probably
     // be the first script in your page
     window.exports = window;

import语句被转换为对require()的调用。结果(或从中提取的属性)将分配给用作import语句中的标识符的变量。默认导入有一点复杂性,这取决于require()的结果是否包含属性__esModule。如果它没有,事情会变得更容易(但是你不能支持在同一个模块中同时使用默认和命名导出...如果你需要这样做,请查看babel生成的代码并弄清楚如何使其工作)。

因此,我们需要require()的工作版本。我们可以通过给出导符号/符号提供模块名称的静态转换来提供一个。例如,在React组件的演示页面中,我有以下实现:

function require (module) {
    if (module === "react")  return React;
    if (module === "react-dom")  return ReactDOM;
}

对于返回多个符号的模块,您只需返回一个包含符号作为属性的对象。

这样,就像

这样的陈述
`import React from "react";`

转换为有效的代码:

`React = React;`

这大致是我们想要的。