TypeScript External Module Loading from node_modules

Topics: General
Jul 8, 2013 at 10:14 AM
So the v0.9 syntax for loading external modules is:
import moduleAlias = require("../path/to/module");
My issue is I'd like to be able to import modules installed in node_modules of the current node package using the same syntax as JavaScript. I always include a definition file in my node module packages. Unfortunately, unless you use the syntax where a module is declared with a string literal for a name, there is no way to import without providing a path like: "node_modules/module_name/module_name" or including the definition file in the same directory as the file that takes a dependency on the module.

Node will automatically alias the node_modules directory for require calls. It would be awesome if there were someway to do one of the following:
  1. When using the -d flag in tsc, be able to tell the compiler to wrap the contents in a declare module "module_name" { } wrapper, where module_name is the package name specified in package.json. This way, any reference to the .d.ts file would allow for require("module_name") instead of require("node_modules/module_name/module_name").
  2. Automatically look in each installed module in the nearest parent node_modules folder for a .d.ts file where the file name matches the module name. If one exists, allow for require("module_name") without providing a module reference at the head of the dependent file.
Jul 8, 2013 at 9:31 PM
These are good suggestions but I did want to point out a workaround for number 1. Let tsc generate your declare file using internal modules via the -d flag. Then create a separate .node.d.ts file which references the generated file and exports the internal module as an external module using the new exports = syntax.

So lets say you compile tsc -d foo.ts which generates the foo.d.ts file below:
declare module foo {
     export function bar();
Create a file called foo.node.d.ts with the code below:
/// <reference path='foo.d.ts'/>

declare module "foo" {
     export = foo;
You'll still need to add a reference to "node_modules/foo/foo.node.d.ts" in your files that consume the module but at least you'll be able to import it without an absolute path. So:
/// <reference path='node_modules/foo/foo.node.d.ts'/>

import foo = require('foo');
Jul 8, 2013 at 10:05 PM
Ah! Awesome. Thanks for the suggestion! I would still love for a supported way in the compiler to make this process easier, but this will definitely do for now.

Another possible solution would be an alias attribute in the reference XML element:
/// <reference path='node_modules/foo/foo.d.ts' alias='foo.d.ts' />

import foo = require('foo');