Deliver Product Everyday

See post on medium – https://medium.com/the-geeks-of-creately/deliver-product-everyday-part-1-1e6a066231e0

Advertisements

How to avoid dependancies being compiled in TypeScript

You actually can’t do this (at the time of this post). But you can work around it.

The  Problem

Let me explain what I am talking about. When you use the typescript compiler (tsc or use any extension of it such as the grunt-typescript), when you specify a set of .ts files to be compiled to a specific destination, tsc would compile the given files as expected. However if you have references in the list of .ts files to other .ts files that are not include in the given list of files, the files that were not included also will get compiled along with the given .ts files and placed relatively in the given destination path. There is no actual way to avoid this or restrict this when compiling.

This might sound like something you don’t need but as  your project grows you may need to restructure the project or do targeted compiling of only specific files, you can’t simply use a compiler switch to do this. A very good example is placing source and test files in different locations. Take the following structure (an outcome of my previous post). The app/ folder only contains .ts files. The test/ and www/script folders are expected to have the compiled .js

project/
    app/
        script/
        test/
    test/
    www/
        script/

Now if you want to compile your scripts and your tests (from app) to go into two different locations (respectively www/script/ and test/), it’s not as simple as running two tsc commands with the related source and destination paths. Since the test files will reference the files in app/script/ the compiler will recompile the referenced files and place them in test/.

There are two ways to deal with this. For both of them you will need to use a workflow management tool like Grunt to make them work sensibly.

Using Declarations

One way to go is, to avoid referencing .ts files that are not within a compilation target. Instead generate definition files (.d.ts) and reference them. In our example case we have two compilation targets – app/script/ and app/test/. In this case we avoid referencing the .ts files in app/script/ within the test files in app/test/. Instead we generate .d.ts files for all .ts files in app/script/ and then reference them in the test files in app/test/.

This can be done with the compiler switch --declaration when using tsc. For grunt-typescript task you can use declaration: true option to do the same. So your Grunt workflow would look like.

  1. When writing your test files in app/test/ make sure to add the references to the source files as a .d.ts (not yet available) instead of .ts.
  2. Compileapp/script/ with the --declaration option which will generate the .d.ts files in the same location as the .ts files.
  3. Compile app/test/  to test/ .

Using similar relative paths

You can use a single compilation command/step which will compile all the files into relative paths. This however alone is not going to solve our problem in the above example. Lets look at how this works.

This time we use a single compile step targeting app/ and everything in there to www/ which will create www/script/ and www/test. This method does not duplicate the .js files, but it puts the test/ in the wrong place. We can fix this by adding two more steps into the workflow. Lets look at how our workflow is going to be when we use this approach.

  1. Compile app/  to www/  which will create both the script and test folders in the www/
  2. Use the grunt copy task to copy the www/test/ back to the root of the project.
  3. Use the grunt clean task to delete the www/test/ .

Of course you can be done with the first step if your source path and destination path are both relatively same. If you are able to structure you project in such way life will be quite easy for you.

Conclusion

These workarounds don’t solve bigger problems such as the need to compile only the files that are changing. This becomes a nightmare in very large code bases where you have workflow configured to watch and compile only file that are changing.

Hopefully TypeScript team will put in a sensible solution for this in future releases. If you would like to add something to this please post it in the comments.