error TS2307: Cannot find module 'app' - node.js

I want to use typescript on node side. I have a very simple server. tsconfig.file inside my server folder is as follows:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"outDir": "../dist/serverBuild",
"typeRoots": [
"../node_modules/#types"
]
},
"exclude": [
"../node_modules"
]
}
I have an app.ts file which has express related configuration in it and then I have server.ts file which is importing app module from app.ts and it has code to create and start the node server.
But I am getting following error:
TSError: тип Unable to compile TypeScript
server.ts (11,22): Cannot find module 'app'. (2307)
other modules that I am importing in my server.ts file like http module is not throwing any such error. What am I doing wrong here.
Here is how I am importing modules:
import * as http from "http";
import * as app from "app";
Thanks!

To load files from your project include the path. Use:
import * as app from './app';
By using from 'app' you are saying there is a module named app installed in your project. If that was the case you would need to install the typings for that module or create it yourself.

Related

Typescript/Node Error [ERR_MODULE_NOT_FOUND]: Cannot find module

Converting Project form CJS to ESM
I am attempting to convert my current TypeScript-Node project from ESM to CJS, however, I keep getting the error below
Error [ERR_MODULE_NOT_FOUND]: Cannot find module` 'redacted/dist/config/datadog'
imported from /redacted/dist/app.js
This is what the import looks like in app.ts:
import './config/datadog';
And this is what it looks like for app.js
import './config/datadog';
Here is my datadog.ts document
datadog.ts
import tracer from 'dd-trace';
tracer.init({
logInjection: true,
profiling: true,
appsec: true
});
export default tracer;
Here is the full printout of the error I am recieving when I execute the app via ~/$ node dist/app.js.
> node dist/app.js
node:internal/errors:465
ErrorCaptureStackTrace(err);
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module 'redacted/dist/config/datadog' imported from /redacted/dist/app.js
at new NodeError (node:internal/errors:372:5)
at finalizeResolution (node:internal/modules/esm/resolve:405:11)
at moduleResolve (node:internal/modules/esm/resolve:966:10)
at defaultResolve (node:internal/modules/esm/resolve:1176:11)
at ESMLoader.resolve (node:internal/modules/esm/loader:605:30)
at ESMLoader.getModuleJob (node:internal/modules/esm/loader:318:18)
at ModuleWrap.<anonymous> (node:internal/modules/esm/module_job:80:40)
at link (node:internal/modules/esm/module_job:78:36) {
code: 'ERR_MODULE_NOT_FOUND'
}
Node.js v18.0.0
Process finished with exit code 1
It works fine When running using ts-node
node --experimental-specifier-resolution=node --loader ts-node/esm app.ts --project tsconfig.json
I have configured my tsconfig.json file like this:
{
"compilerOptions": {
"target": "ES2020",
"module": "ES2020",
"lib": ["ES2020"],
"moduleResolution": "node",
"esModuleInterop": true,
"rootDir": "./src",
"outDir": "./dist",
"forceConsistentCasingInFileNames": true,
"strict": true,
}
}
Edit
I've posted the code on GitHub
Your need to use TypeScript v4.7 which is currently the TS-Next Version
Once you upgrade to typescript#next which can be done by executing the command ~/$ npm install -D typescript#next, you will need to make the changes below to your tsconfig.json file.
{
"compilerOptions": {
"lib": [
"ESNext" /* ESNext includes new Level-4 features that were
recently added to the ECMA-262 JS spec */
],
"module": "NodeNext",/* (1 of 2) TS v4.7 settings you need
to change */
"moduleResolution": "NodeNext", /* This is the one that will
specifically solve the error you're
getting. Without the internal changes
made by this, your project will not
resolve modules correctly. */
"esModuleInterop": true, /* This is properly configured. FYI you cannot
change this, it must be set to true. */
/*
THE REST OF THE SETTINGS DO NOT AFFECT THE MODULE TYPE OR HOW TSC
RESOLVES OTHER MODULES */
"target": "ES2021",
"rootDir": "./src",
"outDir": "./dist",
"forceConsistentCasingInFileNames": true,
"strict": true,
}
}
To Summarize
You must set the tsconfig.json keys module and moduleResolution as they are shown below.
`moduleResolution: "NodeNext"
module: "NodeNext"
You will need TypeScript v4.7
Personally I keep a global property, so below I show the command for the global install, but all you really need is to add it to your node_modules dir it as a dependency for your current project.
~$ sudo npm i -g typescript#next // Global Install
~$ npm i -D typescript#next // Add as a Project Dependency
I can't help with ever IDE in existance, but if you use VSCode, use the following configuration so your project uses the ver v4.7.
Then you need to set the following configuration
"typescript.tsdk": "./node_modules/typescript/lib",
package.json
You also need to enable ESM in for Node.. To do this you need to add the following to your package.json
/** #file "package.json" */
{
"type": "module"
}
...OR YOU CAN use the dot MTS (.mts) file extension for all of your files. There are advantages to both, but discussing the advantages is beyond the scope of this answer.
That should be it. It sounds hard but its actually easy once you have done it before.
For another helpful source:
The answer at this LINK covers this same subject with a bit more detail. I really suggest you check it out.

migrating from D3.js v6 to v7 in typescript + node environment

I'm trying to make d3 v7 work in Typescript + Node environment. The previous code on d3 v6 was working fine with these configurations:
tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"module": "commonjs",
"moduleResolution": "node",
"esModuleInterop": true,
}
}
and there was NO "type": "module" in package.json file.
What I've tried (step-by-step):
Updated d3 to v7 and restarted the app; Error:
/app/dist/controllers/d3-node.js:4
const d3_1 = require("d3");
^
Error [ERR_REQUIRE_ESM]: require() of ES Module /app/node_modules/d3/src/index.js from /app/dist/controllers/d3-node.js not supported.
Instead change the require of index.js in /app/dist/controllers/d3-node.js to a dynamic import() which is available in all CommonJS modules.
which was expected due to d3 v7 changes.
knowing that I need to make Typescript compiler generate import statements instead of require, I changed the tsconfig.json to:
{
"compilerOptions": {
"target": "ES6",
"module": "ES2020", /* <------------- */
"moduleResolution": "node",
"esModuleInterop": true,
}
}
which results in this error (as expected):
import app from '../app.js';
^^^^^^
SyntaxError: Cannot use import statement outside a module
To solve the previous error, I added "type": "module" to package.json, hoping this would (finally!) solve the issue.
Basically the change caused all import statements to break; so as an example, this import:
import app from '../app'
results in:
node:internal/errors:464
ErrorCaptureStackTrace(err);
^
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/dist/app' imported from /app/dist/bin/www.js
After finding this #13422 issue on GitHub, I know that I should add .js to the end of import statements to make it work.
But the project has dozens of import statements and BTW, as discussed in the issue, it doesn't feels right to have all those .js extensions, even though we're writing Typescript.
Is there any other way to make it work without adding the .js to all the import statements?
Thanks

How to use node --experimental-modules with Typescript output

Might be the stupidest question ever, but I have a Node project that is using ES modules with --experimental-modules and Node 12.
Now I'm adding an inner package to the monorepo that's written in Typescript that's consumed by the main node app. I'm struggling with my Typescript build settings that produce something that will work with --experimental-modules.
Currently tsconfig.json:
{
"include": [
"src/**/*ts"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
],
"compilerOptions": {
"module": "esnext",
"esModuleInterop": true,
"target": "esnext",
"moduleResolution": "node",
"sourceMap": true,
"outDir": "dist"
},
"lib": ["es2015"]
}
If I have index.ts that imports from a neighbour ts file:
import { schema } from './schema'
The built import statements is without any .js and this makes my node app choke:
(node:78972) ExperimentalWarning: The ESM module loader is experimental.
internal/modules/esm/default_resolve.js:79
let url = moduleWrapResolve(specifier, parentURL);
^
Error: Cannot find module /Users/viktor/dev/projects/kb-frontend/packages/graph/dist/schema imported from /Users/viktor/dev/projects/kb-frontend/packages/graph/dist/index.js
The reason is that the import is without .js - patching that in my dist directory of the ts build it works.
I cannot simply change my ts module to commonjs since this will also change the way my main exports are working with my esm based main giving me other errors:
import { server as graphMiddleware } from '#kb-front/graph'
^^^^^^
SyntaxError: The requested module '#kb-front/graph' does not provide an export named 'server'
I would not want to add a lot of .default here and there since the entire setup I have is to avoid commonjs alltogether and just use js and typescript with esm. Hey, I want the new shiny stuff.
What am I missing?
Two issues on using native module support in browser with Typescript:
https://github.com/microsoft/TypeScript/issues/13422
https://github.com/microsoft/TypeScript/issues/16577
From them I got the hack to just import with .js extension. Super weird, but works for my case.

Typescript can not find node core modules

I am trying to write a class with TypeScript and therefore I'd like to import some native node modules which fails because of
[ts] Can not find module 'net'.
The same issue happens for other native node modules. However it does work for bluebird for example. (See Screenshot).
My tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"allowJs": true,
"types": ["node"]
},
"exclude": [
"node_modules"
]
}
My question:
Why does it not recognize native modules like 'net' ?
Edit: This error is thrown when executing the build task: error TS2688: Cannot find type definition file for 'node'

Relative path Issue - TypeScript compiler behaving differently on Windows vs Linux

I have used relative Paths to import modules created in my Angular2 and TypeScript application.
Example (Source Code)
import {Http} from 'angular2/http';
import {Injectable} from 'angular2/core';
import {Person} from '../core/Person';
This compiles fine on windows (tsc v1.7.5) but is not able to load on Linux.
Questions:
Why is this behaving so on linux?
Is there a standard way to declare path of modules in typescript?
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
},
"exclude": [
"node_modules",
"wwwroot/lib"
]
}
Error on Ubuntu 14.04
wwwroot/app/people/people.service.ts(3,22): error TS2307: Cannot find module '../core/Person'.
wwwroot/app/routes.config.ts(1,22): error TS2307: Cannot find module './home/Home'.
wwwroot/app/routes.config.ts(2,23): error TS2307: Cannot find module './about/About'.
wwwroot/app/routes.config.ts(3,24): error TS2307: Cannot find module './people/People'.
wwwroot/app/routes.config.ts(4,30): error TS2307: Cannot find module './people/PersonDetail'.
As you can see from sourcecode on github, Person.ts contains the class person located in wwwroot\app\core\Person.ts
Please help me resolve this issue. Thanks in advance.
I found the problem.
Windows ignores case in directory & file names whereas linux does not.
After keeping all folder and file names in small case and replicating the same in imports. It compiled successfully.

Resources