VSCode Intellisense doesn't resolve imports with absolute paths - javascript

I'm maintaining an electron app using Typescript. I'm trying to implement absolute paths for imports in my project.
I understand that the way you would normally resolve this would be to edit webpack config, but since I'm using react CRA, and ideally don't want to "eject" and manage things myself just for this issue, I've been looking for other ways to solve the problem.
The intent is to go from something like this:
import * as Constants for '../../../../types/Constants'
to:
import * as Constants from '#types/Constants'
After reading through lots of articles, these are the steps I "think" I should be taking:
So far what I've done is:
Installed 'react-app-rewired' via NPM, and set up the config-overrides.js (to allow absolute imports to work).
Updated the tsconfig.json file (to allow VSCode to "see" the absolute imports)
(EDIT: Most of the steps I've tried come from absolute path with react, react-app-rewire and typescript)
//~config-overrides.js
module.exports = function override(config, env) {
config.resolve = {
...config.resolve,
alias: {
...config.resolve.alias,
'#types': path.resolve(__dirname, 'src/types')
}
}
return config;
Doing a console.log() of the config shows the alias field was set correctly. This allows the system to be aware of the imports via their absolute paths. Importing via the #types path operates as expected and I'm able to build, launch, and interact with my app without issue.
The problem arises with VSCode Intellisense, which marks all the absolute imports with the "red squiggly" and thus blocking things like autocomplete and being able to navigate to function/field definitions. I tried to resolve this by updating my tsconfig.json file thusly (specifcally adding the "extends" option and the referenced "tsconfig.paths.json" file):
// ~tsconfig.json
{
"extends": "./tsconfig.paths.json",
"compilerOptions": {
"target": "ES2015",
"module": "esnext",
"allowJs": true,
"sourceMap": true,
"outDir": "./build",
"strict": true,
"noImplicitAny": false,
"esModuleInterop": true,
"preserveSymlinks": true,
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"moduleResolution": "node",
"isolatedModules": true,
"noEmit": true,
"resolveJsonModule": true,
"jsx": "preserve"
},
"include": [
"src/backend/**/*.ts",
"src/backend/**/*.tsx",
"src/backend/**/*.js",
"src/electron.ts"
]
}
// ~tsconfig.paths.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#types/*": ["./src/types/*"]
}
}
}
Possible issue:
When I build, I receive the following two error messages, and I don't know what to do with them:
compilerOptions.baseUrl must not be set (absolute imports are not supported (yet))
compilerOptions.paths must not be set (aliased imports are not supported)
EDIT:
I have a TSLint file in my project. Do I need to make any updates to that to make this work?

Related

typescript javascript library dependencies for production build

I'm pretty new to web development and JavaScript. I'm currently working on a project where I'm using plotly. I found a typescript interface and included it in my typescript script like this:
import Plotly, { PlotlyHTMLElement } from "plotly.js-dist-min";
When I compile my typescript code to JavaScript the dependencies don't work anymore. currently I'm always editing my JavaScript output manually and correct the dependencies like this:
import Plotly, { PlotlyHTMLElement } from "plotly.js-dist-min"; //WORKS IN TS REMOVE IN JAVASCRIPT
import "../node_modules/plotly.js-dist-min/plotly.min.js"; //WORKS IN JS
import "./plotly.min.js"; //WORKS IN JS WHEN plotly.min.js is copied to dist folder
Is it possible to automatize the manual steps whenever I call "tsc -p ."
This is my tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"module": "esnext",
"lib": [
"ES2017",
"DOM"
],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"strictPropertyInitialization": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true
}
}
I guess that's a very basic question but I couldn't find a way yet.
Thanks for your advice.

Compile Typescript so that it does not use require() in JavaScript

Writing a PacMan game in TypeScript, my app.ts file has in import for the PacMan class like this:
import { PacMan } from "./pacman"
Using TypeScript 4.9.4 and for some reason unknown to me, I needed to configure NodeJS 18.12.1, this gets compiled in WebStorm 2022.3 to a line
var pacman_1 = require("./pacman");
For that line, my browser (Firefox 108.0) throws an exception
ReferenceError: require is not defined
I read some stuff but honestly, I hardly understand anything.
I tried suggestions for changes in tsconfig.json, so I set "target": "es5", and "esModuleInterop": true, but that didn't result in any better in the browser. My full config is currently
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"sourceMap": true,
"inlineSources": true,
"esModuleInterop": true,
},
"compileOnSave": true,
"exclude": [
"node_modules"
]
}
I think the problem lies in the choice of the module. I don't know what CommonJS or RequireJS or an AMD is, nor how I would configure that correctly. I don't know the difference between ES5 and ES6, so it's guesswork for me, or "trial and error".
I thought TypeScript would compile to JavaScript. Can I configure "module" to VanillaJS maybe? Or do I really have to go with a dependency like RequireJS? If so, why doesn't the TypeScript compiler compile that dependency into the resulting JavaScript?
I can't believe that it so simple and not documented in module. Thanks to #jabaa, I simply used "module": "es6" in my tsconfig.json and that fixed it.
{
"compilerOptions": {
"module": "es6",
"target": "es6",
"sourceMap": true,
"inlineSources": true,
"esModuleInterop": true,
},
"compileOnSave": true,
"exclude": [
"node_modules"
]
}

Typescript can't find module of a referenced Project

I am trying to share code between 2 seperate Typescript projects.
To demonstrate this easily reproducable problem I created a minimal repository here (Including instructions to reproduce):
https://github.com/realdegrees/ts-function-reference/tree/master/project
You can check out the repo or the following code snippets.
The issue is that I can import e.g. interfaces and enums just fine and they work (ran the code and had the enums logged) but as soon as it's a function I'm trying to import it doesn't work anymore.
Running tsc works fine and throws no errors. You can even see that typescript resolves the module in question perfectly fine.
❯ tsc --traceResolution | grep 'reference/lib'
======== Resolving module '../reference/lib' from '/home/fasc/projects/reference-
test/project/index.ts'. ========
Loading module as file / folder, candidate module location
'/home/fasc/projects/reference-test/reference/lib', target file type 'TypeScript'.
File '/home/fasc/projects/reference-test/reference/lib.ts' exist - use it as a name
resolution result.
======== Module name '../reference/lib' was successfully resolved to
'/home/fasc/projects/reference-test/reference/lib.ts'. ========
======== Module name './lib' was successfully resolved to
'/home/fasc/projects/reference-test/reference/lib.ts'. ========
However as soon as I try to start the project it's the 'ole
Error: Cannot find module '../reference/lib'
I have tried importing the index.ts, lib.ts directly and paths in tsconfig.ts.
References are setup correctly and it obviously works with types but for some reason not functions.
The project looks like this: https://i.stack.imgur.com/KXOGc.png
Files:
////////////// project/index.ts
// None of these work
import { foo as regularDirectImport } from '../reference/lib';
import { foo as regularIndexImport } from '../reference/index';
import {foo as pathsImport} from '#reference';
pathsImport();
regularDirectImport();
regularIndexImport();
/////////// project/tsconfig.ts
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"baseUrl": ".",
"paths": {
"#reference": ["../reference/index"]
}
},
"references": [
{
"path": "../reference"
}
]
}
////////// reference/index.ts
export * from './lib';
////////// reference/lib.ts
export const foo = () => {
console.log('bar');
}
////////// reference/tsconfig.ts
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"outDir": "dist",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"baseUrl": "src",
"declaration": true,
"declarationMap": true,
"composite": true
}
}
I would die for some help, I have found several guides on how to import code from external typescript projects and they all mention that functions work as well but I just cannot get it work.

How do I import a Javascript library into Typescript when the package has a declaration file

I am trying to use the type definitions in the callbag library. This library declares its type definition file in its package.json. It is not uploaded to DefinitelyTyped. When I try to import the library, I get the error:
Cannot find module 'callbag'. Did you mean to set the 'moduleResolution' option to 'node', or to add aliases to the 'paths' option?
This is how I import it:
import type { Sink } from 'callbag';
Here is my tsconfig.json:
{
"compilerOptions": {
"module": "es6",
"noEmitOnError": true,
"outDir": "./dist",
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "es5"
},
"include": ["./src/**/*"]
}
I also tried adding "types": ["callbag"] to the tsconfig.json, but it didn't work.
How do I get typescript to recognize the types for this library?
As posted in the comments, I needed to add "moduleResolution": "node" to my tsconfig.json. Not sure why because nothing that I working on is related to Node.js. But that's what worked.

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.

Categories