Search code examples
javascriptknockout.jsiife

IIFE across multiple files


Is there anyway to have javascript code defined in 2 or more separate files to run in the same IIFE? I'm open to using build tools like gulp to accomplish this.

It just seems like such a mundane problem. I want my code to be organized and separated into their own files (distinct knockout view models, by the way). But I want them all to run in the same function and not pollute global.


Solution

  • The modern way to do this is to use modules rather than try to put everything into an IIFE. Right now, using modules means using a module bundler like RequireJS, SystemJS, Webpack, Browserify, etc. In the medium-term future, you'll be able to use ES2015+ modules directly in the browser if you like, or again use bundlers to bundle them into a single file. (You can use ES2015+ module syntax today with transpilers like Babel, but you still need a bundler.)

    You've mentioned you're using RequireJS at the moment but not using its define functionality. Just for the purposes of illustration, here's roughly how you'd define a module (I'm not a fan of Require's syntax, but you can use Babel to transpile ES2015 syntax to it):

    Say I have a module that defines a KO component:

    define("my-component", ["ko"], function(ko) {
        // ...define the component...
    
        // Return it
        return MyComponent;
    });
    

    That:

    1. Says the module is called my-component (module names are optional, so for instance the top-level module of an app needn't have a name)
    2. Says it depends on the module ko (which provides Knockout); note how that dependency is then provided as an argument to the callback that you use to define your module
    3. Returns MyComponent as the top-level thing defined by the module

    Then in my app:

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

    You can also have modules that group together other modules that are commonly used in groups, to simplify things.

    In ES2015+ syntax instead:

    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...
    

    Obviously, both examples are very simplified and there's a lot more you can do.