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

Javascript ES2015模块,我是否应该导入/导出所有内容?,javascript,class,import,ecmascript-6,export,Javascript,Class,Import,Ecmascript 6,Export,最近我开始在javascript中使用导入和导出,但我有点困惑。我不确定我应该导出什么,以及我应该在文件中保留什么。我不知道如何用英语表达这种美好,所以这里是我代码中的一小部分: /client/js/Inventory.js文件,模块: import { $, renderHTML, game } from "../main.js"; const template = { titanium: { name: "Titanium", description: "

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

/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);
}
由于我正在从main.js文件导出
game
对象,这是否意味着导入后将在Inventory.js文件中创建一个新的
game
对象,或者这是否意味着Inventory.js文件现在可以访问main.js文件的
game
对象

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

仅导出类就可以了,但是我不知道如果没有导出,main.js如何访问模板?如果在main.js中找不到,它会在Inventory.js文件中查找吗


谢谢

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

您可以导出希望与将加载模块的其他模块共享的任何函数或数据

如果您无意共享或不需要共享,请不要导出它。如果您确实需要共享它或其他模块需要能够访问它,您可以将其导出。导出是与其他模块共享的方式

您可以从其他模块导入需要在此模块中使用的任何属性

对于导入,您只导入您现在需要的内容。不需要导入将来“可能”需要的东西。您总是可以在实际需要时添加导入

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


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


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

在逻辑上,您可以将导入视为指定要从其他模块使用的“API”

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

模块系统是一种结构化的方式,表示默认情况下,所有内容都是私有的。然后,只显式导出要共享的内容。然后,当有人想要使用您的API时,他们会显式地导入他们想要使用的API。每个模块都位于自己的作用域中,因此有自己的名称空间。模块也是一个非常自然的可测试单元

在Javascript模块标准化之前,开发人员已经构建了一系列不同的约定,试图在Javascript中围绕大型平面全局命名空间工作。如果使用第三方库,在同一个项目中遇到多个约定并不罕见。对于不尝试使用约定来解决此问题的开发人员,代码可能会变得相当混乱,可能会出现变量命名冲突、意外替换函数以及文件之间通常未记录的依赖关系网等。。。标准化的模块设计试图提供一种解决这些问题的通用方法,在这个过程中,也使编写可重用、可测试、可共享的代码变得更加容易


由于我正在从main.js文件导出游戏对象,这是否意味着导入后将在Inventory.js文件中创建新的游戏对象,还是意味着Inventory.js文件现在可以访问main.js文件的游戏对象

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

既然我在main.js文件中调用类,那么我是否还需要从Inventory.js文件中导出模板对象,并将其导入main.js文件中

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

仅导出类就可以了,但我不知道如果未导出,main.js如何访问模板?如果在main.js或main.js中找不到,它会在Inventory.js文件中查找吗

导出
库存
类允许任何其他模块使用该类及其所有方法。从
inventory.js
导入任何内容的过程会导致模块本身被加载,因此
inventory.js
中定义的所有变量都在
inventory.js
中处于活动状态。当您通过导出类创建
库存
对象时,您正在
inve中运行代码
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
};