Search code examples
javascripttypescriptrequirejsamdtypescript-typings

TypeScript 1.8 relative module name resolution in AMD style modules with RequireJS 2.1


I am trying to use TypeScript in a part of a legacy JS system. In this system, many applications exist that get executed in a RequireJS environment where the main.js will execute when that application is launched. I have created this structure

App1/
   main.js
   app.ts
   Modules/
      myModule.ts
      Models/
         model1.js
         model2.js

Models are generated codes and have to stay as .JS files. Models should be required by 'Require' statements from different .ts modules.

I know how to use something like this in a Declaration file in modules folder to let the .ts files compile.

   declare module "Models/model1" { var x:any; export = x;}  

But the code will not execute because this will create such an AMD module definition for myModule.ts

define(["require","exports","Models/model1", function(require,exports,model){ ...

but the path gets resolved by Require.JS as

 http://mysite/Models/model1.js

which is missing path sections because path is relative and has to be absolute from RequireJS's context root. I can not have models as TS because they are generated files. They don't compile just by renaming to .ts also non-relative paths are not usable due to different ways the application runs in harnesses, production and unit-test setups.

Question: Is there a way to get TypeScript to generate relative paths for JavaScript (.js) modules?


Solution

  • Have you looked into Triple-Slash Directives? As of TypeScript 2.0 this has been deprecated for import "moduleName" but should work for older versions:

    /// <amd-dependency path="x" /> informs the compiler about a non-TS module dependency that needs to be injected in the resulting module’s require call.

    The amd-dependency directive can also have an optional name property; this allows passing an optional name for an amd-dependency:

    /// <amd-dependency path="legacy/moduleA" name="moduleA"/>
    declare var moduleA:MyType
    moduleA.callStuff()
    

    Generated JS code:

    define(["require", "exports", "legacy/moduleA"], function (require, exports, moduleA) {
        moduleA.callStuff()
    });