1

I transpile my TypeScript using "-m umd" because my project includes server, client and shared code. However, client side code doesn't work in browser. The browser doesn't even display any error and the breakpoint I located didn't hit, so I had to remove js-ts mapping. Then, I was able to debug it and I found the problem.

Following is the code that UMD generates:

(function (factory) {
    if (typeof module === 'object' && typeof module.exports === 'object') {
        var v = factory(require, exports); if (v !== undefined) module.exports = v;
    }
    else if (typeof define === 'function' && define.amd) {
        define(["require", "exports", "./model"], factory);
    }
})(function (require, exports) {
    //my code
});

It doesn't work because both 'module' and 'define' are undefined. Therefore my code is not executed and there isn't even any exception.

What's wrong? How could I make it work?

Alon
  • 10,381
  • 23
  • 88
  • 152
  • 2
    You have to use a module loader. – Tamas Hegedus Jul 18 '16 at 12:09
  • @Tamas Hegedus like SystemJS? So I don't need to use UMD in that case. I thought UMD is supposed to solve me that problem. – Alon Jul 18 '16 at 12:13
  • 1
    UMD unifies AMD and CommonJS modules, so you can use these modules with either. SystemJS unifies AMD and CommonJS too, so it can load either. The only clear way to solve the problem is to use pure es6 modules and bundle with rollupjs. I dont know if typescript has a rollup like bundler built in – Tamas Hegedus Jul 18 '16 at 12:16
  • @Tamas Hegedus afaik AMD is the module format that the browser is familiar with, CommonJS is the one that Node is familiar with, meaning unifying of both should make js code to work in both client and server, and that's what I'm expecting from UMD to do. What did I understand wrong? – Alon Jul 18 '16 at 12:30
  • 1
    The browser is not familiar with any module loader at all. There was a System module loader spec, but got abandoned as it just introduced one more module format. Currently MS Edge is the only browser that understands modules, and it uses the standard es6 module formats. For every other browser you must either use a loader (say the one with webpack, requirejs or any AMD, systemjs) or bundle with rollupjs which doesn't rely on module loaders. Sure AMD fits better browsers as it is asynchronous, but is not supported natively. – Tamas Hegedus Jul 18 '16 at 13:57
  • 1
    This question is related: http://stackoverflow.com/questions/31593694/do-i-need-require-js-when-i-use-babel/34168934#34168934 – Tamas Hegedus Jul 18 '16 at 13:58
  • @Tamas Hegedus OK, I understand now. You can rewrite your first comment as an answer and I will accept it. – Alon Jul 18 '16 at 14:26

1 Answers1

4

Today none of the browsers understand AMD modules natively. (In fact none of the module formats except standard ES6 in some really new builds of MS Edge).

So you have to bundle a module loader with your code. I suggest you to either use only AMD modules and a lightweight AMD loader, concatenating your modules and the module loader in a single file, or use RollupJS, which generates a loader-less bundle from standard ES6 modules. If I remember correctly the rollup-plugin-typescript plugin doesn't work well with multiple files, so I recommend compiling typescript with tsc into es6 modules, and bundle it with rollupjs in a second step.

You can read more about module bundlers in this StackOverflow thread: Do I need require js when I use babel?

EDIT

Today (September 2016) the rollup-plugin-typescript plugin works like a charm! Definitely this is the recommended way now.

Community
  • 1
  • 1
Tamas Hegedus
  • 28,755
  • 12
  • 63
  • 97