OK so I have an interesting situation in setting up my Node.js TypeScript project. I want to be able to refer to my local modules using a non-relative require
reference. The way TypeScript and Node.js look up modules is to look for a node_modules
directory in the current directory and then each parent directory until they find such a directory containing the reference. So let's say I have a module I want to reference in the following directory structure:
/node_modules <-- Main NPM modules dir
/...
/package.json
/src
/node_modules <-- My local modules dir
/modules
/myModule.ts
/scripts
/init.ts
... and in init.ts
I reference myModule
like this:
import myModule from "modules/myModule";
As I understand it, I want TypeScript to transpile my node_modules
directory over to the output dist
directory along with all my other .ts
file directories, so that the dist
directory looks like this:
/node_modules <-- Main NPM modules dir
/...
/package.json
/dist
/node_modules <-- My local modules dir
/modules
/myModule.js
/scripts
/init.js
Then, when Node.js looks for the module it will find it at dist/node_modules/modules/myModule.js
. So in this case I actually do want TypeScript to include the node_modules
directory in its input files. I seem to be missing something fundamental, though, because TypeScript actually ignores this directory by default.
Is my scenario a legitimate one for including the node_modules
directory, and if so, how can I make TypeScript include it in the transpilation when I just run tsc
(and therefore it will use my tsconfig.json
file)?
UPDATE:
I have found that I can make it include my node_modules
directory by explicitly putting it in the include
directive in the .tsconfig.json
like so:
"include": [
"./src/node_modules/**/*",
"./src/**/*"
]
The question remains; am I getting something fundamentally wrong here, because I am having to override something TypeScript excludes by default? I've tested this and when I make it transpile node_modules
, it does indeed find my local modules correctly.
That's not correct to include node_modules
for transpilation. Because node_modules
contains javascript and doesn't requires second transpilation in case of ts libraries, they should have declarations in .d.ts
.
If you have custom types, or you want to add types to some libraries that don't have them, you need to use own declarations or @types/*
packages.
in your tsconfig.json
you can define type roots (where to load declarations from).
{
"compilerOptions": {
"typeRoots": ["./declarations", "./node_modules/@types"],
"types": ["node"],
}
}
then you can install npm i --save-dev @types/node@^12
for example to get declarations of nodejs v12.
and define your own declarations in declarations
for express
for example: ./declarations/express/index.d.ts
import * as express from 'express';
declare module 'express' {
export interface Request {
user?: {
id: string;
name: string;
}
}
}