New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compiler fails to find external module referenced by two different files #2192

Closed
michael-terry opened this Issue Mar 4, 2015 · 18 comments

Comments

Projects
None yet
8 participants
@michael-terry

michael-terry commented Mar 4, 2015

(Also posted on StackOverflow: https://stackoverflow.com/questions/28844917/typescript-cant-find-external-module-when-referenced-by-two-different-files)

I may be missing something obvious, but Typescript's module resolver for commonjs isn't working as expected.

Given the following directory structure and files:

  • ./first/shared.ts
  • ./first/second/class_a.ts
  • ./first/second/class_b.ts
  • ./third/class_c.ts

Where:

  • class_a references shared.ts
  • class_b references class_a.ts and class_c.ts
  • class_c references shared.ts

Specifically:

shared.ts:

class Shared{}
export = Shared;

class_a.ts:

import Shared = require('../shared');
class A{}
export = A;

class_b.ts:

import A = require('./class_a');
import C = require('../../third/class_c');
class B {}
export = B;

class_c.ts:

import Shared = require('../first/shared');
class C {}
export = C;

All compile individually, except class_b.ts, using the following compiler invocation:

tsc --module commonjs class_b.ts

Compiling class_b.ts fails with the error that it can't find shared.ts:

../../third/class_c.ts(1,25): error TS2307: Cannot find external module '../first/shared'.

Note that if you reverse the order of imports in class_b.ts, you get a different error:

class_a.ts(1,25): error TS2307: Cannot find external module '../shared'.

It seems the compiler is finding shared.ts the first time it is imported, but not the second time.

This is with tsc 1.4.1.0.

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Mar 4, 2015

Contributor

the problem is how files are named when relative path are used. as a work around, wither call the compiler from the root directory, or pass in absolute paths.

Contributor

mhegazy commented Mar 4, 2015

the problem is how files are named when relative path are used. as a work around, wither call the compiler from the root directory, or pass in absolute paths.

@mhegazy mhegazy added this to the TypeScript 1.6 milestone Mar 26, 2015

@canmrt

This comment has been minimized.

Show comment
Hide comment
@canmrt

canmrt May 22, 2015

@mhegazy : can you please provide an example of how to run a gulp/grunt task from the root directory to bypass this issue? Currently this is a blocker issue, since I'm using only external modules.

canmrt commented May 22, 2015

@mhegazy : can you please provide an example of how to run a gulp/grunt task from the root directory to bypass this issue? Currently this is a blocker issue, since I'm using only external modules.

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy May 22, 2015

Contributor

@canmrt how is this happening with grunt or gulp? if i understand correctly, you have a build file, possibly at the root of your project, and you will always be calling it from the same place.. is that accurate? what is the issue you are seeing?

Contributor

mhegazy commented May 22, 2015

@canmrt how is this happening with grunt or gulp? if i understand correctly, you have a build file, possibly at the root of your project, and you will always be calling it from the same place.. is that accurate? what is the issue you are seeing?

@niemyjski

This comment has been minimized.

Show comment
Hide comment
@niemyjski

niemyjski Jun 1, 2015

+1 with a external module.

niemyjski commented Jun 1, 2015

+1 with a external module.

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 7, 2015

have the same issue, without any relative path, I had next schema
server.ts -> uses few imports e.g. import require('mongoose') etc..
from server.ts I'm refering to modile dto/elmyDatasource.ts and it's working fine, once I'm adding same imports to dto/elmyDatasource.ts this module not able to find in server.ts. Is there any way to reuse imports in all files?

sneerin commented Jun 7, 2015

have the same issue, without any relative path, I had next schema
server.ts -> uses few imports e.g. import require('mongoose') etc..
from server.ts I'm refering to modile dto/elmyDatasource.ts and it's working fine, once I'm adding same imports to dto/elmyDatasource.ts this module not able to find in server.ts. Is there any way to reuse imports in all files?

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 7, 2015

log is next : [gulp-typescript] 2304 Cannot find name 'DBBackend'.

file: /Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/server/server.ts:
[35]

/Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/node_modules/gulp-typescript/release/output.js:161
var references = file.original.ts.referencedFiles.map(function
^
TypeError: Cannot read property 'ts' of undefined

sneerin commented Jun 7, 2015

log is next : [gulp-typescript] 2304 Cannot find name 'DBBackend'.

file: /Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/server/server.ts:
[35]

/Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/node_modules/gulp-typescript/release/output.js:161
var references = file.original.ts.referencedFiles.map(function
^
TypeError: Cannot read property 'ts' of undefined

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 7, 2015

Is there any workaround for this, without this workaround I can't use external files at all

sneerin commented Jun 7, 2015

Is there any workaround for this, without this workaround I can't use external files at all

@ivogabe

This comment has been minimized.

Show comment
Hide comment
@ivogabe

ivogabe Jun 8, 2015

Contributor

@sneerin It looks like you're using an older version of gulp-typescript, can you try upgrading to the latest release?

Contributor

ivogabe commented Jun 8, 2015

@sneerin It looks like you're using an older version of gulp-typescript, can you try upgrading to the latest release?

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 8, 2015

I updated and now having even more troubles, I have a class:

 class Backend {
        public server:any;

        private dbUtils:DbUtils;

        constructor() {
          //  debug.log("starting server");
          //  this.startServer();

            debug.log("init mongo");
            this.initDb();

            debug.log("init routes");
            this.initRoutes();

        }

        startServer():void {
            this.server = restify.createServer();
            this.server.use(restify.bodyParser());
            this.server.listen('8080', ()=> {
                debug.log('listening port: 8080');
            })
        }

and this during compilation cause next that happened for commented part of the file( :

file: /Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/server/server.ts:
[66] // this.startServer();
/Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/node_modules/gulp-typescript/release/output.js:162
var references = file.original.ts.referencedFiles.map(function

sneerin commented Jun 8, 2015

I updated and now having even more troubles, I have a class:

 class Backend {
        public server:any;

        private dbUtils:DbUtils;

        constructor() {
          //  debug.log("starting server");
          //  this.startServer();

            debug.log("init mongo");
            this.initDb();

            debug.log("init routes");
            this.initRoutes();

        }

        startServer():void {
            this.server = restify.createServer();
            this.server.use(restify.bodyParser());
            this.server.listen('8080', ()=> {
                debug.log('listening port: 8080');
            })
        }

and this during compilation cause next that happened for commented part of the file( :

file: /Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/server/server.ts:
[66] // this.startServer();
/Users/mdomarev/workspace/singularex/angular-typescript-gulp-seed/node_modules/gulp-typescript/release/output.js:162
var references = file.original.ts.referencedFiles.map(function

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 8, 2015

I don't know what's wrong, but I'm about to giveup using typescript, I did many tricks, and it finally compiles, however when I'm staring node.js sever it is said my require imports with relative path wasn't able to find.

sneerin commented Jun 8, 2015

I don't know what's wrong, but I'm about to giveup using typescript, I did many tricks, and it finally compiles, however when I'm staring node.js sever it is said my require imports with relative path wasn't able to find.

@sneerin

This comment has been minimized.

Show comment
Hide comment
@sneerin

sneerin Jun 8, 2015

is there any good structured with classes and modules sample of code for server node.js and commonjs modules?

sneerin commented Jun 8, 2015

is there any good structured with classes and modules sample of code for server node.js and commonjs modules?

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Jun 9, 2015

Contributor

@sneerin can you share the full application, or more error information. i can not piece together what you are trying to do from the information provided.

Contributor

mhegazy commented Jun 9, 2015

@sneerin can you share the full application, or more error information. i can not piece together what you are trying to do from the information provided.

@gravidThoughts

This comment has been minimized.

Show comment
Hide comment
@gravidThoughts

gravidThoughts Sep 16, 2015

@mhegazy
"the problem is how files are named when relative path are used. as a work around, wither call the compiler from the root directory, or pass in absolute paths."

How do I call the compiler from a root directory in a VS blank node.js console project?

gravidThoughts commented Sep 16, 2015

@mhegazy
"the problem is how files are named when relative path are used. as a work around, wither call the compiler from the root directory, or pass in absolute paths."

How do I call the compiler from a root directory in a VS blank node.js console project?

@gravidThoughts

This comment has been minimized.

Show comment
Hide comment
@gravidThoughts

gravidThoughts Sep 16, 2015

My situation is slightly different than OP I am not using tsc directly.
Clean blank node.js console project, VS 2013 Update 5.
npm install inversify --save-dev

app.ts

import inversify = require('node_modules/inversify/source/inversify');
var kernel = new inversify.Kernel();

The above builds without issue, I get my lovely intellisense.
I get the following runtime error.

Debugger listening on port 5858
module.js:338
    throw err;
          ^
Error: Cannot find module 'node_modules/inversify/source/inversify'
    at Function.Module._resolveFilename (module.js:336:15)
...

Using the absolute path works, but obviously is a non starter in a distributed enterprise project with multiple developers.

I tried setting the working directory in the project properties to the root of the project, but this did not solve the issue.

gravidThoughts commented Sep 16, 2015

My situation is slightly different than OP I am not using tsc directly.
Clean blank node.js console project, VS 2013 Update 5.
npm install inversify --save-dev

app.ts

import inversify = require('node_modules/inversify/source/inversify');
var kernel = new inversify.Kernel();

The above builds without issue, I get my lovely intellisense.
I get the following runtime error.

Debugger listening on port 5858
module.js:338
    throw err;
          ^
Error: Cannot find module 'node_modules/inversify/source/inversify'
    at Function.Module._resolveFilename (module.js:336:15)
...

Using the absolute path works, but obviously is a non starter in a distributed enterprise project with multiple developers.

I tried setting the working directory in the project properties to the root of the project, but this did not solve the issue.

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Sep 17, 2015

Contributor

@gravidThoughts, in TS 1.6 we now have support to importing types from npm packages. your package author needs to export the typings. inversify package author will need:

  • build with --declarations (generate inversify.d.ts)
  • set typings field in package.json to point to inversify.d.ts

with that in place, you should be able to do something like:

import * from "inversify"

and it should work for your typings and at runt time.

You can find more about this in https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages
and check out the typescript package definition here:

"typings": "./lib/typescript.d.ts",

Contributor

mhegazy commented Sep 17, 2015

@gravidThoughts, in TS 1.6 we now have support to importing types from npm packages. your package author needs to export the typings. inversify package author will need:

  • build with --declarations (generate inversify.d.ts)
  • set typings field in package.json to point to inversify.d.ts

with that in place, you should be able to do something like:

import * from "inversify"

and it should work for your typings and at runt time.

You can find more about this in https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages
and check out the typescript package definition here:

"typings": "./lib/typescript.d.ts",

@gravidThoughts

This comment has been minimized.

Show comment
Hide comment
@gravidThoughts

gravidThoughts Sep 17, 2015

@mhegazy That sounds great. I look forward to it.
2 Questions.
First, does the package author need to do the same for their bower package?
Second, I still have to use an absolute path for my internal project modules.

vehicle.ts (same directory as app.ts)

export class vehicle{ ... }
export class car extends vehicle { ... }

app.ts

import vehicle = require('vehicle');
var myCar = new vehicle.Car();

Above still gets the runtime exception can't find module. Using an absolute path works.

Is this the same issue as encountered by the OP?

gravidThoughts commented Sep 17, 2015

@mhegazy That sounds great. I look forward to it.
2 Questions.
First, does the package author need to do the same for their bower package?
Second, I still have to use an absolute path for my internal project modules.

vehicle.ts (same directory as app.ts)

export class vehicle{ ... }
export class car extends vehicle { ... }

app.ts

import vehicle = require('vehicle');
var myCar = new vehicle.Car();

Above still gets the runtime exception can't find module. Using an absolute path works.

Is this the same issue as encountered by the OP?

@mhegazy

This comment has been minimized.

Show comment
Hide comment
@mhegazy

mhegazy Sep 17, 2015

Contributor

First, does the package author need to do the same for their bower package?

there is not a special bower package handling. what are your expectations here?

Second, I still have to use an absolute path for my internal project modules.

if the file is local, use relative path to find it, e.g. require("./vehice")

Contributor

mhegazy commented Sep 17, 2015

First, does the package author need to do the same for their bower package?

there is not a special bower package handling. what are your expectations here?

Second, I still have to use an absolute path for my internal project modules.

if the file is local, use relative path to find it, e.g. require("./vehice")

@gravidThoughts

This comment has been minimized.

Show comment
Hide comment
@gravidThoughts

gravidThoughts Sep 18, 2015

@mhegazy

there is not a special bower package handling. what are your expectations here?

Typescript enabled components are distributed in Bower. If the package distributes a d.ts and specifies the typings propety in bower.json, will 1.6 behave be the same for Bower packages as it will for npm?

if the file is local, use relative path to find it, e.g. require("./vehice")

I have posted a new issue concerning this.#4857

gravidThoughts commented Sep 18, 2015

@mhegazy

there is not a special bower package handling. what are your expectations here?

Typescript enabled components are distributed in Bower. If the package distributes a d.ts and specifies the typings propety in bower.json, will 1.6 behave be the same for Bower packages as it will for npm?

if the file is local, use relative path to find it, e.g. require("./vehice")

I have posted a new issue concerning this.#4857

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.