typescript-ruby / typescript-rails

An asset pipeline wrapper for the TypeScript language
MIT License
255 stars 29 forks source link

typescript-rails compiler does not pass TS file dependencies to Sprockets #23

Closed wtmcc closed 9 years ago

wtmcc commented 9 years ago

I’m involved in a project where we’re migrating a TypeScript build chain from grunt to Sprockets and the Rails Asset Pipeline, using typescript-rails. We’ve had problems getting Sprockets to recognize changes in referenced TS files, and as a result we have to make an arbitrary change in the root TS file to force a cache invalidation any time we want a TS recompile.

Here’s how I understand things:

Sprockets expects to build its dependency graph by recursively parsing require directives embedded in JS source files, and in-lining their processed referents.

TypeScript’s idiom (which we’ll want to play along with so that type checking works) expects to build its dependency graph by parsing reference tag comments.

Our use of typescript-rails only ever has Sprockets process the root application.ts file. The rest of the files are brought in by embedded <reference /> tags.

This means Sprockets has no idea that all the files listed in embedded <reference /> tags are dependencies of application.ts.

And that means when any TS file other than application.ts changes, Sprockets doesn’t invalidate its cache of application.ts, even though it should.

Proposed fix

Have the compiler wrapper recurse through the whole dependency tree, and manually tell its Sprockets::Context that the TS file being processed depends_on each file listed as a reference in the TS idiom.

I’m opening a PR implementing the proposed behavior. There may be some trivial tweak to our configuration that I’ve overlooked, so feel free to let me know if my approach seems heavy-handed or unnecessary!

joamaki commented 9 years ago

I worked around this issue by declaring a dependency before the reference:

/// <reference path="foo.js.ts" />
//= depend_on foo.js.ts
wtmcc commented 9 years ago

@joamaki: Good tip. That totally works for simple projects, but in our case it’d mean declaring almost 200 Sprockets-style .ts dependencies in our root file, in addition to our existing TS-style declarations in reference.ts. In our case, having a single, authoritative source of truth does a lot to make the codebase more manageable.

wtmcc commented 9 years ago

This was resolved by #24.