Pawel Pawel - 15 days ago 9
Node.js Question

Creating a typescript library that can be used in browser and nodejs

I would like to create a library that can be used in both - browser and nodejs. For the sake of the argument let's say this is my library:

export default class MyClass {
public getString(): string {
return "Message";
}
}


ES2015 modules are not supported by browsers as of now and I don't want to depend on requirejs or any other module loader when in browser - I would like this library to be consumed just by including the generated .js file using the
script
tag. It feels that what I want can be achieved by using internal modules (I don't want to pollute the global namespace).
However when I wrap my code in
namespace
/
module
I am having a hard time to get it compiled to as commonjs module.

What is the proper way of achieving what I want? Or, may be, I am getting completely off the rails here being a typescript and javascript noob?

Answer

I think what you need is UMD. With tsconfig.json containing

{ "compilerOptions": { "module": "umd" }, }

generated JavaScript will look like this:

(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"], factory); } })(function (require, exports) { "use strict"; var MyClass = (function () { function MyClass() { } MyClass.prototype.getString = function () { return "Message"; }; return MyClass; }()); exports.__esModule = true; exports["default"] = MyClass; });

It works in node (CommonJS) as well as with browsers (CommonJS, AMD). To allow users of your library to just include it through script tag, you need module bundler like Webpack, Browserify or Rollup. Those will produce UMD definition with global export, so default export of main file of your library will be available as some variable in global scope.