Typescript: `module `...` was resolved to '...', but '--allowJs' is not set` error for explicit node_module import

Created on 20 May 2017  路  12Comments  路  Source: microsoft/TypeScript



TypeScript Version: 2.3.2

Code

Project layout:

|__node_modules/
|  |__foo/
|     |__foo.js
|__src/
   |__index.ts

tsonfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "module": "es2015",
    "moduleResolution": "node",
    "outDir": "lib",
    "rootDir": "src",
    "target": "esnext"
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"   
  ], "exclude": [
    "node_modules/**/*",
    "third_party/**/*"
  ]
}

index.ts:

import * from '../node_modules/foo/foo.js';

Expected behavior:

Compilation works

Actual behavior:

error TS6059: File '/Users/justin/Documents/Projects/test/node_modules/foo/foo.js' is not under 'rootDir' '/Users/justin/Documents/Projects/test/src'. 'rootDir' is expected to contain all source files.
error

My lib/ directory, which should contain just the compiled contents of src/ contains src/ and node_modules/ subdirectories.

If I remove allowJs, then tsc complains that I'm importing JS and need to add the option.

Bug Fixed

Most helpful comment

If you're using typescript, just rename the file extension to .ts instead of .js. (foo.ts) .
Then when you import, do not use the file extension:
import ( Foo ) from '../node_modules/foo/foo';

All 12 comments

there are a few issues going on here. first --allowJs combined with the import makes the compiler think the node_module is part of your sources, and it will compile it for you, so your output will have node_modules\foo\foo.js, do not think this is what you had in mind.

If I remove allowJs, then tsc complains that I'm importing JS and need to add the option.

I believe this is the real bug here that needs to be fixed. if the file is found on disk, you should not get this error message.

With allowJs on, we are running into a similar issue like the one described in #15755

I had the same problem. I did typings dt~mypackage --save --global and the problem was solved.

Huge bummer in my early learning stage, I've been like a week trying to find a workaround!. Same experience, turning allowJs ON mess up the entire Angular app. I'd have expected to turn it on for arbitrary directories/files.

If you're using typescript, just rename the file extension to .ts instead of .js. (foo.ts) .
Then when you import, do not use the file extension:
import ( Foo ) from '../node_modules/foo/foo';

@coffeenexus vs code says foo.ts is not a node module

@aritrabasu104 To be a module it must have an export somewhere. If you were using module.exports = ... or exports.x = ... before you'll need to switch to an ES6 syntax when converting to TypeScript.

@andy-ms hi, is there any way to use exports.x rather than switch to ES6 syntax? Such as transpiling?

@AbnerZheng There's no way to transpile "up" from commonjs to es6. It you're writing JS code you can use commonjs syntax, but it isn't allowed in TypeScript.
We are working on a way to automatically refactor your code from commonjs to es6: #19719.

@andy-ms, as I know, refactor means a action .So after refacting, my file's content will be changed,from "module.export " to exports, rather than changing the behavior of tsc. Is this right?

I'm now working with vscode/webstorm intelligense autocompletion of eggjs framework. Since eggjs have d.ts files, the function autocompletion works well. But there are some problems. We use declartion merge of ts to mixin user's custom Controller/or Service singleton to eggjs's type definition. For example,
'''egg.d.ts'''
export interface IService{}

now I use declartion merge, creating a file:
'''egg.dm.ts'''
import {IService} from "egg"
import {HomeController} from "./home.js"
declare IService{
home: HomeController
}

'''home.js'''
class HomeController extend require('egg').IService{
test (){}
}
module.export = HomeController

This doesn't work, But When I change to the way of exports default HomeController. All works great.
Is there any suggestion to fix it?

import {HomeController} from "./home.js" is a named import. You might mean import HomeController = require("./home.js").

Another problem: In home.js you write extend require('egg').IService, but you can't extend an interface, and at runtime this will presumably fail since IService doesn't actually exist.

May be a good idea to just write a home.d.ts to avoid switching between .ts and .js so much.

@andy-ms Yes, you're right. These two problem exist, and after I fixed them, it still won't work. But as I change the way export to es6, everything works fine.
Since user/third party plugin may not write their own d.ts, so maybe I have to generate home.d.ts for these module.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Antony-Jones picture Antony-Jones  路  3Comments

CyrusNajmabadi picture CyrusNajmabadi  路  3Comments

wmaurer picture wmaurer  路  3Comments

dlaberge picture dlaberge  路  3Comments

DanielRosenwasser picture DanielRosenwasser  路  3Comments