Tom Crockett
Tom Crockett

Reputation: 31599

Developing a requirejs-exported library in TypeScript

Apologies if this question is a bit unfocused/rambling, but what I really have here are several interrelated questions that I'd like to ask all at once.

Suppose I'm developing a library called foo which consists of files foo.ts, bar.ts and baz.ts. foo.ts is the root of the library, i.e. it depends on the other two and exports all the functionality that might be needed by a dependent application. Suppose also that I want to make this library available as an AMD-loadable module.

What is the right way to structure this code in TypeScript? Here are the ways that I can think of to do this:

  1. Use /// <reference path="..."/> throughout the files, and then use --out combined.js to combine them into one big library. But if I do this, I don't see how to make the combined output available downstream as an AMD module. If I add an export statement to the foo module, it has no effect on the combined file, only producing a requirejs-wrapped version of foo.js. So it seems that combining internal modules via --out combined.js and then making certain parts of the combined result available via an export is not straightforward. Should I just use another tool to wrap the concatenated result in AMD boilerplate, eschewing the import/export features of TypeScript?

  2. Make foo.ts, bar.ts and baz.ts all external modules, have them depend on one another using e.g. import bar = require('./bar');, and have foo.ts export a module containing only the parts of bar and baz that are part of the library's public API. If I go this route, then by default, since we're using AMD modules, all files will be downloaded separately, even though they're highly inter-dependent, which seems less than ideal. But I could use the requirejs optimizer to combine the resulting individual modules into one big module. However, if the application using the library is also written in TypeScript and wants to make use of its declarations, where should it look? When using the --out combined.js option as in (1), it's possible to also get a combined .d.ts for the library, but when using external modules I don't see how to do this. Should the downstream application code instead reach into the source directory and pick up individual declaration files, i.e. foo.d.ts, bar.d.ts, baz.d.ts? Should I manually create a master declaration file that refers to all the auto-generated singleton .d.tss?

Upvotes: 1

Views: 437

Answers (2)

httpete
httpete

Reputation: 2983

New way! Forget the references, just put a tsconfig.json file at the root of the project, and all will work with no collisions.

Upvotes: 1

basarat
basarat

Reputation: 276085

Here is what I would do. Compile with --out lib.js --declaration flags all files except foo.ts. And then use the declaration to create foo.ts e.g. Assume:

bar.ts:

module Foo{
   export class Bar{
   }
}

baz.ts:

module Foo{
   export class Baz{
   }
}

The declaration file (due to --declaration flag) you will get is :

module Foo{
  export class Bar{
   }
  export class Baz{
   }
}

So you can create Foo.ts as :

/// <reference path="lib.d.ts"/>
declare module "Foo"{
  export = Foo;
}

Then hardcode a lib.dist.js to load the --out js file and export to amd:

define([require,'lib'],function(){
    return Foo;
});

UPDATE If you need to depend on a third party lib use <amd-depenedency in Foo.ts and use Foo.ts yourself as well in other sections.

Upvotes: 1

Related Questions