tsconfig's path parameter and ESLint - node.js

I've been setting up the paths option in my tsconfig.json file. So far everything works fine. I can run my tests, and I can execute the program as usual. My only problem is, that ESLint does not find the modules that are accessed with one of the paths defined in tsconfig.json.
Here are all of the files that are related to the problem:
tsconfig.json:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"allowJs": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./",
"strict": true,
"esModuleInterop": true,
"declaration": true,
"resolveJsonModule": true,
"baseUrl": ".",
"paths": {
"#/*": ["./src/*"]
}
},
"include": ["src/**/*", "test/**/*", "index.ts"]
}
tsconfig.eslint.json:
{
"extends": "./tsconfig.json",
"include": ["src/**/*", "test/**/*", "index.ts", ".eslintrc.js"]
}
.eslintrc.js:
{
root: true,
env: {
browser: true,
es6: true,
node: true
},
extends: ['plugin:#typescript-eslint/recommended', 'plugin:#typescript-eslint/recommended-requiring-type-checking'],
parser: '#typescript-eslint/parser',
parserOptions: {
project: ['tsconfig.eslint.json'],
sourceType: 'module'
},
settings: {
'import/resolver': {
typescript: {}
}
},
plugins: ['#typescript-eslint', 'import', 'prefer-arrow'],
rules: {...}
}
Am am using the package eslint-import-resolver-typescript.
Now, if I try to import the file './src/test.ts' into './index.ts' with the path '#/test', then ESLint will not be able to resolve that import (although TypeScript resolves it just fine).
I've mostly copied my current solution from here, because I thought the person who asked that problem had the same problem that I had, but my setup still does not work.
I am in an NodeJS environment by the way.
EDIT:
I've also tried using the package eslint-import-resolver-alias. This only helped partially. I could get rid of the 'import/no-unresolved' errors, but whenever I call an imported function, I get '#typescript-eslint/no-unsafe-call' because apparently, ESLint does not find the types for the imported files and thusly gives everything the type any.

Could you try adding the tsconfigRootDir to your .eslintrc.js? It has worked for me.
parserOptions: {
tsconfigRootDir: __dirname,
}

For those using Angular and.eslintrc.json, I use this (notice the 2 stars in "Project"
"parserOptions": {
"project": ["**/tsconfig.json"],
"createDefaultProgram": true
},

you need to add eslint plugin https://github.com/benmosher/eslint-plugin-import#typescript
there under the extends you can specify option for typescript
extends:
- plugin:import/typescript
it should do the trick

Related

Module #adobe/leonardo-contrast-colors: How to use it. Failing on import

I'm setting app a new TypeScript/React Project using the following module https://www.npmjs.com/package/#adobe/leonardo-contrast-colors
Using node v16.17.0.
To start with I replicate the example in the README.md but the import doesn't work. Doing the following:
import { Theme, Color, BackgroundColor } from '#adobe/leonardo-contrast-colors';
returns:
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'Theme'.
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'Color'.
Module '"#adobe/leonardo-contrast-colors"' has no exported member 'BackgroundColor'.
Apparently '#adobe/leonardo-contrast-colors' leads to index.d.ts
and if I try to import the members like this:
import { Color } from "#adobe/leonardo-contrast-colors/color.mjs";
neither it works as I get:
Package path ./color.mjs is not exported from package /Users/.../package.json)
I see this open issue in the package repo: https://github.com/adobe/leonardo/issues/173
but backing to 1.0.0-alpha.13 turns out the same for me.
This is my tsconfig
{
"compilerOptions": {
"allowJs": true,
"esModuleInterop": true,
"target": "ES2015",
"jsx": "react",
"typeRoots": ["./node_modules/#types"],
"module": "ESNext",
"moduleResolution": "Node",
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true
},
"include": ["src/**/*.ts", "src/**/*.tsx"]
}
And webpack.config.js:
module.exports = (env, argv) => ({
...
module: {
rules: [
// Converts TypeScript code to JavaScript
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
},
...
],
},
resolve: { extensions: [".tsx", ".ts", ".jsx", ".js"] },
...
});
Is this a problem with the package or my project cofiguration?
Thanks in advance

Problem mapping path in ts-jest (TypeScript Jest), module cannot be found

I want to implement some jest tests in my backend and so I was trying to map my paths that I have configured in tsconfig.json via the moduleNameMapper of jest.config.js but when I run the tests I find the file is still not imported and I am shown this error on line 8 ⬇
Please assist me to map my paths correctly, I would highly appreciate any help.
To help you assist me here are the important files.
jest.config.js (where jest is usually configured) ⬇
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ["**/***.test.ts"],
verbose: true,
forceExit: true,
moduleNameMapper: {
'#util/(.*)': '<rootDir>/src/util/$1'
}
};
tsconfig.json (normal config file for typescript) ⬇
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"baseUrl": "src",
"paths": {
"#util/*": ["util/*"]
},
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
I created a file named .babelrc with this contents ⬇ :
{
"presets": ["#babel/preset-env"]
}
I then configured jest.config.js as shown below ⬇
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
transform: {
'^.+\\.ts$': 'ts-jest',
'^.+\\.js$': 'babel-jest',
'^.+\\.mjs$': 'babel-jest',
},
moduleDirectories: ['node_modules', '<rootDir>/src'],
moduleNameMapper: {
'#controllers/(.*)': '<rootDir>/src/controllers/$1',
'#middleware/(.*)': '<rootDir>/src/middleware/$1',
'#models/(.*)': '<rootDir>/src/models/$1',
'#routes/(.*)': '<rootDir>/src/routes/$1',
'#types/(.*)': '<rootDir>/src/types/$1',
'#util/(.*)': '<rootDir>/src/util/$1',
}
};
I then configured tsconfig.json as shown below ⬇:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"baseUrl": "src",
"paths": {
"#util/*": ["util/*"]
},
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"types": ["jest"]
}
}
Vote of thanks to Benjamin Drury & #Ashok for the much helpful support.
This issue is occuring due to absolute import. If you look closely, you can observe that your import statement is util/logger. This kind of imports are not properly resolved.
In case you are using VSCode, then this is a common occurence, since VSCode tries to reduce the length of your import statement.
To fix this, use relative import. So your import should look like as follow:
import logger from '../util/logger'
(Note: Above import is relative to the path src/middleware/authenticateUser.ts, please update the import based on in which file you are using the import)

Is there a webpack config to bundle webpack plugin?

I am working on creating a webpack plugin. I have used typescript to code the plugin. I am trying to bundle the plugin code before I publish it on NPM. I am getting exception that my plugin class is not a constructor.
Please find below the directory structure:-
tsconfig.json:-
{
"compilerOptions": {
// Target latest version of ECMAScript.
"target": "es5",
// Specify module code generation: 'commonjs', 'amd', 'system', 'umd' or 'es2015'.
"module": "commonjs",
// Search under node_modules for non-relative imports.
"moduleResolution": "node",
// Process & infer types from .js files.
"allowJs": true,
// Don't emit; allow Babel to transform files.
"noEmit": false,
"pretty": true,
// Enable strictest settings like strictNullChecks & noImplicitAny.
"strict": true,
// Disallow features that require cross-file information for emit.
"isolatedModules": true,
// Import non-ES modules as default imports.
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"skipLibCheck": true,
"resolveJsonModule": true,
"outDir": "dist/"
},
"include": [
"src"
],
"exclude": [
"dist",
"node_modules"
]
}
Webpack config:-
const path = require('path');
module.exports = {
name: 'log-stylizer-webpack-plugin',
entry: './src/index.ts',
output: {
filename: 'index.bundle.js',
path: path.resolve(__dirname, 'dist'),
},
mode: 'development',
target: 'node',
module: {
rules: [
{
test: /\.ts?$/,
use: 'ts-loader',
exclude: /node_modules/,
}
]
},
resolve: {
extensions: ['.ts']
}
};
In order to build a thing as a library with webpack, you have to specify the option output.libraryTarget to export things.
{
output: {
// ...
// `umd` is always a best choice in most cases
// since it would work for all kind of module styles
libraryTarget: 'umd',
}
}

Parsing error "parserOptions.project" has been set for #typescript-eslint/parser

I created a new NestJS project which is a very popular NodeJS framework. But I have this error (see title) on my IDE (PhpStorm 2020.2-Beta) and ESLint doesn't work at all.
I've used the NestJS CLI :
nest new nestjs-micro
I don't seem to be the only one with this problem, so it would be nice to find the cause of this problem and fix it once and for all.
I already have an open issue but I haven't had an answer, this is really very problematic.
If anyone has an idea on how to fix the problem and keeping an ESLint / Prettier integration with PhpStorm, thanks.
Repro
// .eslintrc.js
module.exports = {
parser: '#typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
sourceType: 'module',
},
plugins: ['#typescript-eslint/eslint-plugin'],
extends: [
'plugin:#typescript-eslint/eslint-recommended',
'plugin:#typescript-eslint/recommended',
'prettier',
'prettier/#typescript-eslint',
],
root: true,
env: {
node: true,
jest: true,
},
rules: {
'#typescript-eslint/interface-name-prefix': 'off',
'#typescript-eslint/explicit-function-return-type': 'off',
'#typescript-eslint/no-explicit-any': 'off',
},
};
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2017",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true
}
}
Additional Info
Versions
Typescript: 3.7.4
Node: 14.3.0
ESLint: 7.1.0
#typescript-eslint/parser: 3.0.2
Yarn: 1.22.4
FWIW what worked for me with this error was to add ignorePatterns: ['.eslintrc.js'], to the .eslintrc.js file. This line tells eslint to ignore the .eslintrc.js file (since it's not included in the tsconfig declared project rootDir).
I figured it out.
The error occurs when Typescript does not have a file to include for compilation.
The simplest solution is to create a tsconfig.build.json file for example and specify the following parameters in it :
{
"extends": "./tsconfig.json",
"exclude": ["node_modules", "test", "dist", "dist/**/*spec.ts"],
"include": ["src/**/*", ".eslintrc.js"]
}
The above example is adapted for NestJS but should work for other projects.
The most surprising thing is that it's only an error that shows up on PHPStorm, the build, it works fine.
Add it to the includes in tsconfig.json:
"include": [
".eslintrc.js",
]
in my case it was due to typings.d.ts file and adding it t0 the includes in tsconfig.json:
"include": [
...
"typings.d.ts",
...
]
resolved my issue.

Error compiling Typescript with graphql files

So I'm new in this area, the thing is that I'm trying to compile a Typescript project with graphql files on it (with .graphqlextension).
It' based on the serverless framework, so to compile it I launch npm startwhich launches a cd src/app && tscin the command line.
The .tsfile references the .graphqlfile like this:
import SchemaDefinition from './schemaDefinition.graphql';
And the error is
data/schema/index.ts(2,30): error TS2307: Cannot find module './schemaDefinition.graphql'.
I think the issue here is in the tsccompilation, as it creates the output directory (../../built) but it is not copying the .graphqlfiles. Here is my tsconfig.json file:
{
"compilerOptions": {
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "es5",
"lib": ["dom", "es6"],
"module": "commonjs",
"allowJs": true,
"moduleResolution": "node",
"noImplicitAny": false,
"removeComments": true,
"preserveConstEnums": true,
"rootDir": "./",
"outDir": "../../built",
"sourceMap": true,
"pretty": true,
"typeRoots": [
"node_modules/#types"
],
"types": [
"#types/node",
"#types/graphql"
],
"allowSyntheticDefaultImports": true
},
"include": [
"./*"
],
"exclude": [
"node_modules"
]
}
I'm not sure if I have to do some trick to copy these files or put a precompiler step to convert the .graphqlfiles in .tsfiles, using something like this: GraphQL Code Generator
Any ideas out there? I'm stuck :S
If you are packaging the banckend in NodeJS, it should be configured in the webpack.config.js file and in the typings.d.ts files, so both the editor and the packager knows about these files.
typings.d.ts:
declare module "*.graphql" {
const value: any;
export default value;
}
code:
import * as query from query.graphql
For this to work, a loader such as raw-loader for those using Webpack will work.
module: {
rules: [
{ test: /\.json$/, loader: 'json-loader' },
{ test: /\.html$/, loader: 'raw-loader' },
{ test: /\.graphql$/, loader: 'raw-loader' },
]
This sample has been taken from https://github.com/apollographql/graphql-tools/issues/273 where there's an active discussion about different approaches.
Here is a GitHub repo which does roughly the same but with a more powerful solution: https://github.com/webpack-contrib/copy-webpack-plugin
On the other hand, if you are packaging the front, there's a handy plugin to do the work for you: https://www.npmjs.com/package/webpack-graphql-loader
Assuming the graphql files have a JS extension so are processed if they do not export anything or nothing imports them you could try the not recommended
import "./my-module.js";
Another workaround is to copy .graphql file to the output folder through automated script for example https://www.npmjs.com/package/copy

Resources