package.json not honouring exports property for esm and cjs npm package - node.js

I am having difficulty getting my npm library to support subpath imports/requires via the exports field in the package.json. For context, package.json supports a field "exports" which allows you to conditonally expose files based on the runtime (i.e. commonjs OR ecmascript.
When importing the npm library in my typescript project, I get the following error:
// How I import
import logger from '#myorg/custom-logger/src/logger';
// The error I get in vscode
Cannot find module '#myorg/custom-logger/src/logger' or its corresponding type declarations.
The tsc compiler error:
TSError: ⨯ Unable to compile TypeScript:
src/config/winston.ts:1:20 - error TS2307: Cannot find module '#myorg/custom-logger/src/logger' or its corresponding type declarations.
The custom-logger package comes with support for commonjs and esm. It is built & deployed to npm with the following structure:
esm/
--- src/
--- index.js
--- logger.js
--- index.d.ts
--- logger.d.ts
--- package.json which contains { "type": "module" } (also tried without this - same issue occurs)
cjs/
--- src/
--- index.js
--- logger.js
--- index.d.ts
--- logger.d.ts
--- package.json which contains { "type": "commonjs" } (also tried without this - same issue occurs)
package.json which contains (see below)
The main package.json in the #myorg/custom-logger package contains the following:
{
"name": "#myorg/custom-logger",
"version": "0.1.4",
"dependencies": {
"app-root-path": "^3.0.0",
"winston": "^3.8.1"
},
"devDependencies": {
"#types/app-root-path": "^1.2.4",
"#types/winston": "^2.4.4"
},
"types": "./esm/src/index.d.ts",
"typings": "./esm/src/index.d.ts",
"module": "./esm/src/index.js",
"main": "./cjs/src/index.js",
"exports": {
"./src/*": {
"types": "./esm/src/*.d.ts",
"import": "./esm/src/*.js",
"require": "./cjs/src/*.js"
},
".": {
"types": "./esm/src/index.d.ts",
"import": "./esm/src/index.js",
"require": "./cjs/src/index.js"
}
}
}
The issues I am having are as follows:
Typescript and vscode doesn't seem to honour the exports logic (it throws the errors seen above)
What I am trying to achieve is:
Be able to import subpaths. i.e. import mylib from '#myorg/custom-logger/src/logger'
I am using "typescript": "4.7.4", and am using esm (ecmascript) natively in node.

So to get this working, I had to update my tsconfig "moduleResolution" config.
Here is my new config (notice how I have "moduleResolution": "Node16" set):
You can also use NodeNext as the moduleResolution
{
"compilerOptions": {
"target": "ESNEXT", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */
"module": "ESNext", /* Specify module code generation: 'none', commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
"moduleResolution": "Node16",
"outDir": "build/" /* Redirect output structure to the directory. */,
/* Strict Type-Checking Options */
"strict": true /* Enable all strict type-checking options. */,
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
"rootDir": "./",
"resolveJsonModule": true
},
"include": ["src/", "e2e"],
"exclude": ["node_modules", "build", "logs", "db"],
"resolveJsonModule": true,
"esModuleInterop": true
}
Before this, the moduleResolution value was set to node. After further investigation, the node moduleResolution does not support the "exports" field in the package.json. Here is a great answer that explains it in more detail

Related

how to setup tsconfig for using with unit-test

I am a newbee in nodejs and typescript, and I have a problem setting up my mocha unit test framework.
I started to develop in a folder with the following folder hierachy:
myproject
src
dist
The paths specified in the tsconfig.json were not correctly resolved, and a friend made me installed ttypescript and the typescript-transform-paths pluggin.
Here is the resulting tsconfig.json :
{
"compilerOptions": {
"target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"module": "commonjs", /* Specify what module code is generated. */
"moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
"baseUrl": ".", /* Specify the base directory to resolve non-relative module names. */
"paths": {
"core/*": [
"src/core/*"
],
"model/*": [
"src/model/*"
],
"module/*": [
"src/modules/*"
],
"utils/*": [
"src/utils/*"
],
"client/*":[
"src/client/*"
],
"test/*": [
"test/*"
]
},
"plugins": [
{
"transform": "typescript-transform-paths"
}
],
"sourceMap": true, /* Create source map files for emitted JavaScript files. */
"outDir": "./dist", /* Specify an output folder for all emitted files. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
"strict": true, /* Enable all strict type-checking options. */
"strictNullChecks": false, /* When type checking, take into account `null` and `undefined`. */
"strictPropertyInitialization": false, /* Check for class properties that are declared but not set in the constructor. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
},
"ts-node": {
"transpileOnly": true,
"require": [ "typescript-transform-paths/register" ],
},
"include": ["src/**/*", "test/**/*"],
"exclude": ["node_modules"]
}
Everything works fine for the development.
I want to start unit testing, and add a test folder along side the src folder:
myproject
src
test
dist
I can type my typescript file in the test, but when I run the test with mocha, the paths are not correclty resolved.
I get the following error:
Test
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
Can anyone give me pointer on how to setup my tsconfig file to use correctly the paths in dev and test?
Thanks!

Configure typescript to output imports with extensions, ex: `from './file.js``

Using node 14.x I would like to switch my project to full ES Modules, as it's now supported.
So I enabled on package.json "type": "module"
and my tsconfig.json looks like that:
{
"compilerOptions": {
"outDir": "dist", /* Redirect output structure to the directory. */
"strict": true, /* Enable all strict type-checking options. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"skipLibCheck": true, /* Skip type checking of declaration files. */
"forceConsistentCasingInFileNames": true, /* Disallow inconsistently-cased references to the same file. */
"allowSyntheticDefaultImports": true,
"lib": ["ES2020"],
"module": "ESNext",
"moduleResolution": "node",
"target": "ES2020"
}
}
But the output files have unspecified extension in imports, it's instead REQUIRED for node 14.x to specify full file ext
For example:
import { ENV, redisConfig } from './config';
should instead be:
import { ENV, redisConfig } from './config.js';
TS won't handle that for you, but you can run Node with the node --experimental-specifier-resolution=node parameter.
Source
Unfortunately it seems that TS isn't going to support adding extension to the end of the import, since apparently it's not as simple as adding .js to the end of the import.

Built TypeScript application imports from wrong, src instead of dist, folder

TLDR; App builds but tries to import files from src folder instead of dist
I have an Express app that is built with TypeScript.
This is the tsconfig.json
{
"compilerOptions": {
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */
"sourceMap": true, /* Generates corresponding '.map' file. */
"outDir": "dist", /* Redirect output structure to the directory. */
"strict": false, /* Enable all strict type-checking options. */
"noImplicitAny": false, /* Raise error on expressions and declarations with an implied 'any' type. */
"moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
"baseUrl": "./dist", /* Base directory to resolve non-absolute module names. */
"paths": {
"*": [
"node_modules/*"
]
}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"esModuleInterop": true, /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
"experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
"emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
},
"include": [
"src/**/*",
"custom.d.ts"
]
}
These are my npm scripts:
"scripts": {
"clean": "rimraf dist/*",
"dev": "nodemon",
"tsc": "tsc",
"start": "node dist/index.js",
"build": "npm-run-all clean tsc",
},
npm run build works fine and all seems nice and dandy, but when I run npm run start I get the following error:
/app/server/src/entity/Category.ts:1
import {Entity, PrimaryGeneratedColumn, Column, ManyToMany, BaseEntity} from "typeorm";
^^^^^^
SyntaxError: Cannot use import statement outside a module
The error seems to be that my build for some reason seems to import from the src-folder and not from the build folder. I have no idea what is wrong, any guiding or ideas are appreciated to help me get further.
Ok, so doing "start": "node build/index.js" results in the above behaviour, however if I do the following on the command line:
cd build
node index.js
It works. So I guess some path is wrong in some module in the application. Will update with more if I find a good way to get this working with NPM scripts.
For anybody else that encounters this problem with Typescript + TypeORM, I encountered it too. The way I solved it was by using __dirname to help resolve paths in my TypeORM config.
For example, instead of doing
const connection: DataSourceOptions = {
...
entities: ['src/entities/*.ts', 'dist/entities/*{.ts,.js}'],
}
I modified it to
const connection: DataSourceOptions = {
...
entities: [`${__dirname}/../../entities/*{.ts,.js}`],
migrations: [`${__dirname}/migrations/*{.ts,.js}`],
}
Hope this helps!

Exporting Global Styles with Font Assets from a TypeScript->CommonJS module

I have a TypeScript React project organized as follows:
tsconfig.json
package.json
yarn.lock
lerna.json
node_modules/
packages/
ui-library/
package.json
tsconfig.json
typings.d.ts
src/
fonts/
myfont.ttf
components/
GlobalStyle.tsx
lib/ <-- `tsc` builds to here
web-app/
package.json
src/
components/
The web-app imports the ui-library as a commonjs module in its package.json. This is managed through Yarn Workspaces, hence node_modules being at the root instead of each folder. At one point, the web-app imports GlobalStyle from the ui-lib, which is where the issue occurs.
Error: Cannot find module '../fonts/myfont.ttf'
Require stack:
- /Users/me/sources/myproject/packages/ui-library/lib/styles/GlobalStyle.js...
Here is the original import statement from ui-library/src/GlobalStyle.tsx that causes the issue:
import myFont from "../fonts/myfont.ttf";
const GlobalStyle = () => (
<style global jsx>{`
#font-face {
font-family: "My font family";
src: url(${myFont}) format("truetype");
}
...</style>);
The issue is the require statement in the emitted GlobalStyle.js code, built when I run tsc in the ui-lib folder:
const MYFONT_ttf_1 = __importDefault(require("./myfont.ttf"));
I googled this issue online, and I found you had to add typings for compiling .ttf and other abnormal imports. So I created a typings.d.ts file with this declaration:
declare module "*.ttf" {
const value: string;
export default value;
}
And I included it on ui-library/tsconfig.json as follows:
{
"extends": "../../tsconfig.json",
"exclude": ["lib"],
"include": ["src"],
"files": ["./typings.d.ts"],
"compilerOptions": {
"baseUrl": "src",
"outDir": "lib",
"declaration": true,
"declarationMap": true,
"noEmit": false
}
}
The tsconfig above extends the root tsconfig:
{
"files": ["./typings.d.ts"],
"compilerOptions": {
"module": "commonjs",
"target": "es2019",
"lib": ["dom", "es2019"],
"strict": true,
"jsx": "react",
"moduleResolution": "node",
"isolatedModules": true,
"esModuleInterop": true,
"noUnusedLocals": false,
"forceConsistentCasingInFileNames": true,
"strictNullChecks": true,
"sourceMap": true,
"noEmit": true,
"declaration": false
},
"exclude": ["node_modules"]
}
We are using TypeScript 3.8. Let me know if there is any additional info to provide. My hunch is that I am either using the wrong module/target, or fundamentally misunderstanding some aspect of this.
More Details
I should note the reason we are using CommonJS modules is because ts-node can only work with that. We pull in ts-node when we are doing our gatsby build, following the gist here in gatsby-config.js:
require("ts-node").register();
// Use a TypeScript version of gatsby-config.js.
module.exports = require("./gatsby-config.ts");
Maybe it's an impossible problem to solve, to get fonts imported through ts-node which is a server side environment? Confused on what the right approach is to export a module with fonts. Willing to get rid of ts-node, and leave the Gatsby config files as js.. but mostly just want to be able to import my fonts.
I solved this by just copying the fonts as part of build steps. Basically, fonts have their own pipeline. There may be better ways, but this works well enough.

Can't run my Node.js Typescript project TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/App.ts

When I try to start my app on Heroku I got the following stack trace.
It is just a basic ts.app like you see with ts-node and nodemon.
I am really interested in what the answer is going to be.
2020-05-30T00:03:12.201106+00:00 heroku[web.1]: Starting process with command `npm start`
2020-05-30T00:03:14.405285+00:00 app[web.1]:
2020-05-30T00:03:14.405303+00:00 app[web.1]: > discordtoornamentmanager#1.0.0 start /app
2020-05-30T00:03:14.405303+00:00 app[web.1]: > ts-node src/App.ts
2020-05-30T00:03:14.405304+00:00 app[web.1]:
2020-05-30T00:03:14.833655+00:00 app[web.1]: (node:23) ExperimentalWarning: The ESM module loader is experimental.
2020-05-30T00:03:14.839311+00:00 app[web.1]: TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for /app/src/App.ts
2020-05-30T00:03:14.839312+00:00 app[web.1]: at Loader.defaultGetFormat [as _getFormat] (internal/modules/esm/get_format.js:65:15)
2020-05-30T00:03:14.839314+00:00 app[web.1]: at Loader.getFormat (internal/modules/esm/loader.js:113:42)
2020-05-30T00:03:14.839315+00:00 app[web.1]: at Loader.getModuleJob (internal/modules/esm/loader.js:244:31)
2020-05-30T00:03:14.839315+00:00 app[web.1]: at processTicksAndRejections (internal/process/task_queues.js:97:5)
2020-05-30T00:03:14.839316+00:00 app[web.1]: at Loader.import (internal/modules/esm/loader.js:178:17)
2020-05-30T00:03:14.847801+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2020-05-30T00:03:14.847998+00:00 app[web.1]: npm ERR! errno 1
2020-05-30T00:03:14.848957+00:00 app[web.1]: npm ERR! discordtoornamentmanager#1.0.0 start: `ts-node src/App.ts`
2020-05-30T00:03:14.849050+00:00 app[web.1]: npm ERR! Exit status 1
2020-05-30T00:03:14.849172+00:00 app[web.1]: npm ERR!
2020-05-30T00:03:14.849254+00:00 app[web.1]: npm ERR! Failed at the discordtoornamentmanager#1.0.0 start script.
2020-05-30T00:03:14.849337+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2020-05-30T00:03:14.854859+00:00 app[web.1]:
2020-05-30T00:03:14.854998+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2020-05-30T00:03:14.855069+00:00 app[web.1]: npm ERR! /app/.npm/_logs/2020-05-30T00_03_14_850Z-debug.log
2020-05-30T00:03:14.907689+00:00 heroku[web.1]: Process exited with status 1
2020-05-30T00:03:14.943718+00:00 heroku[web.1]: State changed from starting to crashed
This is my package.json
{
"name": "discordtoornamentmanager",
"version": "1.0.0",
"description": "",
"main": "dist/app.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "nodemon -x ts-node src/App.ts",
"start": "ts-node src/App.ts"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"#types/node": "^14.0.5",
"axios": "^0.19.2",
"discord.js": "^12.2.0",
"pg": "^8.2.1",
"reflect-metadata": "^0.1.10",
"typeorm": "0.2.25",
"typescript": "^3.9.3",
"nodemon": "^2.0.4",
"ts-node": "8.10.1"
}
}
And this is my tsconfig
{
"compilerOptions": {
"lib": [
"es6"
],
"target": "es6",
"module": "commonjs",
"moduleResolution": "node",
"outDir": "dist",
"resolveJsonModule": true,
"emitDecoratorMetadata": true,
"esModuleInterop": true,
"experimentalDecorators": true,
"sourceMap": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
Remove "type": "module" from package.json
https://github.com/TypeStrong/ts-node/issues/935
https://github.com/TypeStrong/ts-node/issues/1007#issuecomment-1163471306
If you don't want to remove "type": "module" (for example if you're using import statements in your .ts which allows the inference of types from modules), then you can use the following option in tsconfig.json:
{
"compilerOptions": {
"esModuleInterop": true,
}
}
And then you can start the server with the config using ts-node.
Install:
npm install -g ts-node
Run:
ts-node-esm my_server.ts
use
node --loader ts-node/esm ./my-script.ts
instead of
ts-node ./my-script.ts
MARCH 2022
USING: Node 16.6.2, ts-node v 10.7.0
What worked for me was having "type": "module" in package.json, and adding
node --experimental-specifier-resolution=node --loader ts-node/esm ./src/app.ts
tsconfig.json:
{
"compilerOptions": {
"module": "ESNext",
"esModuleInterop": true,
"target": "ESNext",
"moduleResolution": "Node",
"outDir": "dist",
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"isolatedModules": false,
"strict": true,
"noImplicitAny": true,
"useUnknownInCatchVariables": false,
"inlineSourceMap": true
},
"ts-node": {
"esm": true
},
"lib": ["esnext"]
}
Credits to #FelipePlets for the useful answer here
EDIT
You may want to use a non-esnext option, as per the ts docs:
The special ESNext value refers to the highest version your version of TypeScript supports. This setting should be used with caution, since it doesn’t mean the same thing between different TypeScript versions and can make upgrades less predictable.
Removing "type": "module" from package.json and adding:
"compilerOptions": {
"module": "CommonJS"
},
In tsconfig.json fixed this for me.
Solution One
Remove "type": "module" from package.json if it's added
In tsconfig.json under the compilerOptions Set module property to CommonJS module: "CommonJS" and moduleResolution: "Node"
Solution Two
if the first one didn't work, or you have for some reason to keep module: "ESNext"
1- Add "type": "module" to package.json
2- Install ts-node npm i -g ts-node
3- Go to tsconfig.json and add the following:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
/* ... your props ... */
},
"ts-node": {
"esm": true
}
}
4- Run ts-node fileName.ts
Try adding this to your tsconfig.json
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node",
}
I was able to fix with a tsconfig.json that looked something like:
{
"compilerOptions": {
"target": "es2022",
"lib": ["ES2022"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "ES2022",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
},
"exclude": [
"node_modules",
],
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node",
}
}
I first came across this problem probably over a year ago, and ts-node has yet to fix it. None of the above solutions worked for me, and I have seemingly tried everything.
I just resorted to using tsc --outDir out file.ts and then running the file normally with node out/file.js, and then adding out to the .gitignore.
The thought behind ts-node is wonderful, just really sucks when it can't handle seemingly straightforward examples like this. Apologies the solution doesn't use ts-node, but I couldn't get it to work.
I made some changes on my package.json & tsconfig.json.Finally, it worked for me!
Add "type": "module" to package.json
Uncomment "moduleResolution": "node" section in your tsconfig.json
Change "module" section to "ESNEXT" in your tsconfig.json
Then Just Run the main script with this node --loader ts-node/esm .\index.ts
tsconfig.json
{
"compilerOptions": {
/* Visit https://aka.ms/tsconfig.json to read more about this file */
/* Projects */
// "incremental": true, /* Enable incremental compilation */
// "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */
// "tsBuildInfoFile": "./", /* Specify the folder for .tsbuildinfo incremental compilation files. */
// "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects */
// "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */
/* Language and Environment */
"target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
// "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */
// "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h' */
// "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */
// "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using `jsx: react-jsx*`.` */
// "reactNamespace": "", /* Specify the object invoked for `createElement`. This only applies when targeting `react` JSX emit. */
// "noLib": true, /* Disable including any library files, including the default lib.d.ts. */
// "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */
/* Modules */
"module": "ESNEXT", // ****HERE /* Specify what module code is generated. */
// "rootDir": "./", /* Specify the root folder within your source files. */
"moduleResolution": "node", // ****HERE /* Specify how TypeScript looks up a file from a given module specifier. */
// "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */
// "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */
// "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
// "typeRoots": [], /* Specify multiple folders that act like `./node_modules/#types`. */
// "types": [], /* Specify type package names to be included without being referenced in a source file. */
// "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */
// "resolveJsonModule": true, /* Enable importing .json files */
// "noResolve": true, /* Disallow `import`s, `require`s or `<reference>`s from expanding the number of files TypeScript should add to a project. */
/* JavaScript Support */
// "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
// "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from `node_modules`. Only applicable with `allowJs`. */
/* Emit */
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
// "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If `declaration` is true, also designates a file that bundles all .d.ts output. */
// "outDir": "./", /* Specify an output folder for all emitted files. */
// "removeComments": true, /* Disable emitting comments. */
// "noEmit": true, /* Disable emitting files from a compilation. */
// "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */
// "importsNotUsedAsValues": "remove", /* Specify emit/checking behavior for imports that are only used for types */
// "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */
// "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */
// "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */
// "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */
// "newLine": "crlf", /* Set the newline character for emitting files. */
// "stripInternal": true, /* Disable emitting declarations that have `#internal` in their JSDoc comments. */
// "noEmitHelpers": true, /* Disable generating custom helper functions like `__extends` in compiled output. */
// "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
// "preserveConstEnums": true, /* Disable erasing `const enum` declarations in generated code. */
// "declarationDir": "./", /* Specify the output directory for generated declaration files. */
/* Interop Constraints */
// "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */
// "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */
"esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
// "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
"forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
/* Type Checking */
"strict": true, /* Enable all strict type-checking options. */
// "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied `any` type.. */
// "strictNullChecks": true, /* When type checking, take into account `null` and `undefined`. */
// "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */
// "strictBindCallApply": true, /* Check that the arguments for `bind`, `call`, and `apply` methods match the original function. */
// "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */
// "noImplicitThis": true, /* Enable error reporting when `this` is given the type `any`. */
// "useUnknownInCatchVariables": true, /* Type catch clause variables as 'unknown' instead of 'any'. */
// "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */
// "noUnusedLocals": true, /* Enable error reporting when a local variables aren't read. */
// "noUnusedParameters": true, /* Raise an error when a function parameter isn't read */
// "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */
// "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */
// "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */
// "noUncheckedIndexedAccess": true, /* Include 'undefined' in index signature results */
// "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */
// "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type */
// "allowUnusedLabels": true, /* Disable error reporting for unused labels. */
// "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */
/* Completeness */
// "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */
"skipLibCheck": true /* Skip type checking all .d.ts files. */
}}
package.json
{
"name": "async-with-ts",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
"type": "module", // ****HERE
"devDependencies": {
"#types/node-fetch": "^3.0.3",
"ts-node": "^10.2.1",
"typescript": "^4.4.2"
},
"dependencies": {
"node-fetch": "^3.0.0"
}
}
You should be aware of using this command
node --loader ts-node/esm .\index.ts
You can use ts-node-esm instead of ts-node, keeping "type":"module" in package.json, and using import './module.js' in your .ts files.
Related: https://github.com/TypeStrong/ts-node/issues/1007
UPDATE:
This answer has an even better solution as allows to import modules without .js extension:
https://stackoverflow.com/a/65163089/1482990
I tried to remove this error by following methods but FAILED :
1- Using .mts extension
2- Using type:commonjs instead of type:module in package.json (this will not let you use 'import' in your TS file, However i wanted that, therefore i consider this try to be failed).
3- Restarting the VS-Code
Then I tried the following and succeeded :
1- Using --esm flag with ts-node command. e.g => npx ts-node --esm ./src/index.ts
2 - Inside tsConfig.json, add another option after Compiler options' closing bracket named "ts-node" and set its "esm" option to "true", same as below :
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "Node",
/* ... your props ... */
},
"ts-node": {
"esm": true
}
}
I followed advice given herein. I also had to uninstall lodash-es and install lodash instead to make it work.
After some experimentation with my ts-node/puppeteer configuration I came up with this:
package.json
{
"type": "module",
"scripts": {
"start": "npx ts-node main.ts"
},
...
}
tsconfig.json
{
"ts-node": { "esm": true, "experimentalSpecifierResolution": "node" },
"compilerOptions": {
"esModuleInterop": true,
"moduleResolution": "node",
"module": "ESNext",
...
},
...
}
Works great for running puppeteer in a TypeScript environment.
(Running NodeJS 19.0.0 with TypeScript 4.9.4 and ts-node 10.9.1)
if your tsconfig.json contains "module": "ESNext". I have used the below script in my package.json. It worked.
"start": "nodemon -e ts -w ./src -x npm run watch:serve",
"watch:serve": "node --loader ts-node/esm src/server.ts",
Running ts-node with --esm worked for me.
For example:
ts-node --esm src/App.ts
That error is caused by trying to import modules, which without the ES Modules flag, ts-node doesn't support.
Update:
Thanks to some maintainers, a working solution is now officially documented by webpack. Just take a small look at the official webpack documentation.
The second solution is similar to other answers here and works perfectly fine in my case.
For me (node version 14), for some reason, the problem was that I install the serialize-error package and when I tried to import it to threw that error.
To solve it I downgraded the version of the package from 11.0.0 to 8.0.0.
If you use PowerShell on VS Code on Windows 11 try to use this command:
ts-node-esm.cmd .\my_script.ts
after this solution: https://stackoverflow.com/a/62099904/8967481
For anyone who is running into this issue while trying run an script in an NX project.
# For apps
ts-node --project tsconfig.app.json $yourFilePath
# For libraries
ts-node --project tsconfig.lib.json $yourFilePath
# For tests
ts-node --project tsconfig.spec.json $yourFilePath
#vadimk7 wasn't far off, my solution was to change my file extension to .mts and then use ts-node-esm myfile.mts
Add this to tsconfig.json
{
/* ... your props ... */
"ts-node": {
"compilerOptions": {
"module": "CommonJS"
}
}
}
July 2022, with the use of ts-node
Node 16.14.2, ts-node 10.8.2
First install ts-node and base configuration
npm install ts-node --save-dev
npm install #tsconfig/node16 --save-dev
tsconfig.json:
{
"extends": "#tsconfig/node16/tsconfig.json",
"compilerOptions": {
"resolveJsonModule": true
},
"include": [
"main.ts"
// here you can include another directories with sources
],
"exclude": [
"node_modules"
]
}
You can remove everything related to modules/compilation from package.json.
And then you can run your program as
ts-node ./main.ts
I wanted to use ES modules instead of commonjs in my project. In addition to making some changes covered in other answers, the last need step for me was to add this to my compilerOptions in tsconfig.json:
"sourceMap": true,
before this:
node --loader ts-node/esm ./my-script.ts
I had to update ssri
npm update ssri --depth 5
Not sure if this will help anyone but I fixed it by putting this at the start:
#!/usr/bin/env node
changing my
"moduleResolution": "node",
to
"moduleResolution": "Node",
in package.json solved this for me
In your package.json {Module:commonJS}, and tsconfig.json {module:commonJS},to ts-node youname.ts
I changed my imports from:
import blah from './modules/blah'
to
import blah from './modules.blah.js'

Resources