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
}
}