2017-01-26 39 views
2

反正有没有在两个或多个单独的文件中定义的JavaScript代码在同一个IIFE中运行?我愿意使用像gulp这样的构建工具来实现这一点。跨多个文件的IIFE

这似乎是这样一个平凡的问题。我希望我的代码能够被组织并分离到他们自己的文件中(顺便提一下,不同的挖空视图模型)。但我希望他们都以相同的功能运行,不污染全球。

+0

当然。选择你想使用的工具超出了堆栈溢出的范围(这将是基于意见的),但是 - 你可以连接文件来做到这一点。淘汰赛本身[使用这些片段](https://github.com/knockout/knockout/tree/master/build/fragments)就是为了这个目的。 –

+0

是的!我看过这些碎片,并且知道这是可能的。将所有文件连接在一起并用IIFE(可能使用gulp-concat)将它包围起来看起来似乎超级微不足道。但是,这个问题正在Chrome中发展。我想仍然可以使用chrome的开发工具对代码进行即时更改。并且使它们生成的js文件不起作用,我需要能够修改原始文件。 – smulz

回答

2

现代的做法是使用模块而不是尝试将所有内容都放入IIFE中。现在,使用模块意味着使用像RequireJS,SystemJS,Webpack,Browserify等模块捆绑器。在中期,您可以直接在浏览器中使用ES2015 +模块,或者使用捆绑器将它们捆绑到一个文件中。 (您可以使用ES2015 +模块语法今天像巴贝尔transpilers,但你仍然需要一个捆绑。)

你你使用RequireJS的时刻,但没有使用它的define功能提及。只是为了说明的目的,这里的大致你如何定义一个模块(我不是要求的语法的粉丝,但你可以使用通天transpile ES2015语法吧):

说我有一个模块定义了KO组件:

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

    // Return it 
    return MyComponent; 
}); 

即:

  1. 说,模块称为my-component(模块名称是可选的,所以例如应用程序的顶层模块不需要有名称)
  2. 说这取决于模块ko(它提供了Knockout);注意这种依赖是如何,然后作为参数传递给您用来定义模块
  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... 

显然,这两个例子都非常简化,有很多你可以做更多。

+0

谢谢!我正在使用RequireJS来导入我的所有文件。我没有使用任何define()功能,纯粹使用它来通过require()将javascript文件导入浏览器。我试着查阅文档,将所有这些文件都放到了IIFE中,但是没有完成。 – smulz

+0

@smulz:对不起,我应该更清楚一点:你*不会*把所有东西都放在一个IIFE中。相反,你需要在模块中定义事物(你不需要创建全局变量),并且使用'require'和'define'(在RequireJS的情况下)将你需要的东西从一个模块拉到另一个模块。这些捆绑器他们有一个工具,您可以在构建时使用它,它遍历依赖关系树并构建一个包含所有依赖项的文件(不会创建不必要的全局变量)。例如,现代的做法是使用模块*来代替*。 –

+0

@smulz:所以在开发时,捆绑器会单独引入这些文件,这对于开发很方便。准备发布时,运行一个构建,它运行捆绑器的依赖树检查,并将这些文件合并为一个可交付物。 –

0

这是两个单独的问题。

  1. IIFE能跨越多个文件 - 不!
  2. 可以在多个文件中的类/函数/等不是全局范围 - YES!

file1的

var myNS = {}; 

file2的

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

file3的

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

作为一个非常简单的例子,其中有101种实现是相同的。

+0

是的,这是我最初处理这个问题的方法。我不是一个巨大的粉丝,因为大量的代码需要重构将“myNS”添加到每个对象实例。我开始认为我没有其他选择。 – smulz

+0

@smulz:你这样做:模块。 –

+0

@smulz要清楚,这是一个老式的答案。 T.J.在现代意义上远远更加正确。 – Jamiec