cmd eslint can not find ts error which found by IDE - eslint

I want to use eslint in cmd to check ts file, but it can not get error info which I got in IDE.
I have set #typescript-eslint/parser in eslintrc.js. And eslint which running in cmd gave me some ts error when I did some wrong. But some wrong else did not be found.
I have a ts file with code:
interface Item {
name: string;
age: number;
}
const config: Array<Item> = [{
name: 'foo',
}]
so, I got some error in IDE:
Property 'age' is missing in type '{ name: string; age: number }' but required in type 'Item'.ts(2741)
That right. I need this error info.
But when I run eslint in cmd
eslint fileName.ts or eslint --ext .ts fileName.ts
cmd eslint return nothing or some other warning/error in this file.
eslintrc here
module.exports = {
"extends": ["xxx"],
"globals": {
"__SERVER_ENV__": true,
},
"rules": {
"react/jsx-filename-extension": 0,
"no-console": ["warn", { allow: ["error", "warn"] }],
"#typescript-eslint/no-unused-vars": ["error", {
"vars": "all",
"args": "after-used",
"ignoreRestSiblings": true
}],
},
"settings": {
"react": {
"createClass": "createReactClass", // Regex for Component Factory to use,
// default to "createReactClass"
"pragma": "React", // Pragma to use, default to "React"
"version": "detect", // React version. "detect" automatically picks the version you have installed.
// You can also use `16.0`, `16.3`, etc, if you want to override the detected value.
// default to latest and warns if missing
// It will default to "detect" in the future
},
"import/parsers": {
"#typescript-eslint/parser": [".ts", ".tsx"]
},
"import/resolver": {
// use <root>/tsconfig.json
"typescript": {
// always try to resolve types under `<roo/>#types` directory even it doesn't contain any source code, like`#types/unist`
"alwaysTryTypes": true,
"directory": "./",
},
},
},
"parser": "#typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"modules": true,
},
},
"plugins": ["#typescript-eslint", "import"],
};
and tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"noImplicitAny": true,
"module": "commonjs",
"lib": ["es6","dom","es2017"],
"target": "es5",
"jsx": "react",
"types":["react"],
"outDir": "/output",
"baseUrl": ".",
"paths": {
"src/*": ["./src/*"]
},
"allowSyntheticDefaultImports": true,
"sourceMap": true
},
"awesomeTypescriptLoaderOptions": {
"useWebpackText": true,
"useTranspileModule": true,
"doTypeCheck": true,
"forkChecker": true
},
"include": [
".d.ts",
"./src/**/*"
]
}
I hope to get whole error info by cmd. what should I do?

It appears that eslint by design will not perform your Typescript type checking. I am just running my build command locally using tsc to be notified of this "property missing in type" error message, and fixing when the build fails.
It's very inconvenient because I only get alerted to one error per build attempt. If anyone has a better solution I'd appreciate any help.

Related

Run mocha with Typescript throws: TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts"

I'm trying to write some tests with Typescript and Mocha.
Following its documentation I ended up with the following setup:
package.json
{
//...
"scripts": {
"test": "mocha",
},
//...
}
.mocharc.json
{
"extension": ["test.ts"],
"spec": "tests/*.test.ts",
"require": "ts-node/register",
"recursive": true
}
tsconfig.json
{
"compilerOptions": {
"outDir": "dist",
"module": "commonjs",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"sourceMap": false,
"strict": true,
"esModuleInterop": true,
"isolatedModules": true,
},
"files": [
"src/main/main.ts",
],
}
Running npm test throws the following error: TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".ts" for [...]/tests/task.test.ts.
That is my only test, and it works until I import a separate .ts file (../src/core/task), for completeness:
task.test.ts
import { assert } from 'chai';
import { Task } from '../src/core/task';
describe('Task', () => {
it('Task Run', () => {
const task = new Task({
title: "My Title",
command: "echo hello",
path: "."
});
task.run();
})
});
I have tried several permutations of my config according to some other answers as well as ts-mocha without success.
I have same problem before it work in ts-node#9 but not in ts-node#10 and then i tried this configuration in .mocharc.json to make it work as expected
{
"extensions": ["ts"],
"spec": ["**/*.spec.*"],
"node-option": [
"experimental-specifier-resolution=node",
"loader=ts-node/esm"
]
}
In my case the problem was caused by an import in a JS file imported by TypeScript test files. Transforming it to a require fixed the problem.
Generally speaking, when the exception occurs in:
Loader.defaultGetFormat [as _getFormat] internal/modules/esm/get_format.js
there can be only one explanation: Node.js is using its ESM loader to load what should be code transpiled by ts-node.
So the fix should always be - find the reason Node.js is switching to ESM and eliminate it.

Building es6 module in typescript project with webpack

I am trying to use imagemin node package in my project. It is a es6 module and I am getting error while using it.
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module. with "type" as "module" in package.json
ReferenceError: require is not defined with "type" as "commonjs" in package.json
My webpack config:
export default env => {
return {
mode: env.production ? 'production' : 'development',
entry: {
main: './src/main.ts',
worker: './src/worker.ts'
},
target: ['node', 'es2019'],
devtool: env.production ? false : 'inline-source-map',
watch: !env.production,
resolve: {
extensions: ['.ts', '.js'],
alias: {
src: _resolve(process.cwd(), './src')
}
},
module: {
rules: [{
test: /\.ts$/,
include: _resolve(process.cwd(), "src"),
use: 'ts-loader',
exclude: [/node_modules/, /\.spec\.ts/, /\.e2e-spec\.ts/]
}],
},
externalsPresets: { node: true },
externals: [nodeExternals()],
output: {
filename: '[name].js',
path: OUTPUT_DIR,
clean: !!env.production,
devtoolModuleFilenameTemplate: 'file:///[absolute-resource-path]',
library: {
type: 'module'
}
},
optimization: {
minimize: false, //!!env.production
mangleExports: true,
minimizer: [new terserPlugin({
terserOptions: {
output: {
comments: false
},
keep_classnames: true,
},
extractComments: false,
})]
},
experiments: {
outputModule: true
}
};
};
My tsconfig:
{
"compilerOptions": {
"module": "ES2020",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "es2019",
"sourceMap": true,
"strict": true,
"baseUrl": ".",
"esModuleInterop": true,
"noImplicitAny": true,
"moduleResolution": "node",
"outDir": "../bin/server",
"typeRoots": [
"node_module/#types",
"./typings"
],
"types": [
"node",
"#types/jest"
]
},
"exclude": [
"node_modules"
]
}
When I try to "import" imagemin in one of my .ts file, webpack convert it to "require". I have also tried using import() but it doesn't work either.
I have made a repo on github
Is there a way to get es6 bundle (preferred) or use imagemin with commonjs bundle?
I couldn't found a way to bundle es6 format through webpack but i was able to use es6 module in commonjs system while bundling through webpack.
externals: [
nodeExternals({
allowlist: ['imagemin', 'imagemin-mozjpeg']
}),
async function ({ request }) {
if (request === 'imagemin' || request === 'imagemin-mozjpeg')
return `import ${request}`;
},
]
This is how i got imagemin to work.
Change your start script
"start": "node --experimental-modules src/index.mjs "
and In package.json Add
{
...
"type": "module",
...
}

Unable to execute Typescript, NodeJS, and Sequelize due to a Model Error

I am attempting to run sequelize on NodeJS. I am writing the code in Typescript
The versions of software I am using is as follows:
nodejs - 14.16.0 sequelize - 6.5.1 typescript - 4.2.3
Typescript builds correctly but when running the node command against the compiled index.js file, I get the following error:
import { DataTypes, Model, Sequelize, TableHints } from 'sequelize';
^^^^^
SyntaxError: Named export 'Model' not found. The requested module 'sequelize' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'sequelize';
const { DataTypes, Model, Sequelize, TableHints } = pkg;
The code is a simple index.ts
import { DataTypes, Model, Optional, Sequelize, TableHints } from 'sequelize';
let server = "server";
let database = "db";
let user_name = "user";
let password = "password";
let app_name = "api";
let _mssql_service = new Sequelize(database, user_name, password, {
dialect: "mssql",
isolationLevel: TableHints.READUNCOMMITTED,
host: server,
dialectOptions: {
options: {
appName: app_name,
},
},
});
// These are all the attributes in the User model
export interface TrackingAttributes {
id: number;
column1: string;
...
}
interface TrackingCreationAttributes
extends Optional<TrackingAttributes, "id"> {}
export class TrackingModel
extends Model<TrackingAttributes, TrackingCreationAttributes>
implements TrackingAttributes {
public id!: number; // Note that the `null assertion` `!` is required in strict mode.
public column1!: string;
...
}
async function test() {
try {
TrackingModel.init(
{
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
},
column1: {
type: DataTypes.STRING(10),
allowNull: true
},
},
{
tableName: "table1",
schema: "schema1",
sequelize: _mssql_service, // passing the `sequelize` instance is required
}
);
let val = await TrackingModel.findOne({ where: { id: 24 } });
console.log("Connection has been established successfully.");
console.log(val);
} catch (error) {
console.error("Unable to connect to the database:", error);
} finally {
_mssql_service.close();
}
}
test();
I have the following types installed and included in package.json:
"#types/node": "^14.14.35",
"#types/sequelize": "^4.28.9",
"#types/validator": "^13.1.3"
I have the following tsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "esnext",
"esModuleInterop": true,
"moduleResolution": "node",
"strict": true,
"declaration": true,
"outDir": "bin",
"types": ["node"],
"typeRoots": ["../node_modules/#types"],
"sourceMap": true
},
"include": ["**/*.ts"],
"exclude": ["tests", "dist", "node_modules", "lib", "bin"]
}
I have the following package.json
{
"name": "console-application",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"sequelize": "^6.5.1"
},
"devDependencies": {
"#types/node": "^14.14.35",
"#types/validator": "^13.1.3"
}
}
I am stumped on why I am getting this error but any assistance would be appreciated.
Normally the #types/* packages match the major version of the package they provide types for. In this case you have sequelize v6 but #types/sequelize v4 so they don't match.
I had a look at the sequelize repo and found that they provide their own types since v5, so you should uninstall #types/sequelize as those are not needed and are the cause of your issue.
See here for the info I found - https://sequelize.org/master/manual/typescript.html
Edit: Additional info in issues with tsconfig.json/package.json after OP updated their post to include it.
First of all, you need to include typescript in your dependencies list. You can simply run npm i typescript (or use a specific version if you need to).
Then, the issue with your tsconfig.json is that you have set the module compiler option to esnext but Node does not support this out of the box (Node does has experimental support for this via the --experimental-modules flag, but I'm ignoring this for now). You should set this to commonjs instead.
Working tsconfig.json:
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"esModuleInterop": true,
"moduleResolution": "node",
"strict": true,
"declaration": true,
"outDir": "bin",
"types": ["node"],
"typeRoots": ["../node_modules/#types"],
"sourceMap": true
},
"include": ["**/*.ts"],
"exclude": ["tests", "dist", "node_modules", "lib", "bin"]
}
With this I was able to compile and run the code, although I now get a separate error which is Error: Please install tedious package manually from sequelize - but this is just a dependency issue.

tsconfig's path parameter and ESLint

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

ESLint with Mocha

I am trying to use ESLint for mocha, but for some reason the rules don'y apply and the linting passes.
My config file:
module.exports = {
"env": {
"browser": true,
"es6": true,
"node": true,
},
"extends": "eslint:recommended",
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly",
"expect": "true"
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
overrides: [
{
files: [
"**/*.test.js"
],
env: {
mocha: true
},
plugins: ["mocha"],
rules: {
"mocha/no-exclusive-tests": "error",
"mocha/no-pending-tests": "error"
}
}
]
};
My test file only includes one line:
it('should throw a lint error')
The linter should find an error because of the 'no pending tests' rule, yet when I run the test file with eslint the linting passes as a success.
I have no idea why. I looked it up online and it seems like my configuration file is good as it is.
your solution is the same as this post answer.
However, the one that suits you better is the one you only edit the .eslintrc file as shown in eslint-configuration-doc, which would go like this:
module.exports = {
env: {
browser: false,
es6: true,
node: true,
mocha: true
}
// More code to go on that is not relative to your question ...
}
The line you are aiming is the one with
mocha: true
This solution worked for me.
{
"env": {
"browser": true,
"es6": true,
"mocha": true // add mocha as true to your ".eslintrc. *" file
}
}

Resources