Reputation: 1903
I have the bluebird
module along with @types/bluebird
installed in a node_modules
folder.
I also have some .ts
files that will be bundled using Webpack and be used in a browser.
For various reasons the node_modules
folder is outside the path hierarchy of my .ts
files.
I would like to import the bluebird
module in my .ts
files such that:
If the node_modules
was in the right place in the path hierarchy I could simply do this:
import * as Promise from 'bluebird'
The Typescript compiler (through the ts-loader
) resolves to the type definitions in node_modules/@types/bluebird
and type checks the code and Webpack resolves to the actual module in node_modules/bluebird
and emits it in the bundle.
With an external node_modules
folder however, I cannot get this to work.
So far I am able to get it so that Typescript is happy but not Webpack.
1. Setting baseURL
and paths
in tsconfig.ts
The most obvious solution to me seemed to be to set the baseURL
and setup a paths
into the node_modules
in tsconfig.json
like so (shared
contains the node_modules
folder):
"baseUrl": "..",
"paths": {"shared/*":["shared/*"]}
However I am not able to do:
import * as Promise from 'shared/node_modules/bluebird'
I need:
import * as Promise from 'shared/node_modules/@types/bluebird/index'
But this import does not work for Webpack. It either can't find it, or if I configure it to find it, ts-loader will not like to compile it (because it is a declaration file), or if I configure it to ignore it, it will crash at runtime because it is not there.
2. Relative Import
I tried specifying a relative path in to the node_modules
folder but ended up with roughly the same problem.
Upvotes: 4
Views: 3200
Reputation: 1903
I employed a somewhat hacky solution to this problem.
The crux of the problem I was having was that I needed a single import
statement to be resolved in different ways by Typescript and Webpack. Typescript needs to resolve it to the type definitions, and Webpack needs to resolve it to the module.
To acheive this I used paths
in tsconfig.json
to point the import to the type definitions, and resolve.alias
in the webpack.config.js
to point the same import to the acutal module.
tsconfig.json:
{
"compilerOptions": {
"baseUrl":"..", // you need this to set paths below.
"paths":{
"shared/bluebird":["shared/node_modules/@types/bluebird/index"]
}
...
}
}
webpack.config.js
resolve: {
alias: {
"shared/bluebird": path.resolve(__dirname, '../shared/node_modules/bluebird')
}
...
}
This allows me to do:
import * as Promise from 'shared/bluebird'
and Typescript and Webpack are both happy.
Upvotes: 3