non existing import stopped breaking build - javascript

I have a project based on create react-app, and it seems since an update of the yup dependency, it stopped launching error on invalid import.
The error "module filename has no exported member X", which used to be launched by react-scripts build, as well as by npm start has completely disappeared, though my IDE still finds such error.
react-scripts build and npm start will still launch an error if I try to use the unexisting import as a variable, but not if I try to use it as a type.
I tried looking at i.e this question or this one, or others similar questions, but none was like my case (i.e, the files giving problems DO have import, and the commit introducing the bug was litterally changing just the yup dependency in package.json, and changing package-lock.json accordingly. I also tried updating my #typescript-eslint/no-unused-vars rules to error, but it gave me too many errors, and I have no guarantee it'll catch any unexisting type exported and used as type)
In case it helps, here is my tsconfig.json
{
"compilerOptions": {
"baseUrl": "src",
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react",
"noFallthroughCasesInSwitch": true
},
"include": [
"src"
]
}
and my .eslintrc.json
{
"parser": "#typescript-eslint/parser",
"parserOptions": {
"tsconfigRootDir": ".",
"project": [
"./tsconfig.json"
]
},
"extends": [
"react-app",
"eslint:recommended",
"plugin:#typescript-eslint/recommended",
"prettier/#typescript-eslint",
"plugin:prettier/recommended"
],
"plugins": [
"filenames"
],
"rules": {
//- https://palantir.github.io/tslint/rules/no-null-undefined-union/ should be added once a typescript-eslint equivalent exists
"#typescript-eslint/explicit-function-return-type": 0,
"#typescript-eslint/no-explicit-any": 0,
// as per https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-unused-vars.md, we must disable the base rule to prefer the typescript one
"no-unused-vars": 0,
"filenames/match-exported": 1,
"#typescript-eslint/prefer-as-const": 1,
"#typescript-eslint/ban-types": 1,
"#typescript-eslint/no-unnecessary-type-assertion": 1,
"#typescript-eslint/strict-boolean-expressions": [
1,
{
"allowNullableString": true,
"allowNullableObject": true,
"allowNullableBoolean": true,
"allowNumber": false,
"allowAny": true
// we use lodash, better allow these any
}
],
"#typescript-eslint/no-unused-vars": 1,
"no-return-await": 2,
"curly": 2,
"#typescript-eslint/no-inferrable-types": [
2,
{
"ignoreParameters": true
}
]
}
}
Thank you for any help.

So I ended up fixing this problem by reinstalling my dependencies with a more up to date version. I juste removed my node_module and my package-lock.json before running npm i. I know suppressing node_module and package-lock should have had no effect, but I preferred to be sure.
It made my project have all kind of new errors, but in the lot, there was my error for invalid import, so it was good for me.

Related

Cypress in node_modules overwriting zx's value for global `$` variable even though I'm not importing it

I have zx and Cypress installed. Zx defines $ as a command runner and Cypress defines $ as JQuery. I'm not importing Cypress types anywhere, but when I use zx's $, I'm getting errors like Property 'stdout' does not exist on type 'JQuery<HTMLSelectElement>'.. After uninstalling Cypress, these errors go away.
I tried adding Cypress to exclude, but it didn't work. Here's the relevant parts of my TSConfig:
tsconfig-base.json:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
"noEmit": true,
"noEmitHelpers": true,
"strict": true,
"isolatedModules": true,
"esModuleInterop": true,
"skipLibCheck": true,
"baseUrl": "./",
"noImplicitAny": true,
"noImplicitOverride": true,
"strictNullChecks": true,
"useUnknownInCatchVariables": true,
"resolveJsonModule": false,
"lib": ["es2021"],
"types": [
"webpack-env",
],
"experimentalDecorators": true,
"noErrorTruncation": true,
},
"exclude": [
"./node_modules",
"./node_modules/cypress/types/jquery",
],
}
scripts/tsconfig.json:
{
"extends": "../tsconfig-base.json",
"compilerOptions": {
"checkJs": true,
"noImplicitAny": false,
"rootDir": ".",
"types": [
"webpack-env",
"zx",
],
},
"include": [
".",
],
}
Typescript does not do "auto imports", and this has nothing to do with Typescript configs and everything to do with code that is importing Cypress or JQuery directly or indirectly, as well as the order of import, because the one imported later will overwrite the globally set $ with its value.
First clue: You have Cypress installed for a reason. *That means something is using it. The fact that uninstalling it changes the behavior proves this.
Remember, Typescript/Javascript imports are transitive/recursive. If you import A, and A imports B and B imports C, the script for C will execute before the script for B which will execute before the script for A.
Also: tsconfig exclude does not behave the way you think it does:
Important: exclude only changes which files are included as a result of the include setting. A file specified by exclude can still become part of your codebase due to an import statement in your code, a types inclusion, a /// <reference directive, or being specified in the files list.
It is not a mechanism that prevents a file from being included in the codebase - it simply changes what the include setting finds.

Sharing TypeScript code between Node.js and Vue.js

I'm having a hard time figuring out how to do this. My environment is:
Node.js 16.1.x
Vue.js 3.x
TypeScript 4.2.4
My directory structure is like this:
Root (Node.js server)
shared
MySharedFile.ts
ui (Vue.js code)
MySharedFile.ts is exporting a very simple module:
export const MyShared = {
TEST: 1
};
In Vue.js, I'm trying to import this module import {MyShared} from '../../shared/MySharedFile', but when the app builds, I get the error Parsing error: 'import' and 'export' may appear only with 'sourceType: module'. I've searched and found a thread that suggests changing the eslintrc settings, which didn't work. This error really doesn't make sense to me, so what does it mean, and how can I fix it?
ui/tsconfig.json
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"outDir": "./dist",
// https://github.com/TypeStrong/ts-loader/issues/1138
"importsNotUsedAsValues": "preserve",
"types": [
"webpack-env"
],
"paths": {
"#/*": [
"src/*"
]
},
"lib": [
"es2020",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
ui/.eslintrc.js
module.exports = {
root: true,
env: {
node: true
},
extends: [
'#vue/typescript',
'plugin:vue/vue3-recommended',
'plugin:vue/vue3-essential',
'eslint:recommended',
'#vue/typescript/recommended'
],
parserOptions: {
ecmaVersion: 11,
sourceType: 'module',
allowImportExportEverywhere: true
}
}
For anyone wanting the source code... I'm now at a new error Parsing error: ‘import’ and ‘export’ may appear only with ‘sourceType: module’
I learned a few things with this. The first is that I'm using what's referred to as a monorepo. The second was that I should be using some sort of workspace, and I ended up using npm workspaces, but there're other options, like yarn workspaces. I had to refactor my app to follow a different structure, so I now have something like this:
Root (main workspace)
api (Node.js)
package.json ("dependencies": {"shared": "^1.0.0"})
tsconfig.json
package-lock.json (removed this)
shared (TypeScript code)
package.json ("version": "1.0.0")
tsconfig.json
ui (Vue.js)
package.json ("dependencies": {"shared": "^1.0.0"})
tsconfig.json
package-lock.json (removed this)
package.json ("workspaces": ["api", "shared", "ui"])
package-lock.json (this gets generated and now contains all deps for workspaces)
After moving to this structure, I didn't have to modify the tsconfig.json or vue.config.js files to add the shared dir, as I could reference it like any other package when importing. I also like this approach because it keeps all of my node_modules in one dir at the main workspace level.

Typescript's declaration merging not working as expected using ts-node

For a project using the express-session package, I'm trying to mutate the session object by simply adding a user key.
req.session.user = 123;
Coming from this question's accepted answer, I understand I could use declaration merging to extend the SessionData interface, using my own interface.
Looking at various open-source projects, such as the HospitalRun components repository I notice them having the types directory in their tsconfig.json file under the include section like this.
"include": [
"src",
"types"
]
My whole tsconfig.json looks like this, which lives in the root of the project.
{
"include": [
"types",
"src",
],
"exclude": [
"node_modules"
],
"compilerOptions": {
"lib": [
"esnext",
"esnext.asynciterable"
],
"baseUrl": ".",
"skipLibCheck": true,
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"outDir": "build",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"strictPropertyInitialization": false,
},
}
I tried doing the same, together a file called express-session.d.ts in the root of this folder (~/types/), having the following contents:
import session from 'express-session';
declare module 'express-session' {
interface SessionData {
user: any;
}
}
However, the error I keep receiving is this.
Property 'user' does not exist on type 'Session & Partial<SessionData>'
When I do however add this piece of code above the code I use for mutating my session object, I no longer have the problem. This doesn't seem like the right approach though.
Also, when I use tsc src/index.ts --build instead of ts-node src/index.ts it also works.
What am I doing wrong here? How can this be fixed? I also tried using the typeRoots, using the same folder.
LATEST UPDATE (08-MAY-2021)
When running the typescript program by using ts-node, even typeRoots are specified in tsconfig.json, it cannot recognise the custom .d.ts and prompt Property 'x does not exist on type y` error.
According to https://github.com/TypeStrong/ts-node/issues/1132#issuecomment-716642560
One of the contributors of ts-node suggested multiple ways to solve it.
Here is one of it:
Specifying file: true flag in tsconfig.json to inform ts-node to load files, include and exclude options from tsconfig.json on startup
{
"ts-node": {
"files": true
},
"exclude": [...],
"compilerOptions": {
...
}
OLD: (07-MAY-2021)
There is no need to use include in tsconfig.json and the paths are not correct. The compiler can search the ts file in the directory and sub-directories
Try to remove it. and restart TS server.
If you are using VSCode, try Cmd + Shift + P or Ctrl + Shift + P and search Restart TS server and see if the user type error still exist
{
"exclude": [
"node_modules"
],
"compilerOptions": {
"lib": [
"esnext",
"esnext.asynciterable"
],
"baseUrl": ".",
"skipLibCheck": true,
"module": "commonjs",
"esModuleInterop": true,
"target": "es6",
"moduleResolution": "node",
"outDir": "build",
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"strictPropertyInitialization": false,
},
}

How to resolve "Definition for rule '#typescript-eslint/rule-name' was not found"

I'm trying to add TypeScript compilation to an existing Javascript project.
AFAIK this is supposed to be possible (even easy), and you can incrementally spread TS through the codebase. Unfortunately this isn't what I'm seeing - after adding typescript and trying to start the project, I get this error for every single file in the project:
Definition for rule '#typescript-eslint/rule-name' was not found
There is no instance of the string rule-name anywhere in my source code.
This is my tsconfig.json:
{
"compilerOptions": {
"baseUrl": "src",
"noImplicitAny": false,
"sourceMap": true,
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"esModuleInterop": true,
"jsx": "react",
"skipLibCheck": true
},
"include": [
"src",
"types"
],
"exclude": [
"node_modules",
"build"
]
}
I have tried adding "checkJs": false to the config and restarting but that doesn't change anything.
I haven't been able to track down anything online about this "rule-name" problem. It really looks like this is a placeholder text of some sort, but I can't find the source.
Can anybody suggest anything that might help me get this project to build?
The error that you have is coming from ESLint and means that you have a rule in your .eslintrc which doesn't exist in any of your plugins. This could have happened if you followed the usage guide for #typescript-eslint/eslint-plugin but didn't replace the placeholder rule-name with an actual rule name as seen here https://www.npmjs.com/package/#typescript-eslint/eslint-plugin
For those who do not want to just disable ESLint but make it work, running npm update could resolve the issue. In my case updating just #typescript-eslint/parser and #typescript-eslint/eslint-plugin was not enough but after npm update warnings dissapeared and ESLint was up and running.
Also worth to keep in mind this higlight from package authors:
It is important that you use the same version number for #typescript-eslint/parser and #typescript-eslint/eslint-plugin.
More detailed packages setup on npmjs.
This is because the rule is not declared in your eslint.json file
Add the following line to your RULES in esling.json file
"#typescript-eslint/object-curly-spacing" : "off"
Refer the image below to know more
Refer this image to add the rule to eslint.json file
For me, it was enough to add plugin:#typescript-eslint/recommended
in the .eslintrc file.
"extends": [
...<otherExtentions>...
"plugin:#typescript-eslint/recommended"
]
If you're using react-app-rewired and customize-cra, you need to make sure you use disableEsLint from the latter; otherwise linting errors become typescript errors and prevent compilation.

ionic 2 typescript source map not created

I am trying to debug Ionic 2 Application And I want to know how to include souceMap for every typescript file that maps to the javascript files.
But when I open the dev tools in Chrome there is no any souceMap file.
Also, I enabled the "sourceMap":true in tsconfig.json file.
This is my tsconfig.json file
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"declaration": false,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": [
"dom",
"es2015"
],
"module": "es2015",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"types": [
"jasmine"
]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
],
"compileOnSave": false,
"atom": {
"rewriteTsconfig": false
}
}
After that, I tried changing the ionic.config.json according to this
sourcemaps not working for ionic 2. But it also did not work for me.
Does anyone know what is wrong?
found the answer.
Still .map files are not generated. Because it is a bug see this issue. But now I can debug after adding this
"config":{
"ionic_source_map":"source_map"
}
into package.json file. Now all the .ts files are shown in the debug mode.
It has changed now to -
config: {
ionic_bundler: "webpack",
ionic_source_map_type: "#inline-source-map"
}

Categories