Eslint and Babel parser throwing errors in React

675 views Asked by At

Having some strange behaviour when trying to configure ESlint(global install) and babel:

Editor(VSCode) showing error on top most import:

Resolve error: TypeError: Cannot read properties of undefined (reading 'ENV') at module.exports (.....\client\webpack.config.js:29:44) at Object.exports.resolve (.....\client\node_modules\eslint-import-resolver-webpack\index.js:107:21)

while running npm run lint on the whole project throws:

.......\client\webpack.config.js 0:0 error Parsing error: No Babel config file detected for .......\client\webpack.config.js. Either disable config file checking with requireConfigFile: false, or configure Babel so that it can find the config files

for every file it's trying to parse.

eslintrc.json

{
    "globals": {
        "graphql": true,
        "theme": true,
        "classes": true
    },
    "env": {
        "browser": true,
        "es6": true,
        "node": true
    },
    "extends": [
        "eslint:recommended",
        "plugin:react/recommended",
        "plugin:react-hooks/recommended",
        "plugin:jsx-a11y/recommended",
        "plugin:import/recommended"
    ],
    "parser": "@babel/eslint-parser",
    "parserOptions": {
        "ecmaFeatures": {
            "jsx": true,
            "globalReturn": false
        },
        "ecmaVersion": "latest",
        "sourceType": "module",
        "babelOptions": {
            "root": "./client/"
        }
    },
    "plugins": [
        "react",
        "unused-imports",
        "@babel",
        "react-hooks",
        "jsx-a11y",
        "import"
    ],
    "rules": {
        "indent": [
            "error",
            4
        ],
        "linebreak-style": [
            "error",
            "windows"
        ],
        "quotes": [
            "error",
            "single"
        ],
        "semi": [
            "error",
            "never"
        ],
        "react/jsx-uses-react": "error",
        "react/jsx-uses-vars": "error",
        "react/jsx-pascal-case": [
            2,
            {
                "allowAllCaps": true
            }
        ],
        "jsx-quotes": [
            "error",
            "prefer-single"
        ],
        "react/jsx-closing-bracket-location": [
            1,
            "tag-aligned"
        ],
        "react/jsx-closing-tag-location": 1,
        "no-multi-spaces": [
            "error",
            {
                "ignoreEOLComments": true
            }
        ],
        "react/jsx-tag-spacing": 2,
        "react/jsx-boolean-value": [
            2,
            "never"
        ],
        "react/self-closing-comp": [
            "error",
            {
                "component": true,
                "html": true
            }
        ],
        "react/prop-types": "off",
        "import/no-unresolved": [
            "error",
            {
                "caseSensitive": false
            }
        ],
        "no-unused-vars": ["error", { "vars": "local", "args": "after-used" }], // or "@typescript-eslint/no-unused-vars": "off",
        "unused-imports/no-unused-imports": "off",
        "unused-imports/no-unused-vars": [
            "warn",
            {
                "vars": "all",
                "varsIgnorePattern": "^_",
                "args": "after-used",
                "argsIgnorePattern": "^_"
            }
        ],
        "react/no-unknown-property": [
            "error",
            {
                "ignore": [
                    "css"
                ]
            }
        ],
        "import/order": ["error", {
            "newlines-between": "always",
            "groups": ["builtin", "external", "internal", ["sibling", "parent"], "index"],
            "alphabetize": {
                "order": "asc"
            }
        }],
        "import/namespace": "error",
        "import/no-duplicates": "error",
        "import/no-self-import": "error",
        "react-hooks/exhaustive-deps": "error",
        "object-curly-spacing": ["error", "always"],
        "template-curly-spacing": ["error", "always"],
        "react/jsx-curly-spacing": ["error", {"when": "always"}]
    },
    "settings": {
        "react": {
            "createClass": "createReactClass", // Regex for Component Factory to use,
            // default to "createReactClass"
            "pragma": "React", // Pragma to use, default to "React"
            "fragment": "Fragment", // Fragment to use (may be a property of <pragma>), default to "Fragment"
            "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
            "flowVersion": "0.53" // Flow version
        },
        "propWrapperFunctions": [
            // The names of any function used to wrap propTypes, e.g. `forbidExtraProps`. If this isn't set, any propTypes wrapped in a function will be skipped.
            "forbidExtraProps",
            {
                "property": "freeze",
                "object": "Object"
            },
            {
                "property": "myFavoriteWrapper"
            },
            // for rules that check exact prop wrappers
            {
                "property": "forbidExtraProps",
                "exact": true
            }
        ],
        "componentWrapperFunctions": [
            // The name of any function used to wrap components, e.g. Mobx `observer` function. If this isn't set, components wrapped by these functions will be skipped.
            "observer", // `property`
            {
                "property": "styled"
            }, // `object` is optional
            {
                "property": "observer",
                "object": "Mobx"
            },
            {
                "property": "observer",
                "object": "<pragma>"
            } // sets `object` to whatever value `settings.react.pragma` is set to
        ],
        "formComponents": [
            // Components used as alternatives to <form> for forms, eg. <Form endpoint={ url } />
            "CustomForm",
            {
                "name": "Form",
                "formAttribute": "endpoint"
            }
        ],
        "linkComponents": [
            // Components used as alternatives to <a> for linking, eg. <Link to={ url } />
            "Hyperlink",
            {
                "name": "Link",
                "linkAttribute": "to"
            }
        ],
        "import/resolver": {
            "node": {
                "paths": [
                    "client/src",
                    "src"
                ],
                "extensions": [
                    ".js",
                    ".jsx",
                    ".ts",
                    ".tsx"
                ]
            },
            "webpack": {
                "config": "webpack.config.js"
            }
        }
    }
}

babel.config.json

{
  "presets": [
    "@babel/env",
    "@babel/react",
    "@emotion/babel-preset-css-prop"
  ],
  "plugins": [
    "syntax-dynamic-import",
    "react-hot-loader/babel",
    "@babel/plugin-transform-react-jsx-source"
  ]
}

webpack.config.js

const path = require('path')

const CopyWebpackPlugin = require('copy-webpack-plugin')
const dotenv = require('dotenv')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const webpack = require('webpack')

const port = 3000
const host = '0.0.0.0'

module.exports = (env) => {
    const currentPath = path.join(__dirname)
    const envPath = currentPath + `/${ env.ENV }.env`
    const fileEnv = dotenv.config({ path: envPath }).parsed
    const envKeys = Object.keys(fileEnv).reduce((prev, next) => {
        prev[`process.env.${ next }`] = JSON.stringify(fileEnv[next])
        return prev
    }, {})
    const isProd = (env.ENV === 'prod')

    return {
        mode: isProd ? 'production': 'development',
        entry: [
            path.resolve('src', 'index.js')
        ],
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: isProd ? '[name].[chunkhash].js' : '[name].[hash:8].js',
            chunkFilename: isProd ? '[id].[chunkhash].js' : '[id].[hash:8].js',
            sourceMapFilename: isProd ? '[name].[chunkhash].map' : '[name].[hash:8].map',
        },
        module: {
            rules: [
                {
                    test: /\.(jpe?g|png|svg)$/i,
                    type: 'asset',
                },
                {
                    test: /\.(js|jsx)$/,
                    exclude: /node_modules/,
                    use: ['babel-loader']
                },
                {
                    test:/\.css$/,
                    //include: path.resolve(__dirname, 'node_modules'),
                    use: ['style-loader', 'css-loader']
                },
                {
                    test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
                    exclude: /node_modules/,
                    use: [{
                        loader: 'file-loader',
                        options: {
                            name: '[name].[ext]',
                            outputPath: 'content/fonts/'
                        }
                    }]
                }
            ]
        },
        resolve: {
            extensions: ['.js', '.jsx', 'json'],
            modules: [path.join(__dirname, 'src'), 'node_modules'],
            alias: {
                react: path.join(__dirname, 'node_modules', 'react'),
                services: path.join(__dirname, 'src/services/'),
                utils: path.join(__dirname, 'src/utils/'),
                Redux: path.join(__dirname, 'src/redux/'),
                scss: path.join(__dirname, 'src/scss/'),
                hooks: path.join(__dirname, 'src/hooks/'),
                config: path.join(__dirname, 'src/config/'),
                components: path.join(__dirname, 'src/components/'),
                modules: path.join(__dirname, 'src/modules/'),
                locales: path.join(__dirname, 'src/locales/'),
                routes: path.join(__dirname, 'src/routes/')
            },
            preferRelative: true,
            roots: [path.resolve(__dirname), 'content']
        },
        plugins: [
            new CopyWebpackPlugin({
                patterns: [
                    {
                        from:'src/content/images',
                        to: 'content/images',
                        globOptions: {
                            ignore: ['**/index.html']
                        }
                    }
                ],
            }),
            new HtmlWebpackPlugin({
                template: './src/index.html',
                filename: 'index.html',
                inject: 'body',
                //favicon: './content/favicon.ico'
            }),
            new webpack.DefinePlugin(envKeys)
        ],
        devtool: 'eval-cheap-source-map',
        devServer: {
            hot: true,
            host: host,
            port: port,
            historyApiFallback: true,
            headers: { 'Access-Control-Allow-Origin': '*' },
            static: {
                directory: path.resolve(__dirname, 'content'),
                publicPath: '/content'
            }
        }
    }
}

Edit: I fixed the VSCode complaining with adding this to eslintrc's import-resolver rule:

"webpack": {
                "config": "webpack.config.js",
                "env":{
                    "ENV": "dev",
                    "production": false
                }
            }
0

There are 0 answers