Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with ESLint, React/TS when trying to use export * syntax

Is it possible to use export * from './X' with absolute import paths and eslint in react/typescript? I wanted to have single index.ts file in components folder that would export everything else but eslint gives me weird error when i'm trying to do this.

My current structure looks like this:

src/components/Example1/Example1.tsx

import React from 'react';

export type Props = {};
export const Example1 = (props: Props) => <div></div>

src/components/Example1/index.ts

export * from './Example1';

src/components/index.ts

export * from './Example1';

Both index files gives me error: 0:0 error Parsing error: Cannot read property 'name' of undefined

Also when i try to import anything from the components/index file using an absolute path import { Example1 } from 'components'; i have an error:

1:43  error  Parse errors in imported module 'components': Cannot read property 'name' of undefined (undefined:undefined)  import/namespace
1:43  error  Parse errors in imported module 'components': Cannot read property 'name' of undefined (undefined:undefined)  import/named

This is my .eslintrc.json file

  {
  "env": {
    "browser": true,
    "es6": true,
    "node": true
  },
  "root": true,
  "extends": [
    "eslint:recommended",
    "plugin:react/recommended",
    "plugin:@typescript-eslint/eslint-recommended",
    "plugin:import/warnings",
    "plugin:import/errors",
    "plugin:import/typescript",
    "prettier/@typescript-eslint",
    "prettier",
    "prettier/react"
  ],
  "plugins": [
    "react",
    "react-hooks",
    "jsx-a11y",
    "@typescript-eslint",
    "prettier"
  ],
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "ecmaFeatures": {
      "jsx": true
    },
    "ecmaVersion": 2018,
    "sourceType": "module"
  },
  "settings": {
    "react": {
      "version": "detect"
    },
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"],
        "moduleDirectory": ["node_modules", "src/"]
      }
    }
  },
  "rules": {
    "prettier/prettier": "error",
    "import/newline-after-import": "error",
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": [
      "warn",
      { "args": "after-used", "argsIgnorePattern": "^_" }
    ]
  }
}

This is my tsconfig.json:

{
  "compilerOptions": {
    "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",
    "baseUrl": "./src"
  },
  "include": ["src"]
}

My current package.json:

{
  "name": "frontend",
  "version": "0.0.0",
  "license": "MIT",
  "private": true,
  "dependencies": {
    "@apollo/react-hooks": "^3.1.3",
    "@material-ui/core": "^4.9.5",
    "@material-ui/icons": "^4.9.1",
    "@material-ui/styles": "^4.9.0",
    "@testing-library/jest-dom": "^4.2.4",
    "@testing-library/react": "^9.3.2",
    "@testing-library/user-event": "^7.1.2",
    "@types/jest": "^24.0.0",
    "@types/material-ui": "^0.21.7",
    "@types/node": "^12.0.0",
    "@types/react": "^16.9.0",
    "@types/react-dom": "^16.9.0",
    "@types/react-router-dom": "^5.1.3",
    "@types/styled-components": "^5.0.1",
    "@types/yup": "^0.26.32",
    "apollo-boost": "^0.4.7",
    "env-cmd": "^10.1.0",
    "formik": "^2.1.4",
    "graphql": "^14.6.0",
    "i18next": "^19.3.3",
    "i18next-browser-languagedetector": "^4.0.2",
    "react": "^16.13.0",
    "react-dom": "^16.13.0",
    "react-i18next": "^11.3.3",
    "react-router-dom": "^5.1.2",
    "react-scripts": "3.4.0",
    "styled-components": "^5.0.1",
    "typescript": "~3.7.2",
    "yup": "^0.28.3"
  },
  "devDependencies": {
    "@typescript-eslint/eslint-plugin": "^2.23.0",
    "@typescript-eslint/parser": "^2.23.0",
    "eslint": "^6.8.0",
    "eslint-config-prettier": "^6.10.0",
    "eslint-plugin-import": "^2.20.1",
    "eslint-plugin-jsx-a11y": "^6.2.3",
    "eslint-plugin-prettier": "^3.1.2",
    "prettier": "^1.19.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "build:staging": "env-cmd -f .env.staging yarn build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "lint": "tsc --noEmit && eslint . --ext .js,.tsx,.ts --max-warnings=0",
    "lint:fix": "eslint . --ext .js,.tsx,.ts --fix",
    "watch": "react-scripts start",
    "deploy": "yarn build && firebase deploy",
    "deploy:staging": "yarn build:staging && firebase use staging && firebase deploy"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

I'm also using lerna with yarn workspaces to easily handle MERN app.

Deleting eslint package / configs, node_modules did not help me, i still have Cannot read property 'name' of undefined error. It is super weird because in clean CRA everything works. I spent last 4 hours trying to solve this problem and finally used a workaround with importing types to root index file and reexporing them as new type but it's definately a painful solution. I need to keep isolatedModules. Maybe someone had similar problem?

like image 491
Dooomel Avatar asked Mar 17 '20 07:03

Dooomel


1 Answers

The problem was @typescript-eslint package, check out the issue for more info: https://github.com/typescript-eslint/typescript-eslint/issues/1746

Fast fix for this is to downgrade packages to version 2.22.0:

@typescript-eslint/eslint-plugin

@typescript-eslint/parser

@Edit This helped with lint error but my CRA build is still crashing, I guess i will have to wait for package fix

like image 191
Dooomel Avatar answered Nov 05 '22 11:11

Dooomel