3

I have a bit of a strange (but in my view sensible) scenario.

I have a web site, mobile application and maybe going forward a web server all written in Javascript. I have a huge chunk of functionality which is shared between all these systems. This shared stuff would be models, repositories, business logic etc etc.

If we exclude the web server bit as that is a future idea, the web application has a directory structure like this:

app
|- assets
|- models
|- services
|- migrations
|- view-models
|- views
|- descriptors

Now each of these applications is broken down into 2 areas, the core and ui sections, the core is the re-usable stuff such as models, services, migrations and the ui stuff is ONLY used for that application which would comprise of view-models, descriptors (Incase you are wondering views are all html and assets are css, images etc).

Before I was adopting typescript I had a build script which would basically combine all the core files together and minify them. Then it would combine all the UI ones together and minify them. That way in the mobile application I can then just use the my-app.core.min.js and everyone is happy, I am reusing all the re-usable components from the main web application. However I do not need the ui stuff as the mobile UI is completely different to the main web ui, and the web service would not even have a UI going forward.

SO!

With that context explained lets jump back to the Typescript problem at hand. Currently the typescript files are compiled by tsc.exe (version 0.83) via a build script, which just wraps the interaction.

So in the new Typescript world the structure now has a references folder like so:

app
|- assets
|- models
|- services
|- migrations
|- view-models
|- views
|- descriptors
|- references <- NEW ONE!

This references folder is automatically populated by the build script with all local references, so it will trawl through the whole directory tree find all typescript files and build a huge reference file, which is a file full of the reference declarations for local typescript file, to find out more about what im on about look over this question:

Can you create Typescript packages? like c# dlls

So now when I run the build script the following steps happen:


Compiling for Core

  1. Find all *.ts files within the models, services, migrations folders and subfolders
  2. Add all the previous files into an array and also add in the reference files
  3. run tsc.exe with a command like so tsc.exe --out <something>.core.js <previous_file_list>

Compiling for UI

  1. Find all *.ts files within the view-models, descriptors folders and subfolders
  2. Add all the previous files into an array and also add in the reference files
  3. run tsc.exe with a command like so tsc.exe --out <something>.ui.js <previous_file_list>

Now I was expecting this to output 2 files my-app.core.js which ONLY contained the core files, and a my-app.ui.js which ONLY contained the ui files. However they both include everything...

Now after thinking about this, it must be due to the references, as they are both referencing all files, however thats just a compilation dependency in my eyes, not something that needs to be compiled WITH the outputted javascript. In c#/java you would not expect a referenced dll/jar to be compiled into your outputted dll/jar, its just a runtime dependency which is required.

I have tried having 2 separate reference files, one for core and one for ui, but as the ui will depend on core I get same problem, although at least this way the my-app.core.js is devoid of any ui related guff.

So is there a way to have references but NOT have them be outputted into the generated javascript files?

Community
  • 1
  • 1
Grofit
  • 17,693
  • 24
  • 96
  • 176
  • 1
    possible duplicate of [How can typescript generate single one javascript file without reference typescript file code](http://stackoverflow.com/questions/15740653/how-can-typescript-generate-single-one-javascript-file-without-reference-typescr) - although I think you may be better off using a module loader rather than fiddling about with all these files and combining some of them. – Fenton Apr 09 '13 at 14:40
  • I use LabJS (or YepNope) depending upon the client/platform, to load the combined stuff later, the build script and application is quite complex, however I have diluted it down to a simple problem as mentioned above. You are right it is basically a more verbose version of the question you linked to. The code generated here is also used as a contract for other people to make plugins for the system, so I am generating these files not just for runtime but for 3rd party contracts too. – Grofit Apr 09 '13 at 15:30
  • I think the linked question up top is similar, as is http://stackoverflow.com/questions/13461758/referencing-typescript-file-includes-whole-file-in-output that one. However all these feel like work arounds for the compiler doing a bulk include on the --out argument, rather than just including the files passed. Does anyone know if this is being addressed in the compiler, as I remember reading that if you have a file which references another and you build that single file its fine, no references are included, however if you do the same with the --out flag it will include both. – Grofit Apr 10 '13 at 09:35

1 Answers1

7

You can accomplish this by generating definition files for your TypeScript files:

tsc --declaration FileName.ts

In your build script do this for each TypeScript file and use the generated FileName.d.ts as the reference instead of FileName.ts

I had the following files:

-BusinessObjects
--Product.ts
--Customer.ts
--Order.ts
--BusinessObjects.d.ts

BusinessObjects.d.ts looks like this:

/// <reference path="Customer.d.ts" />
/// <reference path="Order.d.ts" />
/// <reference path="Product.d.ts" />

with Product, Customer, and Order each have a reference to BusinessObjects.d.ts

when I run:

tsc --out combine.js Customer.ts Order.ts

The output only references Customer and Order, Product is not included. When I referenced the *.ts files directly in my BusinessObjects.d.ts file however the combined output did include the unwanted file.

dmck
  • 7,801
  • 7
  • 43
  • 79
  • Will look into this, can you not just generate 1 large declaration file as it seems messy having to make a load of temporary typescript descriptors, just to then include them as references to compile the real type script files to javascript. Just to answer my own question here you can generate single large descriptors when using out and multiple args. – Grofit Apr 09 '13 at 14:14
  • @Grofit how did you generate a consolidated reference file from multiple inputs? When I tried `tsc --output refs.d.ts --declaration file1.ts file2.ts` it created a output directory with multiple files. – dmck Apr 09 '13 at 14:46
  • I did ``tsc.exe --declaration --out my-combined-file-js ...`` I was just piggy backing on the original call so it would output the descriptor too (so outputs would be ``my-combined-file.js, my-combined-file.d.ts``, as this is useful for giving a code contract between the components anyway. However I realized the same issue exists because the descriptor was containing all the stuff from the references, and it then becomes a catch 22, I cannot build my code without the references, and if I wanted to reference d.ts files I would need to build the code for them to exist :(. – Grofit Apr 09 '13 at 14:52