ES2015模块,我应该导入/导出所有内容吗?

时间:2018-06-27 17:09:24

标签: javascript class import ecmascript-6 export

我最近开始在javascript中使用 import export ,但我有些困惑。我不确定我应该导出什么,以及我应该保留在文件本地。我不知道如何用英语来表达这一点,所以这是我的代码中的一小部分:

/client/js/Inventory.js 文件,模块:

import {
  $,
  renderHTML,
  game
} from "../main.js";

const template = {
  titanium: {
    name: "Titanium",
    description: "Description here..."
  }
}

export default class Inventory {
  constructor(inventory) {
    this._name = inventory.name;
    this._description = inventory.description;
  }

  get name() {return this._name}
  get description() {return this._description}

  generate(id) {
    renderHTML("inventory, `
      <div class="inventory" id="${id}">
        content here...
      </div>
    `);
  }

  static make(id) {
    game.inventory[id] = new Inventory(template[id]);
    game.inventory[id].generate(id);
}

和我的 /client/main.js 文件看起来像这样:

import Inventory from "./js/Inventory.js";

const $ = (id) => document.getElementById(id);
const renderHTML = (id, str) => $(id).insertAdjacentHTML("beforeend", str);

const game = {
  inventory: {}
};

Inventory.make("titanium");

export {
  $,
  renderHTML,
  game
};

由于我要从 main.js 文件导出game对象,这是否意味着在 Inventory.js中创建了一个新的game对象文件导入后,是否意味着 Inventory.js 文件现在可以访问 main.js 文件的game对象?

由于我正在调用 main.js 文件中的类,因此我还需要从 Inventory.js 文件中导出template对象吗? ,并将其导入 main.js 文件中?

仅导出类工作正常,但如果不导出,我不知道 main.js 如何访问模板?如果在 main.js 中找不到任何内容,它是否会在 Inventory.js 文件中查找?或者

谢谢!

1 个答案:

答案 0 :(得分:0)

这很简单。模块是在不同代码段之间共享代码或数据的结构化方式。

导出任何您希望与其他模块共享的功能或数据,这些模块将加载您的模块。

如果您不打算共享它或不需要共享它,请不要导出它。如果确实需要共享它或某些其他模块需要访问它,则可以导出它。导出是与其他模块共享的方式。

导入其他模块中需要在此模块中使用的所有属性。

对于导入,您仅导入现在需要的内容。将来无需导入您“可能”需要的东西。您始终可以在实际需要时添加导入。

对于导出,您仅导出您现在打算共享的内容。如果您发现以后需要共享更多内容,可以随时在以后添加另一个导出。


仅在此模块内使用的代码不需要导出。实际上,模块的好处之一是您可以维护模块中的代码隐私或保护,因为其他代码无法访问未通过导出以某种方式导出或共享的模块中的任何内容。


您可以在逻辑上将导出视为模块的“ api”。这是其他模块可以在您的模块中调用的内容。

从指定其他模块中要使用的“ api”时,您可以在逻辑上考虑导入。

当所有内容都位于全局名称空间中时(与原始浏览器设计一样),则没有显式导出或导入。在顶层声明的所有内容都是公开和共享的。这引起了各种各样的问题,特别是当项目变得越来越大,文件越来越多,而当您开始尝试使用第三方代码时,问题变得更加复杂。

模块系统是一种结构化的说法,默认情况下,一切都是私有的。然后,您仅显式导出要共享的内容。而且,然后,当某人想要使用您的api时,他们会显式导入他们想要使用的api。每个模块都位于其自己的范围内,因此具有自己的名称空间。模块也是一个非常自然的可测试单元。

在Javascript模块标准化之前,开发人员已经建立了许多不同的约定,以尝试解决Javascript中的大型扁平全局命名空间。如果您使用的是第三方库,则在同一项目中遇到多个约定的情况并不少见。对于不尝试使用约定来解决此问题的开发人员,代码可能会变得很混乱,有很多潜在的变量命名冲突,功能意外替换以及文件之间通常没有文档证明的依存关系等等……标准化模块设计试图提供了一种解决这些问题的常用方法,并且在此过程中,还使编写可重用,可测试,可共享的代码变得容易得多。


  

由于我要从main.js文件中导出游戏对象,这是否意味着导入后在Inventory.js文件中创建了一个新的游戏对象,或者这意味着Inventory.js文件现在可以访问了main.js文件的游戏对象?

这意味着Inventory.js现在可以导出在game中创建的一个main.js对象。导出或导入时没有隐式复制。

  

由于我正在调用main.js文件中的类,因此我是否还需要从Inventory.js文件中导出模板对象,并将其导入main.js文件中?

您只需要从inventory.js中导出您直接需要从其他文件引用的内容。由于main.js不需要引用template变量目录,因此无需导出它。从inventory.js导入的操作加载并运行该模块。这使template内的所有代码都可以使用inventory.js变量,这是您所有代码所需的。因此,无需导出它。

  

仅导出类工作正常,但是如果不导出,我不知道main.js如何访问模板?如果在main.js中找不到文件,它是否会在Inventory.js文件中查找?

导出Inventory类允许任何其他模块使用该类及其所有方法。从inventory.js导入任何内容的过程都会导致模块本身被加载,因此inventory.js中定义的所有变量都在inventory.js内部处于活动状态。通过导出的类创建Inventory对象时,您正在inventory.js中运行可访问该模块中所有数据的代码。

导入分为两个步骤。首先加载引用的模块(如果尚未加载)。然后,获取您要求进口的出口。