Exclude node_modules directory for TypeScript compilation, but allow one individual subdirectory - node.js

The whole node_modules directory can be completely excluded for TypeScript compilation using this tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"sourceMap": true,
"target": "es6"
},
"exclude": [
"node_modules"
]
}
But how can I allow one individual sub-directory under node_modules, like node_modules/app, to still get compiled? I know that the files section can be used to specify individual files and override the exclude section, but that can get unwieldy very quickly, especially when used alongside exclude. Is there a better option?
For a bit of context, I am planning to put application-specific modules in the node_modules/app directory, so I can require them without using relative paths:
var m = require("app/module1")
versus
var m = require("../../module1")).

Just require the module/subfolder that contains your code. Explicitly importing a file/directory overrides the global "exclude" in a sense that it will be picked up by tsc.
Also set "moduleResolution": "node" if you haven't already.

Related

How to stop typescript compiling files *above* `../` the current src dir?

I am developing a package within a larger project, but compiling the package also tries to run all tests from further up the hierarchy. Is there any way to stop this?
app
node_modules
packages/
mypackage/
src/
when I run tsc inside mypackage it will look for files above, all the way to my home directory.
Now, I can compile and build outside my app, and all is good, but for reasons of distribution I wanted to compile things directly inside.
I tried with rootDir and exclude but to no avail.
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"declaration": true,
"outDir": "./dist",
"strict": true,
"rootDir": "./src",
},
"include": [
"./src"
],
"exclude": [
"../../../node_modules",
"node_modules",
"**/node_modules/**",
]
}
the errors look like this:
../../../node_modules/#types/jest/index.d.ts:43:13
43 declare var xit: jest.It;
~~~
'xit' was also declared here.
Found 7 errors in the same file, starting at: ../../../node_modules/#types/mocha/index.d.ts:2642
update found this issue, but not sure if there is a solution. Letting tsc pull in random files from throughout your directory tree, outside the current .src, seems really dangerous behavior to allow TS to do.
https://github.com/microsoft/TypeScript/issues/9858
similar

Typescript Establishing Absolute Imports Node

I built a project in node using TS, and I'm trying to implement absolute path for imports.
However, when I run the project it begins failing saying.
[1] Error: Cannot find module 'src/common/logger'
[1] Require stack:
[1] - C:\...xyz\Workspaces\PROJECT\dist\index.js
When I switch 'src/common/logger' to './common/logger' it proceeds to point to other ones that absolute path imports.
I figure its obviously something wrong with my TS config, but I can't seem to see where I am messing up.
Ultimately I want the imports to become 'common/xyz' and 'db/xyz'
My project directory follows this flow:
├───tsconfig.json
├───node_modules
├───dist // output location
└───src
|───common
|───db
└───index.ts
{
"compilerOptions": {
/* Language and Environment */
"target": "es2021",
/* Modules */
"module": "commonjs",
"rootDir": "./src",
"moduleResolution": "node",
"baseUrl": ".",
"paths": {
"src/*": ["./src/*"],
"/*": [ "./src/*" ],
},
"outDir": "./dist"
}
}
My thought is that the issue is how I set up the tsconfig.
I tried looking through the documentation, but I clearly am not understanding the paths section. I've tried several changes to the paths, but still can't seem to get it work.
Any help would be greatly appreciated.
Leaving this bread trail for people who come across this issue.
TLDR; There is no way with tsconfig only to do it. You would need to use packages such as Webpack, Gulp, or other npm packages to help resolve the absolute imports.
My advice:
If you are working on just getting the project up and running, stick with relative imports for now. Then you can look into the 3rd party tools to implement the absolute pathing.

Does it make sense to transpile TypeScript test code when using ts-jest?

I am just wondering if the JavaScript files generated from the TypeScript test files could be of any use later, since type-checking if part of their job (testing), what could we use their JavaScript form for?
Concretely, my tsconfig.json looks like this:
{
"include": ["./src/**/*"],
"exclude": ["./src/__tests__/**/*"],
"compilerOptions": {
"rootDir": "./src",
"outDir": "./build",
...
}
}
I am excluding all test files, they are stored in the ./src/__tests__ folder.
So my question comes down to should I keep the exclude setting or not ? What would I need the generated JavaScript test files for ?

How to specify the distributable directory visible for both NPM and TypeScript? (Multiple files case)

The library written in TypeScript includes three main files for distribution:
NodeJS.js - for, obviously, Node.js runtime.
BroswerJS.js - for, obviously, browser runtime.
index.js - common functionality for both browser and Node.js
There no "main" file in this library so I has not specified this property in package.json.
Planning usage:
import { isUndefined, isNull } from "package-name;
import { delegateClickEventHandling } from "package-name/BrowserJS;
import { NodeJS_Timer } from "package-name/NodeJS;
Currently, the TypeScript with below config compiles files below Source directory to Distributable directory:
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"moduleResolution": "Node",
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"removeComments": true,
"outDir": "Distributable/",
"declaration": true
},
"include": [ "Source/**/*" ]
}
If to publish the library such as, TypeScript even will not see it:
import { isUndefined } from "package-name";
TS2307: Cannot find module 'package-name' or its corresponding type declarations.
Because as default TypeScript expecting that .d.ts files will be in root directory of the library. But the distributables are in Distributable directory!
And of course, isUndefined will not be found. I know about "main" property in package.json, but it is for one file case, but what about directory?
I know that multiple distributable files exporting is the supported scenario. For example the mysql2 exporting promise.ts besides index.js:
import MySQL from "mysql2";
import MySQL_Promise from "mysql2/promise";
Update
The NPM part solved - modern solution is exports filed in package.json:
"exports": {
".": "./Distributable/index.js",
"./NodeJS": "./Distributable/NodeJS.js",
"./BrowserJS": "./Distributable/BrowserJS.js"
},
But distribution files are still invisible for TypeScript.
TS2307: Cannot find module 'package-name' or its corresponding type declarations.
I learned about "types" field of package.json. Unfortunately, it could be only a string. It means currently it's impossible to specify multiple files. The issue about making in to array has been declined.
But how to make visible all of "./Distributable/index.js", "./Distributable/NodeJS.js", "./Distributable/BrowserJS.js" for TypeScript?
Please don't suggest me again to make all imports to single entry point. In this question we considering the multiple entry points case.
I am not entirely sure what you are trying to achive, in TS generally when you have single project with 1 configuration file, and you emit multiple files from it, you would not use package name within the same project, use path instead './someFileName'.
If you have multiple projects (tsconfig files) to manage different directories - sort of monorepo thing going on.
Your best options is project references: https://www.typescriptlang.org/docs/handbook/project-references.html
Or if you are doing something else then this may help altho I'd do this as last resort :-)
https://www.typescriptlang.org/tsconfig#paths

Why does `allowJS` cause an unwanted `src` subdirectory in my compiled output?

I'm converting a legacy node/express codebase to TypeScript, following the Microsoft TypeScript starter as a starting reference.
In this reference output is compiled to dist, however when enabling allowJS in tsconfig.json, the output is emitted to dist/src - why is that?
Here is my tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"noImplicitAny": false,
"moduleResolution": "node",
"sourceMap": true,
"rootDir" : "./",
"outDir": "dist",
"baseUrl": ".",
"allowJs": true,
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src/**/*"
]
}
I tried changing rootDir to ./src but it gives an error saying 'node_modules/someModule' is not in the src root.
I tried moving tsconfig.json to src, according to a GitHub issue I saw, but no output was generated.
AllowJS
The output was mapping correctly under /dist until allowJS flag was turned on in tsconfig.json, after which output appeared in /dist/src
There are two things going on here:
Typescript relies on rootDir to decide the directory structure of the output (see this comment from Typescript's bossman).
Only code within the rootDir can be compiled/emitted by tsc.
If you don't set rootDir explicitly, it defaults to ./ (relative to tsconfig)... unless you've included something outside of ./ that needs to be compiled/emitted by tsc, in which case it forces rootDir to automatically get set to the directory that contains all the source.
The allowJS setting tells tsc to treat .js code as source and to also emit it to the outDir.
I suspect that when you enabled allowJS, there was .js code outside of src that tsc now had to emit to outDir, and so it automatically moved rootDir one level up. Since src is now a subdir of the rootDir, this gets mirrored within outDir.
See this answer for a solution that enables you to have src remain a rootDir and also include code from outside of it.
Sounds like your compiler (TSC) config file may be up a level from where you want the transpiler to begin the linking process. Can you try pushing it down a level and let us know what happens?
Hope this helps.

Resources