Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 980
Pawel Avatar asked Nov 22 '16 17:11

Pawel


People also ask

Can TypeScript be used in browser?

There are no plans to support TypeScript natively in the browsers. Chrome did some experiment, but later cancelled support.

Can you mix TypeScript and js?

The TypeScript compiler supports a mix of JavaScript and TypeScript files if we use the compiler option --allowJs : TypeScript files are compiled. JavaScript files are simply copied over to the output directory (after a few simple type checks).


1 Answers

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.

like image 182
Eryk Napierała Avatar answered Oct 10 '22 21:10

Eryk Napierała