Visual studio code: navigate to jsx components - reactjs

In visual studio code, I would like to be able to navigate to an imported file using ctrl + click.
So far I'm able to do it for javascript files (.js), but it's not working for react files (.jsx)
Here is what my directory structure looks like :
Here are the imports (relative and absolute) in my TestImport.jsx Component :
import DummyTwo from 'components/common/dummy-two/DummyTwo.jsx';
import something from 'components/common/my-file/myFile.js';
import DummyOne from '../common/dummy-one/DummyOne.jsx';
import somethingElse from '../common/my-file/myFile2.js';
And here is my jsconfig.json for vscode
{
"compilerOptions": {
"experimentalDecorators": true,
"baseUrl": "src"
}
}
Code can be retrieved here:
https://github.com/fthebaud/react-boilerplate
Am I missing something in the jsconfig file? regarding the extensions maybe?

You need to add "jsx": "react" to use jsx:
{
"compilerOptions": {
"experimentalDecorators": true,
"baseUrl": "src",
"jsx": "react"
}
}
See here for more info about this setting

Related

React Nextjs - module import using # no longer working

I was able to import modules using # but I upgraded a few components including react and nextjs.
this used to work
import { ValidateProps } from '#/api-lib/constants';
Now getting error:
Module not found: Can't resolve '#/api-lib/constants'
It works if I give it a path
import { ValidateProps } from '../../api-lib/constants';
Personally, I use a jsconfig.json file. It contains:
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
Then I am able to import like so:
import Loadable from "components/ui/Loadable";
I just figured I no longer had jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#/api-lib/*": ["api-lib/*"],
}
}
}

React TypeScript - Exporting more than one component

Given this folder structure:
├──components/
| └─Elements/
| └─Button/
| └─Input/
| └─index.ts
| └─Home/
| └─home.tsx
I would like to export Button and Input so I can access them from the home component by doing:
home.tsx
import { Button, Input } from '#elements/'
I have tried this:
index.ts (in Elements folder)
export { Button } from './Button/button';
export { Input } from './Input/input';
But it does not work, I get: Cannot find module '#elements/' or its corresponding type declarations. even thou the resolve alias does work.
tsconfig.json
{
"compilerOptions": {
"outDir": "../public",
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": true,
"jsx": "react",
"moduleResolution": "node",
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"baseUrl": "./",
"rootDir": "./",
"typeRoots": ["./node_modules/#types", "./src/#types"],
"paths": {
"#src/*": ["src/*"],
"#images/*": ["src/images/*"],
"#styles/*": ["src/styles/*"],
"#components/*": ["src/components/*"],
"#elements/*": ["src/components/Elements/*"],
},
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"importsNotUsedAsValues": "preserve"
},
"exclude": ["node_modules", "webpack"]
}
webpack.config.babel.js
...
resolve: {
alias: [
'#src': join(rootDir, '/src'),
'#images': join(rootDir, '/src/images'),
'#assets': join(rootDir, '/src/assets'),
'#styles': join(rootDir, '/src/styles'),
'#components': join(rootDir, '/src/components'),
'#elements': join(rootDir, '/src/components/Elements')
]
extensions: ['.tsx', '.ts', '.js', '.jsx']
},
I found the solution to be removing the * from the path declaration on tsconfig.json
This
"#elements/*": ["src/components/Elements/"]
Instead of this
"#elements/*": ["src/components/Elements/*"]
And then importing it by using
import { Button, Input } from '#elements/'
or
"#elements": ["src/components/Elements"]
import { Button, Input } from '#elements'
import { Button } from './Button/button';
import { Input } from './Input/input';
should probably be
export { Button } from './Button/button';
export { Input } from './Input/input';
If they are default exports, you have to do this.
export { default as Button } from './Button/button';
export { default as Input } from './Input/input';
Module resolution in Typescript is the process that the compiler uses to figure out what an import refers to. You can read more on module resolution in the Typescript Handbook.
import { Button } from './Button/button';
This type of import is called a relative import. A relative import is one that starts with /, ./ or ../.
Any other import is considered non-relative. Some examples include:
import * as $ from "jquery";
import { Component } from "#angular/core";
There is two module resolution strategy in typescript which is node and classic. By default module resolution is set to classic.
Set the module resolution to node would solve your problem.
"moduleResoution": "node"
Note: node module resolution is the most-commonly used in the TypeScript community and is recommended for most projects. If you are having resolution problems with imports and exports in TypeScript, try setting moduleResolution: "node" to see if it fixes the issue.

jsconfig.json path alias not working properly

I have a react project created using create-react-app, and I'm trying to add material kit react to the project. I have placed the assets and components of material kit react under src/template and I would like to change the path of assets from src/assets to src/template/assets.
The problem is when I configured jsconfig.json to define the path for assets alias I get the error "Module not found" when using assets, but if I use the template alias it works just fine.
Here is my jsconfig.json file:
{
"compilerOptions": {
"baseUrl": "src",
"target": "es6",
"paths": {
"template/*": ["src/template/*"],
"assets/*": ["src/template/assets/*"]
}
},
"exclude": ["node_modules"]
}
If someone can help me to understand why the template alias is working and not the assets alias.
please try the code below.
I think your 'baseUrl' is wrong.
{
"compilerOptions": {
"baseUrl": ".",
"target": "es6",
"paths": {
"template/*": ["./src/template/*"],
"assets/*": ["./src/template/assets/*"]
}
},
"exclude": ["node_modules"]
}
So, This will make VS Code IntelliSense work.
But there may be other issues. (..Because I went through it.)
Other issue is that resolve does not work.
error is the same
This dependency was not found:
* template/somtething in ./blahblah..
To install it, you can run: npm install --save template/somtething`
If there is an error above,
try to set an alias to the 'template' folder using the following Webpack configuration.
https://webpack.js.org/configuration/resolve/

Add absolute paths to app created by "Create React App"

I have created an app by Create React App and to be more specific I'm also using typescript.
I can't figerout how to set absolute paths to access to my components, pages, etc..
In a different scenario I would update my tscongig with something like:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#components/*": ["src/components/*"]
}
}
}
but I have no idea how to implement this as I'm using react-scripts
any idea?
Create a tsconfig.json file and add the code below.
{
"compilerOptions": {
"baseUrl": "src"
},
"include": [
"src"
]
}
Then you can import your components as
import Header from 'components/Header';
You should be able to use the same approach if create a jsconfig.json file in your solution, which supports the same baseUrl and rootPath properties as tsconfig.
Alternative is adding an .env file in your solution with the following line:
NODE_PATH=src/
Also, apart from the env file add this to your jsconfig.json
{
"rootDir": "src",
"compilerOptions": {
"baseUrl": "src",
"paths": {
"*": ["*"]
}
}
}
This should resolve both the compiler being able to find your absolute imports, and linter handling them properly.
See Building Your App / Importing a Component / Absolute Imports in the Create React App docs.
You can configure your application to support importing modules using absolute paths. This can be done by configuring a jsconfig.json or tsconfig.json file in the root of your project. If you're using TypeScript in your project, you will already have a tsconfig.json file.
Below is an example jsconfig.json file for a JavaScript project. You can create the file if it doesn't already exist:
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
If you're using TypeScript, you can configure the baseUrl setting inside the compilerOptions of your project's tsconfig.json file.
Now that you've configured your project to support absolute imports, if you want to import a module located at src/components/Button.js, you can import the module like so:
import Button from 'components/Button';

Extend TypeScript 2.5.2 Component Props definition in a separate definition file

I have downloaded a NPM package called react-bootstrap-table with type definitions.
https://www.npmjs.com/package/react-bootstrap-table
https://www.npmjs.com/package/#types/react-bootstrap-table
Unfortunately the types are outdated and a prop called strictSearch is missing from BootstrapTable definitions that I need. I can of course update the definitions in node_modules but we are a team working on this project and we are not committing the node_modules folder.
I have read the thread here but I can't get it working anyway:
How do I extend a TypeScript class definition in a separate definition file?
How can I get it working?
If I add a new folder called for example "react-bootstrap-table-ex" everything looks good but of course I have no corresponding module for that.
Module not found: Error: Can't resolve 'react-bootstrap-table-ex'
If I rename my folder to react-bootstrap-table the types are only loaded from my new index.d.ts file and I cant reference the original definitions. I then tried to set the path for the original definitions manually but again the Module not found error occurs.
Module not found: Error: Can't resolve '../../../node_modules/#types/react-bootstrap-table'
Code:
import { ComponentClass, Props } from "react";
import { BootstrapTableProps, BootstrapTable } from '../../node_modules/#types/react-bootstrap-table';
export interface BootstrapTableExProps extends BootstrapTableProps {
strictSearch?: boolean;
}
export interface BootstrapTableEx extends ComponentClass<BootstrapTableExProps> {
}
declare const BootstrapTableEx: BootstrapTableEx;
Use Module Augmentation to extend existing typings. Create .ts file with the following code
import { BootstrapTableProps, BootstrapTable } from 'react-bootstrap-table';
declare module "react-bootstrap-table" {
export interface BootstrapTableExProps extends BootstrapTableProps {
strictSearch?: boolean;
}
export interface BootstrapTableEx extends ComponentClass<BootstrapTableExProps> {
}
}
New typings will be available in the entire project.
You can find more info here https://www.typescriptlang.org/docs/handbook/declaration-merging.html under Module Augmentation section.
Update:
Thanks to #niba I solved it like this, file Typings\react-bootstrap-table-ex\index.d.ts
import { BootstrapTable } from 'react-bootstrap-table';
declare module "react-bootstrap-table" {
export interface BootstrapTableProps {
strictSearch?: boolean;
}
}
Original:
Solved it by copying index.d.ts from node_modules\#types\react-bootstrap-table into Typings\react-bootstrap-table and edit the file there.
My tsconfig.json below for reference:
{
"compilerOptions": {
//baseUrl and paths needed for custom typings
"baseUrl": ".",
"paths": {
"*": [ "./Typings/*" ]
},
//We use webpack bundle instead
"outDir": "./Scripts/NotUsed",
"sourceMap": true,
"noImplicitAny": true,
"noImplicitThis": true,
"forceConsistentCasingInFileNames": true,
"noImplicitReturns": true,
//"experimentalDecorators": true,
"module": "commonjs",
"target": "es5",
"jsx": "react",
"lib": [ "es5", "es6", "dom" ]
},
"exclude": [
"node_modules",
"wwwroot"
]
}

Resources