【问题标题】:IIFE across multiple files跨多个文件的 IIFE
【发布时间】:2017-01-26 21:15:48
【问题描述】:

是否有 javascript 代码定义在 2 个或多个单独的文件中以在同一个 IIFE 中运行?我愿意使用诸如 gulp 之类的构建工具来完成此任务。

这似乎是一个平凡的问题。我希望将我的代码组织并分离到它们自己的文件中(顺便说一下,不同的淘汰视图模型)。但我希望它们都在同一个函数中运行,而不是污染全局。

【问题讨论】:

  • 当然。选择您要使用的工具超出了 Stack Overflow 的范围(它将基于意见),但是是的 - 您可以连接文件来执行此操作。淘汰本身 uses these fragments 就是为了这个目的。
  • 是的!我看过这些片段并且知道这是可能的。将所有文件连接在一起并用 IIFE 包围它似乎非常简单(可能使用 gulp-concat)。但随后问题出现在 Chrome 中。我希望仍然能够使用 chrome 的开发工具即时更改代码。并且在生成的 js 文件上制作它们是行不通的,我需要能够修改原始文件。

标签: javascript knockout.js iife


【解决方案1】:

实现这一点的现代方法是使用模块,而不是尝试将所有内容都放入 IIFE。目前,使用模块意味着使用模块捆绑器,如 RequireJS、SystemJS、Webpack、Browserify 等。在中期内,如果您愿意,您将能够直接在浏览器中使用 ES2015+ 模块,或者再次使用捆绑器来将它们捆绑到一个文件中。 (你现在可以将 ES2015+ 模块 syntax 与 Babel 等转译器一起使用,但你仍然需要一个捆绑器。)

您提到您目前正在使用 RequireJS,但没有使用其 define 功能。只是为了说明的目的,这里大致是如何定义一个模块的(我不喜欢 Require 的语法,但你可以使用 Babel 将 ES2015 语法转换为它):

假设我有一个定义 KO 组件的模块:

define("my-component", ["ko"], function(ko) {
    // ...define the component...

    // Return it
    return MyComponent;
});

那个:

  1. 表示模块名为my-component(模块名称是可选的,因此例如应用的顶级模块不需要名称)
  2. 说它取决于模块ko(提供敲除);请注意,然后如何将该依赖项作为参数提供给您用于定义模块的回调
  3. 返回 MyComponent 作为模块定义的顶级事物

然后在我的应用中:

define(["my-component", "another-component"], function(MyComponent, AnotherComponent) {
    // use MyComponent and AnotherComponent here
});

您还可以将模块组合在一起,将其他常用的模块组合在一起,以简化事情。

在 ES2015+ 语法中:

my-component.js:

import ko from "./ko";
// ...define MyComponent...
export default MyComponent;

app.js:

import MyComponent from "./my-component";
import AnotherComponent from "./another-component";

// ...use them...

显然,这两个示例都非常简化了,您可以做的还有很多。

【讨论】:

  • 谢谢!我正在使用 RequireJS 导入我的所有文件。我没有使用任何define() 功能,纯粹是使用它通过require() 将javascript 文件导入浏览器。我尝试查阅文档以将所有这些文件放入 IIFE,但未能成功。
  • @smulz:抱歉,我应该更清楚一点:您将所有内容都放在一个 IIFE 中。相反,您在模块中定义事物(在其中您不创建全局变量),并使用requiredefine(在 RequireJS 的情况下)将您需要的事物从一个模块拉到另一个模块中。这些捆绑器有一个工具,您可以在构建时使用它来遍历依赖关系树并构建一个包含所有依赖关系的单个文件(这不会创建不必要的全局变量)。例如,使用 IIFE 进行操作的现代方法是使用模块而不是
  • @smulz:所以在开发的时候,bundler 会单独引入文件,方便开发。准备好发布后,您运行构建,该构建运行捆绑器的依赖关系树检查并将文件组合成一个可交付成果。
  • 谢谢 TJ。我想我明白。我想我希望有一个不需要大量重构的解决方案。但这似乎是正确的解决方案。
  • 感谢您提供详细的示例。很有帮助。
【解决方案2】:

这是两个不同的问题。

  1. IIFE 可以跨多个文件吗?不可以!
  2. 多个文件中的类/函数/等可以不污染全局范围 - 是的!

文件1

var myNS = {};

文件2

myNS.MyViewModel = function(){ ... }

文件3

myNS.OtherViewModel = function() { ... }

作为一个非常简单的示例,其中有 101 种方法可以实现相同的目标。

【讨论】:

  • 是的,这是我最初解决这个问题的方法。我不是一个超级粉丝,因为要重构大量代码以将“myNS”添加到每个对象实例化。我开始认为我别无选择。
  • @smulz:你做:模块。
  • @smulz 要清楚,这是一个老式的答案。 T.J.在现代意义上是远远更正确的。
猜你喜欢
  • 2016-12-12
  • 1970-01-01
  • 2013-12-16
  • 1970-01-01
  • 1970-01-01
  • 2016-01-07
  • 2012-07-26
  • 2014-05-16
  • 2023-04-03
相关资源
最近更新 更多