7

I've being trying to bundle my TypeScript "application" into a single javascript file.

I'm not using any bundler but TSC ( using TypeScript 2.2 ). Aside of my own ts files, my application also uses external modules such immutablejs.

I read every possible thread, documentation but I can't find a way to bundle external modules ( from node_modules ) into my compiled / transpiled javascript file using only TSC.

Down below you can find a sample of my latest code/ configu as well as the results of my attempts.

tsconfig.json

{
    "compilerOptions": {
        "target":           "es5",
        "module":           "system",
        "removeComments":   true,
        "sourceMap":        true,
        "allowJs":          true
    }
}

app.ts - note: ./something.ts is successfully bundled.

/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />

import * as something from "./something";
import * as Immutable  from "immutable";

console.log( something.test );

const map1 = Immutable.Map( { a: 1, b: '2', c: 'cu' });
console.log( map1.get( 'a') )

1#: using tsc-bundle (https://www.npmjs.com/package/typescript-bundle)

This method not only don't bundle immutableJs as well as thrown the error: require is not defined.

var dragonfly = (function () {
  var main = null;
  var modules = {
      "require": {
          factory: undefined,
          dependencies: [],
          exports: function (args, callback) { return require(args, callback); },
          resolved: true
      }
  };
  function define(id, dependencies, factory) {
      return main = modules[id] = {
          dependencies: dependencies,
          factory: factory,
          exports: {},
          resolved: false
      };
  }
  function resolve(definition) {
      if (definition.resolved === true)
          return;
      definition.resolved = true;
      var dependencies = definition.dependencies.map(function (id) {
          return (id === "exports")
              ? definition.exports
              : (function () {
                  if(modules[id] !== undefined) {
                    resolve(modules[id]);
                    return modules[id].exports;
                  } else return require(id)
              })();
      });
      definition.factory.apply(null, dependencies);
  }
  function collect() {
      Object.keys(modules).map(function (key) { return modules[key]; }).forEach(resolve);
      return (main !== null) 
        ? main.exports
        : undefined
  }

  define("something", ["require", "exports"], function (require, exports) {
      "use strict";
      Object.defineProperty(exports, "__esModule", { value: true });
      exports.test = "oie";
  });
  define("app", ["require", "exports", "something", "immutable"], function (require, exports, something, Immutable) {
      "use strict";
      Object.defineProperty(exports, "__esModule", { value: true });
      console.log(something.test);
      var map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
      console.log(map1.get('a'));
  });
  //# sourceMappingURL=app.js.map
  return collect(); 
})();

#2 - using TSC with module = system ( tsc src/app.ts -m system --outfile build/app.js )

This method also don't bundle immutableJs but also thrown the error: System is not defined

System.register("something", [], function (exports_1, context_1) {
    "use strict";
    var __moduleName = context_1 && context_1.id;
    var test;
    return {
        setters: [],
        execute: function () {
            exports_1("test", test = "oie");
        }
    };
});
/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
System.register("app", ["something", "immutable"], function (exports_2, context_2) {
    "use strict";
    var __moduleName = context_2 && context_2.id;
    var something, Immutable, map1;
    return {
        setters: [
            function (something_1) {
                something = something_1;
            },
            function (Immutable_1) {
                Immutable = Immutable_1;
            }
        ],
        execute: function () {/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
            console.log(something.test);
            map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
            console.log(map1.get('a'));
        }
    };
});

#3 - using tsc with module = amd ( tsc src/app.ts -m amd --outfile build/app.js )

This method not only don't bundle immutableJs as well as thrown the error: define is not defined.

define("something", ["require", "exports"], function (require, exports) {
    "use strict";
    exports.__esModule = true;
    exports.test = "oie";
});
/// <reference path="../node_modules/immutable/dist/immutable.d.ts" />
define("app", ["require", "exports", "something", "immutable"], function (require, exports, something, Immutable) {
    "use strict";
    exports.__esModule = true;
    console.log(something.test);
    var map1 = Immutable.Map({ a: 1, b: '2', c: 'cu' });
    console.log(map1.get('a'));
});

Conclusion: It's really important for the future of my project be able to bundle external libraries without the need of these popular bundlers such as webpack, browserify, gulp, etc...

Does anyone can help me?

Thanks in advance,

TF!

6
  • Just curious - is there a reason why you reject webpack and browserify but are willing to use relatively unknown typescript-bundle? As you have seen, typescript is not a bundler, it will not include external dependencies in the output, unless they are all compiled together at the same time with your own code. Commented Apr 17, 2017 at 19:59
  • Hi Artem, thanks for the answer... The reason why I'm rejecting is only one. I have to use the webserver / watcher / task runner I created, do you think would still be a good idea / possible use one of these guys ( webpack, gulp, bower ) only as bundler? Commented Apr 18, 2017 at 4:26
  • If you need only the bundler, then webpack with ts-loader is the most obvious choice - you don't need anything else besides that. I also have used systemjs-builder for bundling, and know that some people are using rollup Commented Apr 18, 2017 at 5:33
  • Thanks again for the answer... I had a look in the systemjs-builder, and looked pretty straight forward. Question though is: How you consume the JS from the browser? I mean how can I use the bundle? is it exposed at window object level? Commented Apr 18, 2017 at 6:19
  • Also how it would work with Typescript? I would need to firstly compile ts into js and then run trigger the bundler? Commented Apr 18, 2017 at 6:34

1 Answer 1

1

Just noticed your post, and disclaimer, I am the author of typescript-bundle. You can bundle ImmutableJS with the following.

tsc-bundle --project ./tsconfig.json --importAs immutable=Immutable

Some documentation about this switch here

This will create an additional resolver that attempts to resolve immutable from the window object. This is typically the case if you are including dependant scripts in your page (via a <script> tag) and need that global name (Immutable in this case) referenced in your bundle (and you need to make use of .d.ts files pulled from @types/* with the ambient module named "immutable")

The above line results in the following resolve() function.

  function resolve(definition) {
      if (definition.resolved === true)
          return;
      definition.resolved = true;
      var dependencies = definition.dependencies.map(function (id) {
          return (id === "exports")
              ? definition.exports
              : (function () {
                  if(modules[id] !== undefined) {
                    resolve(modules[id]);
                    return modules[id].exports;
                  } else if(id === "immutable") {
                    return window["Immutable"];
                  } else {
                    try {
                      return require(id);
                    } catch(e) {
                      throw Error("module '" + id + "' not found.");
                    }
                  }
              })();
      });
      definition.factory.apply(null, dependencies);
  }

This works against most declarations you will find in the npm @types/* repository (assumed UMD) and allows the bundle to effectively pull the module from the environment (global variable name).

Hope you find this helpful

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.