Have a TS 4.7 library using ESM modules.
tsconfig.json:
"target": "ES2020",
"module": "ES2020",
"lib": ["ES2020"],
"moduleResolution": "node",
package.json
"type": "module",
I have a main file with only a one silly export:
index.ts
export { Spig } from './spig';
which is compiled to:
index.js
export { Spig } from './spig';
//# sourceMappingURL=index.js.map
Problem
When I use this library from a Node CLI program (with ESM modules enabled as well), I get the following error:
Cannot find module <path>/lib/spig imported from <path>/lib/index.js
When I manually add .js in the generated index.js, the issue is gone:
export { Spig } from './spig.js';
How can I force TypeScript compiler to generate the extension, too? What am I missing here?
You cannot omit the file extension anymore in ESM module imports. The extension should be always .js/.jsx, not .ts/.tsx for a typescript file. So, in the index.ts you should add the extension to spig export like the following and every other file imported/exported if using ESM modules.:
index.ts
export { Spig } from './spig.js';
Also, moduleResolution should be set to Node16 or NodeNext so ESM modules work as expected.
As stated in the docs (enphasis by me):
Relative import paths need full extensions (e.g we have to write import "./foo.js" instead of import "./foo").
When a .ts file is compiled as an ES module, ECMAScript import/export syntax is left alone in the .js output; when it’s compiled as a CommonJS module, it will produce the same output you get today under module: commonjs.
This also means paths resolve differently between .ts files that are ES modules and ones that are CJS modules. For example, let’s say you have the following code today:
// ./foo.ts
export function helper() {
// ...
}
// ./bar.ts
import { helper } from "./foo"; // only works in CJS
helper();
This code works in CommonJS modules, but will fail in ES modules because relative import paths need to use extensions. As a result, it will have to be rewritten to use the extension of the output of foo.ts - so bar.ts will instead have to import from ./foo.js.
// ./bar.ts
import { helper } from "./foo.js"; // works in ESM & CJS
helper();
This might feel a bit cumbersome at first, but TypeScript tooling like auto-imports and path completion will typically just do this for you.
Is there any WORKING way how to bundle node project into one single file (including dependencies) and how?
I am using babel (.babelrc)
{
"presets": ["#babel/preset-env"],
"plugins": [
[
"module-resolver",
{
"root": [
"./src"
],
"alias": {
"test": "./test",
"underscore": "lodash"
}
}
]
]
}
the answer is no. babel can not do what you want by itself. It is a tool for transforming one dialect of Javascript into another, based on rules defined in your .babelrc file. It is a compiler, not a linker (to borrow terms from the C world).
Using babel-plugin-module-resolver will not cause babel to transpile dependencies as if they were source files. It is simply a babel rule which modifies the paths passed to require() or import.
To include dependencies as well as source files you need to use both a compiler like babel and a bundler such as webpack or rollup.
I'm using tsc build tasks. Unfortunately I'm always getting the same errors from the node modules folder
Executing task: .\node_modules\.bin\tsc.cmd --watch -p .\tsconfig.json <
node_modules/#types/node/index.d.ts(6208,55): error TS2304: Cannot find name 'Map'.
node_modules/#types/node/index.d.ts(6215,55): error TS2304: Cannot find name 'Set'.
node_modules/#types/node/index.d.ts(6219,64): error TS2304: Cannot find name 'Symbol'.
node_modules/#types/node/index.d.ts(6225,59): error TS2304: Cannot find name 'WeakMap'.
node_modules/#types/node/index.d.ts(6226,59): error TS2304: Cannot find name 'WeakSet'.
10:13:18 - Compilation complete. Watching for file changes.
I already added the directory to the ignore at tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"strict": false,
"noImplicitAny": false,
"strictPropertyInitialization": false,
"esModuleInterop": true,
},
"include": [
"src/*"
],
"exclude": [
"node_modules",
"./node_modules",
"./node_modules/*",
"./node_modules/#types/node/index.d.ts",
]
}
What I'm doing wrong? What should I do in order to ignore those errors?
I'm using VsCode and tsc Version 2.9.2
Quickfix is to skip the check
{
"compilerOptions": {
"skipLibCheck": true
},
}
Add an empty "types" option in "compilerOptions":
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"sourceMap": true,
"strict": false,
"noImplicitAny": false,
"strictPropertyInitialization": false,
"esModuleInterop": true,
"types": []
},
"include": [
"src/*"
],
"exclude": [
"node_modules",
"./node_modules",
"./node_modules/*",
"./node_modules/#types/node/index.d.ts",
]
}
From https://www.typescriptlang.org/docs/handbook/tsconfig-json.html
#types, typeRoots and types
By default all visible “#types” packages are included in your
compilation. Packages in node_modules/#types of any enclosing folder
are considered visible; specifically, that means packages within
./node_modules/#types/, ../node_modules/#types/,
../../node_modules/#types/, and so on.
...
Specify "types": [] to disable automatic inclusion of #types packages.
Keep in mind that automatic inclusion is only important if you’re
using files with global declarations (as opposed to files declared as
modules). If you use an import "foo" statement, for instance,
TypeScript may still look through node_modules & node_modules/#types
folders to find the foo package
You can do this right on the command line
tsc --skipLibCheck
I met this issue with typescript#3.2.1 and fixed by upgrading it to 3.7.3.
Notice with typescript#3.2.1, the skipLibCheck does not take effect. When I upgraded TypeScript the skipLibCheck: true works.
set "skipLibCheck": true inside tsconfig.json
I had a similar issue in a monorepo using yarn workspaces.
Turned out my app was using a different TypeScript version to the root workspace and bringing those in sync fixed the issue.
You can verify this in your own repo by running yarn list typescript or npm ls typescript.
If you have multiple versions of TypeScript then upgrade your projects with the lower version so that all have the highest version currently in use in your repo, e.g. yarn add -D typescript#4.5.5 (or whatever version you need)
This is random but none of the solutions here worked. I had an error occuring in a node_module and what fixed it was this:
Changing:
target: "esnext"
To any specific version, e.g.:
target: "es2020"
In case it helps some other poor traveller 🤷♂️
If you find yourself here and none of the other answers is solving the problem, check to make sure that you haven't set maxNodeModuleJsDepth.
If you have allowJs enabled this option lets TypeScript attempt to infer types from modules in node_modules, and skipLibCheck doesn't have any effect on that, because it's reading javascript files and not type declarations.
The default setting for maxNodeModuleJsDepth is 0, and in the vast majority of cases that's what you want (and you should prefer using #types packages instead of turning this on).
if you are here and none of the following has worked for you:
❌ Updgrade/downgrading typescript version
(NOTE: When you run the tsc command, the globally installed typescript version is used as the compiler. So even if you have the latest typescript version in your package.json, you will have to upgrade typescript globally. With npm thats npm install typescript#latest -g )
❌ Adding/Editing tsconfig options: target, types, include, exclude, allowJs, skipLibCheck
❌ npm update
❌ Deleting node_modules && npm i
❌ Deleting package-lock (don't do that btw) && npm i
I want to leave this link from the typescript config docs here for you:
What does this("types") affect?
With this knowledge, this solved the issue for me:
See what module is causing the error in the log when you run tsc. (For me it was node_modules/mongoose/types/*, so mongoose was the culprit.)
Convert all your ES6 imports of this module to commonjs's require(). (In my case import mongoose from 'mongoose' --> const mongoose = require('mongoose') )
I hope this solves your issue
Upgrade your typescript & ts-node:
"typescript": "4.9.4"
"ts-node": "10.9.1"
and use the flag --skipLibCheck when you build or put it in the compilerOtions on the tsconfig.json file ("skipLibCheck": true)...
I have a es2017 code with async/await, I want to transform it to es5 so that it'll be supported by most Node.js versions.
My current .babelrc file looks like this:
{
"presets": ["es2015", "es2016", "es2017"]
}
So I'm transforming es2017 to es2016, from es2016 to es2015 and from es2015 to es5.
When I'm trying to run the code after I built it with babel src -d dist -s I'm getting error saying that: ReferenceError: regeneratorRuntime is not defined
How can I transform the es2017 code to es5? I wanna publish the code later and make it usable by node.js v4 and up.
Thanks to #Bergi I found a way how to solve this ReferenceError: regeneratorRuntime is not defined error.
I added the transform-runtime plugin to my .babelrc
Now my .babelrc is:
{
"presets": ["es2015", "es2016", "es2017"],
"plugins": ["transform-runtime"]
}
There aren't any errors now and it works fine.
I've been targeting ES6 for a while in Visual Studio Code, but when I try to switch to TypeScript, it throws errors such as:
Generators are only available when targeting ECMAScript 6
But my tsconfig.json does have the ES6 target:
{
"compilerOptions": {
"target": "ES6",
"module": "amd",
"sourceMap": true
}
}
So I tried npm install -g typescript#1.6.0-beta but it looks like VSCode doesn't care.
Generators are not currently supported.
How can I get TypeScript and generators to work properly together in VS Code?
Update
Changing typescript.tsdk to the 1.6 binary seems to fix IntelliSense errors, but this tasks.json still prints out error TS1220: Generators are only available when targeting ECMAScript 6 or higher.:
"version": "0.1.0",
"command": "/usr/local/lib/node_modules/typescript/bin/tsc",
"showOutput": "silent",
"windows": {"command": "tsc.exe"},
"isShellCommand": true,
"args": ["app.ts"],
"problemMatcher": "$tsc"
However, /usr/local/lib/node_modules/typescript/bin/tsc --target ES6 app.ts used manually in the terminal does work.
I know now!
1. IntelliSense
You can use the typescript.tsdk setting to point VSCode to TypeScript binaries. Upgrade your TypeScript to 1.6 and set the location properly.
You can do it either in your user/workspace settings, or per project in the .vscode/settings.json file. OS X example:
"typescript.tsdk": "/usr/local/lib/node_modules/typescript/lib"
2. Compiler
You also need to make sure your .vscode/tasks.json points to the new binary and makes the compiler operate in Explicit project mode, i.e. use tsconfig.json instead of taking a list of files to compile as an argument.
{
"version": "0.1.0",
"command": "/usr/local/lib/node_modules/typescript/bin/tsc",
"showOutput": "silent",
"windows": {"command": "tsc.exe"},
"isShellCommand": true,
"args": [], //do not pass any files to the compiler. This way it will use tsconfig.json where you can set target: "ES6"
"problemMatcher": "$tsc"
}
And finally tsconfig.json (in the project's root directory):
{
"compilerOptions": {
"target": "ES6", //The key, of course.
"module": "amd",
"sourceMap": true
},
"exclude": [
"node_modules",
".vscode"
]
}
Restart the editor afterwards!
You can change your user settings in VS Code and set "typescript.tsdk" to a custom location .
If you install the nightly (npm install -g typescript#next), you can point to that version of TypeScript's lib folder.
More
Reasons and setup instructions for using ts latest are covered here : https://basarat.gitbooks.io/typescript/content/docs/getting-started.html#typescript-version