如何在vanilla JavaScript中导入/导出类

时间:2017-06-12 02:31:20

标签: javascript html ecmascript-6

我使用普通的javascript并尝试利用作为ECMA-6版本的一部分的类和模块导入/导出的概念。

这是我的代码:

rectangle.js档案 -

export default class  Rectangle{
  constructor(height, width) {
    this.height = height;
    this.width = width;
  }
}

myHifiRectangle.js档案 -

import Rectangle from 'rectangle.js';

class MyHiFiRectangle extends Rectangle {
  constructor(height, width) {
      super(height,width);
      this.foo= "bar";  
 }
}

我试图在一个简单的HTML网页test.html中使用上述两个* .js文件,如下所示:



<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title>Javascipt by Rasik Bihari Tiwari</title>
       <script src="Scripts/rectangle.js"></script>
       <script src="Scripts/myHiFiRectangle.js"></script>
      <script type="text/javascript">
    
   var v = new MyHiFiRectangle(2,4);
   console.debug(v.foo);
      </script>
   </head>
   <body >

   </body>

</html>
&#13;
&#13;
&#13;

现在,当我在各种浏览器中浏览test.html文件时,在Google Chrome上我得到以下错误:

  

未捕获的SyntaxError:意外的令牌导出

在Mozilla Firefox上我得到以下错误:

  

SyntaxError:export声明只能出现在a的顶层   模块

     

SyntaxError:import声明只能出现在顶层   一个模块

     

ReferenceError:未定义MyHiFiRectangle [了解详情]

我尝试重新排序HTML文件的head标记中引用的* .js文件,但它们没有区别。

P.S。我没有使用任何像Babel这样的转发器。我只是想看看班级本地支持的工作情况。和javascript中的模块导出/导入构造(ECMA-6发布)及其工作原理。

4 个答案:

答案 0 :(得分:3)

我想向您展示@Andy Gaskell发布的替代解决方案。

首先,您需要使用babel以确保您可以在浏览器中使用ES6。这是为了确保您的代码仍然可以工作,因为某些浏览器(IE等传统浏览器)不支持现代javascript(ES6及更高版本)功能,如导入/导出和类。

您可以添加以下脚本

`<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>`

在上面提到的任何其他javascript文件之前。

其次,如果您将javascript类包含在内,那么这些类的范围将变为全局,即使它们位于自己的物理js文件中也是如此。

我已经在下面添加了一个工作示例,我稍微改了一下,以便它可以在代码片段中使用。您希望将脚本替换为包含您的javascript文件的脚本,就像您在代码中所做的那样。

&#13;
&#13;
<!DOCTYPE html>
<html lang = "en">
   <head>
      <meta charset = "UTF-8">
      <title>Javascipt by Rasik Bihari Tiwari</title>
       <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.23/browser.min.js"></script>

      <!-- Replace them with script with src pointing to your javascript -->       
      <script type="text/javascript"> 
        class  Rectangle{
          constructor(height, width) {
            this.height = height;
            this.width = width;
          }
        }

        class MyHiFiRectangle extends Rectangle {
          constructor(height, width) {
              super(height,width);
              this.foo= "bar";  
         }
        }
           
       var v = new MyHiFiRectangle(2,4);
       console.log(v.foo);
       </script>
   </head>
   <body >

   </body>

</html>
&#13;
&#13;
&#13;

<强>已更新

  

确定。凉!顺便说一句,如果我将所有类定义带入脚本标记   我的HTML页面本身然后我甚至不需要引用babel-core   在头标签。为什么需要它?

对于不支持IE等类的浏览器,您可能需要它。但是,如果旧版浏览器的兼容性不符合您的要求,那么您就不需要它了。

  

......我甚至需要导出导入的东西吗?会是什么   每个类在本机javascript中导出模块的重要性   或多或少是全球化的?

事实上,由于您的课程是全球性的,您不会需要导出导入的东西。如果要使用模块系统,则仅使用此选项。如果您不使用导入/导出,您的课程应该是全球性的,因此应该有效。但是,如果它不是以某种方式。通过将它附加到窗口对象,确保它全局存在:

 window.myClass = class MyClass { /* Class definition */ }

答案 1 :(得分:3)

我经历了这个过程,并且有一个解决方案,其中包含第三个js文件作为模块。 rectangular.js将是相同的,并且myHifiRectangle.js文件只有一个修改。

import Rectangle from './rectangle.js';

export default class MyHiFiRectangle extends Rectangle {
      constructor(height, width) {
      super(height,width);
      this.foo= "bar";  
   }
}

现在,我们需要第三个文件,它将是一个模块文件,例如 script.js

import MyHiFiRectangle from './myHifiRectangle.js'

var v = new MyHiFiRectangle(2,4);
console.log(v.foo);

现在,应该将第三个文件 script.js 设为一个模块。有关模块here的更多信息。我的所有三个文件都在modelJS文件夹下。

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

现在,当您运行时,您应该在控制台中看到“ bar”。

答案 2 :(得分:1)

most browsers中,这是通过feature flag启用的。

Chrome:转到about:flags并启用“实验性网络平台功能”。

Firefox从版本54开始:dom.moduleScripts.enabled

Edge 15或更新版本:在about:flags中启用“实验性JavaScript功能”。

答案 3 :(得分:0)

从@ curiou.netter的答案中获得提示后,为了完整性起见,我添加了一个答案。我只是在我的原始代码文件中按顺序指出确切的错误。我能够在没有其他script.js文件的情况下实现它:

  1. 在引用JS模块时,我们的脚本类型应改为module。我指的是myHiFiRectancle.js,就像常规的JS文件一样,使用src标签作为src="Scripts/myHiFiRectangle.js"。我还导入了MyHiFiRectangle模块。修复此错误后,head标签现在在我的test.html文件中显示如下:

    <head>
      <meta charset = "UTF-8">
      <title>Javascipt by Rasik Bihari Tiwari</title>
      <script type="module">
         import MyHiFiRectangle from './scripts/myHiFirectangle.js';
         var v = new MyHiFiRectangle(2,4);
         console.debug(v.foo);
      </script>
       </head>
    
  2. export default文件中缺少
  3. myHiFiRectangle.js语句。每个类都必须作为模块导出才能使用。myHiFiRectangle.js文件如下所示,修复了此错误:

    import Rectangle from './rectangle.js';
    export default class MyHiFiRectangle extends Rectangle {
      constructor(height, width) {
      super(height,width);
      this.foo= "bar";  
     }
    }
    
  4. 我的脚本文件在引用模块时出现了另一个错误。

    错误的方式:

    import Rectangle from 'rectangle.js';
    import MyHiFiRectangle from '/scripts/myHiFirectangle.js';
    

    它会引起以下错误,这是不言自明的:

      

    未捕获的TypeError:无法解析模块说明符“ rectangle.js”。   相对引用必须以“ /”、“./”或“ ../”开头。

    正确的方法:

    import Rectangle from './rectangle.js';
    import MyHiFiRectangle from './scripts/myHiFirectangle.js';