From e92334692574d91705f3d93d0b77263819799890 Mon Sep 17 00:00:00 2001 From: Judah Meek Date: Wed, 29 Jan 2025 18:43:46 -0600 Subject: [PATCH 1/3] add main property back to package.json to reenable eslint support --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 166616196..6138e4dcb 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,7 @@ "name": "react-on-rails", "version": "14.1.1", "description": "react-on-rails JavaScript for react_on_rails Ruby gem", + "main": "node_package/lib/ReactOnRails.js", "exports": { ".": { "node": "./node_package/lib/ReactOnRails.node.js", From 782048c1e8046979896fc80a04a047250a1f18ed Mon Sep 17 00:00:00 2001 From: Judah Meek Date: Wed, 29 Jan 2025 18:43:51 -0600 Subject: [PATCH 2/3] lint spec/dummy --- .eslintignore | 10 +++++++--- .eslintrc | 8 ++++++-- package.json | 4 ++-- spec/dummy/babel.config.js | 5 +++-- spec/dummy/client/.eslintignore | 1 - spec/dummy/client/.eslintrc | 12 ------------ spec/dummy/client/app/components/RouterLayout.jsx | 7 +------ spec/dummy/client/app/packs/rescript-components.js | 2 +- spec/dummy/client/app/packs/server-bundle.js | 4 ++-- .../app/startup/ContextFunctionReturnInvalidJSX.jsx | 9 ++++++++- spec/dummy/client/app/startup/HelloTurboStream.jsx | 2 +- spec/dummy/client/app/startup/HelloWorldHooks.jsx | 7 +++++++ .../client/app/startup/HelloWorldHooksContext.jsx | 13 +++++++++++-- spec/dummy/client/app/startup/HelloWorldProps.jsx | 12 ++++++++++-- spec/dummy/client/app/startup/ImageExample.jsx | 10 ++++++---- spec/dummy/client/app/startup/RouterApp.server.jsx | 12 +++++------- spec/dummy/config/webpack/commonWebpackConfig.js | 4 ++-- spec/dummy/config/webpack/serverWebpackConfig.js | 10 +++++----- spec/dummy/config/webpack/webpack.config.js | 4 ++-- yarn.lock | 5 +++++ 20 files changed, 84 insertions(+), 57 deletions(-) delete mode 100644 spec/dummy/client/.eslintignore delete mode 100644 spec/dummy/client/.eslintrc diff --git a/.eslintignore b/.eslintignore index a99bd88c6..20efa3e5f 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,10 +1,14 @@ node_modules coverage spec/react_on_rails/dummy-for-generators -spec/dummy +spec/dummy/.yalc +spec/dummy/public +spec/dummy/vendor +spec/dummy/tmp +spec/dummy/app/assets/config/manifest.js +spec/dummy/client/node_modules +spec/dummy/client/app/components/HelloWorldReScript.res.js node_package/lib/ -node_package/tests/node_modules -node_package/webpack.config.js **/node_modules/** **/assets/webpack/** **/public/webpack/** diff --git a/.eslintrc b/.eslintrc index 1d1df612b..cf2ae3191 100644 --- a/.eslintrc +++ b/.eslintrc @@ -41,14 +41,18 @@ rules: object-curly-newline: 0 no-restricted-syntax: ["error", "SequenceExpression"] # https://stackoverflow.com/a/59268871/5241481 - import/extensions: ['error', 'ignorePackages', {"js": 'never',"ts": "never"}] + import/extensions: ['error', 'ignorePackages', {"js": 'never', "jsx": 'never', "ts": "never", " ": "never"}] # https://github.com/benmosher/eslint-plugin-import/issues/340 import/no-extraneous-dependencies: 0 + react/forbid-prop-types: 0 + jsx-a11y/anchor-is-valid: 0 + settings: import/core-modules: - react-redux import/resolver: + alias: [ ["Assets", "./spec/dummy/client/app/assets"] ] node: - extensions: [".js", ".ts", ".d.ts"] + extensions: [".js", ".jsx", ".ts", ".d.ts"] diff --git a/package.json b/package.json index 6138e4dcb..b2156ebaf 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "eslint": "^7.32.0", "eslint-config-prettier": "^7.0.0", "eslint-config-shakacode": "^16.0.1", + "eslint-import-resolver-alias": "^1.1.2", "eslint-plugin-import": "^2.29.1", "eslint-plugin-jsx-a11y": "^6.8.0", "eslint-plugin-prettier": "^3.4.1", @@ -43,8 +44,7 @@ "ts-jest": "^29.2.5", "typescript": "^5.6.2" }, - "dependencies": { - }, + "dependencies": {}, "peerDependencies": { "react": ">= 16", "react-dom": ">= 16" diff --git a/spec/dummy/babel.config.js b/spec/dummy/babel.config.js index 40e049a1e..6aa1d24be 100644 --- a/spec/dummy/babel.config.js +++ b/spec/dummy/babel.config.js @@ -1,5 +1,6 @@ -module.exports = function (api) { - const defaultConfigFunc = require('shakapacker/package/babel/preset.js'); +const defaultConfigFunc = require('shakapacker/package/babel/preset'); + +module.exports = function createBabelConfig(api) { const resultConfig = defaultConfigFunc(api); const isProductionEnv = api.env('production'); const isDevelopmentEnv = api.env('development'); diff --git a/spec/dummy/client/.eslintignore b/spec/dummy/client/.eslintignore deleted file mode 100644 index 3c3629e64..000000000 --- a/spec/dummy/client/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/spec/dummy/client/.eslintrc b/spec/dummy/client/.eslintrc deleted file mode 100644 index 8ff607255..000000000 --- a/spec/dummy/client/.eslintrc +++ /dev/null @@ -1,12 +0,0 @@ ---- - -extends: - - eslint-config-shakacode - - prettier - - prettier/react - -plugins: - - prettier - -rules: - react/forbid-prop-types: 0 diff --git a/spec/dummy/client/app/components/RouterLayout.jsx b/spec/dummy/client/app/components/RouterLayout.jsx index d72e58bc9..13c3a122a 100644 --- a/spec/dummy/client/app/components/RouterLayout.jsx +++ b/spec/dummy/client/app/components/RouterLayout.jsx @@ -1,10 +1,9 @@ -import PropTypes from 'prop-types'; import React from 'react'; import { Link, Route, Switch } from 'react-router-dom'; import RouterFirstPage from './RouterFirstPage'; import RouterSecondPage from './RouterSecondPage'; -const RouterLayout = ({ children }) => ( +const RouterLayout = () => (

React Router is working!

@@ -29,8 +28,4 @@ const RouterLayout = ({ children }) => (

); -RouterLayout.propTypes = { - children: PropTypes.object, -}; - export default RouterLayout; diff --git a/spec/dummy/client/app/packs/rescript-components.js b/spec/dummy/client/app/packs/rescript-components.js index ae0384cb4..c1b243230 100644 --- a/spec/dummy/client/app/packs/rescript-components.js +++ b/spec/dummy/client/app/packs/rescript-components.js @@ -4,4 +4,4 @@ import HelloWorldReScript from '../components/HelloWorldReScript.res.js'; -export { HelloWorldReScript }; +export default HelloWorldReScript; diff --git a/spec/dummy/client/app/packs/server-bundle.js b/spec/dummy/client/app/packs/server-bundle.js index 517fe677e..f21eb77ec 100644 --- a/spec/dummy/client/app/packs/server-bundle.js +++ b/spec/dummy/client/app/packs/server-bundle.js @@ -1,7 +1,7 @@ -// import statement added by react_on_rails:generate_packs rake task -import './../generated/server-bundle-generated.js'; // Shows the mapping from the exported object to the name used by the server rendering. import ReactOnRails from 'react-on-rails'; +// import statement added by react_on_rails:generate_packs rake task +import './../generated/server-bundle-generated'; // Example of server rendering with no React import HelloString from '../non_react/HelloString'; diff --git a/spec/dummy/client/app/startup/ContextFunctionReturnInvalidJSX.jsx b/spec/dummy/client/app/startup/ContextFunctionReturnInvalidJSX.jsx index 444082420..decd79449 100644 --- a/spec/dummy/client/app/startup/ContextFunctionReturnInvalidJSX.jsx +++ b/spec/dummy/client/app/startup/ContextFunctionReturnInvalidJSX.jsx @@ -1,5 +1,6 @@ // Example of incorrectly taking two params and returning JSX -import React, { useState } from 'react'; +import React from 'react'; +import PropTypes from 'prop-types'; import css from '../components/HelloWorld.module.scss'; import RailsContext from '../components/RailsContext'; @@ -11,6 +12,12 @@ const ContextFunctionReturnInvalidJSX = (props, railsContext) => ( ); +ContextFunctionReturnInvalidJSX.propTypes = { + helloWorldData: PropTypes.shape({ + name: PropTypes.string, + }).isRequired, +} + /* Wrapping in a function would be correct in this case, since two params are passed to the registered function: diff --git a/spec/dummy/client/app/startup/HelloTurboStream.jsx b/spec/dummy/client/app/startup/HelloTurboStream.jsx index 5125044f8..ca32d2c18 100644 --- a/spec/dummy/client/app/startup/HelloTurboStream.jsx +++ b/spec/dummy/client/app/startup/HelloTurboStream.jsx @@ -7,7 +7,7 @@ import css from '../components/HelloWorld.module.scss'; const HelloTurboStream = ({ helloTurboStreamData, railsContext }) => { const [name, setName] = useState(helloTurboStreamData.name); const nameDomRef = useRef(null); - + // eslint-disable-next-line no-unused-vars const handleChange = () => { setName(nameDomRef.current.value); }; diff --git a/spec/dummy/client/app/startup/HelloWorldHooks.jsx b/spec/dummy/client/app/startup/HelloWorldHooks.jsx index 23a7414ac..da2aebbe6 100644 --- a/spec/dummy/client/app/startup/HelloWorldHooks.jsx +++ b/spec/dummy/client/app/startup/HelloWorldHooks.jsx @@ -1,5 +1,6 @@ // Super simple example of the simplest possible React component import React, { useState } from 'react'; +import PropTypes from 'prop-types'; import css from '../components/HelloWorld.module.scss'; // TODO: make more like the HelloWorld.jsx @@ -16,4 +17,10 @@ function HelloWorldHooks(props) { ); } +HelloWorldHooks.propTypes = { + helloWorldData: PropTypes.shape({ + name: PropTypes.string, + }).isRequired, +} + export default HelloWorldHooks; diff --git a/spec/dummy/client/app/startup/HelloWorldHooksContext.jsx b/spec/dummy/client/app/startup/HelloWorldHooksContext.jsx index 332c8a7cc..3fcb9f52b 100644 --- a/spec/dummy/client/app/startup/HelloWorldHooksContext.jsx +++ b/spec/dummy/client/app/startup/HelloWorldHooksContext.jsx @@ -1,12 +1,13 @@ // Example of using hooks when taking the props and railsContext // Note, you need the call the hooks API within the react component stateless function import React, { useState } from 'react'; +import PropTypes from 'prop-types'; import css from '../components/HelloWorld.module.scss'; import RailsContext from '../components/RailsContext'; -const HelloWorldHooksContext = (props, railsContext) => { // You could pass props here or use the closure - return () => { +const HelloWorldHooksContext = (props, railsContext) => { + const Result = () => { const [name, setName] = useState(props.helloWorldData.name); return ( <> @@ -20,6 +21,14 @@ const HelloWorldHooksContext = (props, railsContext) => { ); }; + + Result.propTypes = { + helloWorldData: PropTypes.shape({ + name: PropTypes.string, + }).isRequired, + }; + + return Result; }; export default HelloWorldHooksContext; diff --git a/spec/dummy/client/app/startup/HelloWorldProps.jsx b/spec/dummy/client/app/startup/HelloWorldProps.jsx index ef126eb64..a776f9732 100644 --- a/spec/dummy/client/app/startup/HelloWorldProps.jsx +++ b/spec/dummy/client/app/startup/HelloWorldProps.jsx @@ -1,7 +1,8 @@ import React, { useState, useEffect } from 'react'; +import PropTypes from 'prop-types'; import css from '../components/HelloWorld.module.scss'; -function HelloWorldHooks(props) { +function HelloWorldProps(props) { console.log(`HelloWorldProps modification target prop value: ${props.modificationTarget}`); const [name, setName] = useState(props.helloWorldData.name); @@ -24,4 +25,11 @@ function HelloWorldHooks(props) { ); } -export default HelloWorldHooks; +HelloWorldProps.propTypes = { + helloWorldData: PropTypes.shape({ + name: PropTypes.string, + }).isRequired, + modificationTarget: PropTypes.string.isRequired, +} + +export default HelloWorldProps; diff --git a/spec/dummy/client/app/startup/ImageExample.jsx b/spec/dummy/client/app/startup/ImageExample.jsx index 2f6c1b9e3..72264a5f4 100644 --- a/spec/dummy/client/app/startup/ImageExample.jsx +++ b/spec/dummy/client/app/startup/ImageExample.jsx @@ -1,13 +1,15 @@ import React from 'react'; -import css from '../components/ImageExample/ImageExample.module.scss'; // Note the global alias for images -import bowerLogo from '../components/ImageExample/bower.png'; -import blueprintIcon from '../components/ImageExample/blueprint_icon.svg'; import logo from 'Assets/images/256egghead.png'; import legoIcon from 'Assets/images/lego_icon.svg'; -const TestComponent = (_props) => ( +import css from '../components/ImageExample/ImageExample.module.scss'; + +import bowerLogo from '../components/ImageExample/bower.png'; +import blueprintIcon from '../components/ImageExample/blueprint_icon.svg'; + +const TestComponent = () => (

This is a test of CSS module color red.


diff --git a/spec/dummy/client/app/startup/RouterApp.server.jsx b/spec/dummy/client/app/startup/RouterApp.server.jsx index 1d832e1b3..2995b42c2 100644 --- a/spec/dummy/client/app/startup/RouterApp.server.jsx +++ b/spec/dummy/client/app/startup/RouterApp.server.jsx @@ -3,10 +3,8 @@ import { StaticRouter } from 'react-router-dom'; import routes from '../routes/routes'; -export default (props, railsContext) => { - return () => ( - - {routes} - - ); -}; +export default (props, railsContext) => () => ( + + {routes} + +); diff --git a/spec/dummy/config/webpack/commonWebpackConfig.js b/spec/dummy/config/webpack/commonWebpackConfig.js index 02a1ec0af..ba523a96b 100644 --- a/spec/dummy/config/webpack/commonWebpackConfig.js +++ b/spec/dummy/config/webpack/commonWebpackConfig.js @@ -5,7 +5,7 @@ const baseClientWebpackConfig = generateWebpackConfig(); const webpack = require('webpack'); -const aliasConfig = require('./alias.js'); +const aliasConfig = require('./alias'); const commonOptions = { resolve: { @@ -23,7 +23,7 @@ const sassLoaderConfig = { const scssConfigIndex = baseClientWebpackConfig.module.rules.findIndex((config) => '.scss'.match(config.test), -); +); // eslint-disable-next-line no-undef baseClientWebpackConfig.module.rules[scssConfigIndex]?.use.push(sassLoaderConfig); // add jquery diff --git a/spec/dummy/config/webpack/serverWebpackConfig.js b/spec/dummy/config/webpack/serverWebpackConfig.js index b64a616a6..aca7bf7a9 100644 --- a/spec/dummy/config/webpack/serverWebpackConfig.js +++ b/spec/dummy/config/webpack/serverWebpackConfig.js @@ -1,4 +1,4 @@ -const { merge, config } = require('shakapacker'); +const { config } = require('shakapacker'); const commonWebpackConfig = require('./commonWebpackConfig'); const webpack = require('webpack'); @@ -28,7 +28,7 @@ const configureServer = () => { // replace file-loader with null-loader serverWebpackConfig.module.rules.forEach((loader) => { if (loader.use && loader.use.filter) { - loader.use = loader.use.filter( + loader.use = loader.use.filter( // eslint-disable-line no-param-reassign (item) => !(typeof item === 'string' && item.match(/mini-css-extract-plugin/)), ); } @@ -65,11 +65,11 @@ const configureServer = () => { // Remove the mini-css-extract-plugin from the style loaders because // the client build will handle exporting CSS. // replace file-loader with null-loader - const rules = serverWebpackConfig.module.rules; + const { rules } = serverWebpackConfig.module; rules.forEach((rule) => { if (Array.isArray(rule.use)) { // remove the mini-css-extract-plugin and style-loader - rule.use = rule.use.filter((item) => { + rule.use = rule.use.filter((item) => { // eslint-disable-line no-param-reassign let testValue; if (typeof item === 'string') { testValue = item; @@ -95,7 +95,7 @@ const configureServer = () => { // Skip writing image files during SSR by setting emitFile to false } else if (rule.use && (rule.use.loader === 'url-loader' || rule.use.loader === 'file-loader')) { - rule.use.options.emitFile = false; + rule.use.options.emitFile = false; // eslint-disable-line no-param-reassign } }); diff --git a/spec/dummy/config/webpack/webpack.config.js b/spec/dummy/config/webpack/webpack.config.js index 34ff0b4d6..d2a3fd8f9 100644 --- a/spec/dummy/config/webpack/webpack.config.js +++ b/spec/dummy/config/webpack/webpack.config.js @@ -7,10 +7,10 @@ const envSpecificConfig = () => { const path = resolve(__dirname, `${env.nodeEnv}.js`); if (existsSync(path)) { console.log(`Loading ENV specific webpack configuration file ${path}`); + // eslint-disable-next-line import/no-dynamic-require, global-require return require(path); - } else { - return generateWebpackConfig(); } + return generateWebpackConfig(); }; module.exports = envSpecificConfig(); diff --git a/yarn.lock b/yarn.lock index bb59419ba..1ddef02c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2992,6 +2992,11 @@ eslint-config-shakacode@^16.0.1: babel-eslint "8.2.2" eslint-config-airbnb "16.1.0" +eslint-import-resolver-alias@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-alias/-/eslint-import-resolver-alias-1.1.2.tgz#297062890e31e4d6651eb5eba9534e1f6e68fc97" + integrity sha512-WdviM1Eu834zsfjHtcGHtGfcu+F30Od3V7I9Fi57uhBEwPkjDcii7/yW8jAT+gOhn4P/vOxxNAXbFAKsrrc15w== + eslint-import-resolver-node@^0.3.9: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" From 07e16654fadd7cb24e7fa7f775d9212384702fb2 Mon Sep 17 00:00:00 2001 From: Judah Meek Date: Wed, 29 Jan 2025 18:47:36 -0600 Subject: [PATCH 3/3] add changelog entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d455aa93..f49274f4a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,10 @@ Please follow the recommendations outlined at [keepachangelog.com](http://keepac ### [Unreleased] Changes since the last non-beta release. +#### Fixed + +- Resolved 14.1.1 incompatibility with eslint & made sure that spec/dummy is linted by eslint. [PR 1693](https://github.com/shakacode/react_on_rails/pull/1693) by [judahmeek](https://github.com/judahmeek). + ### [14.1.1] - 2025-01-15 #### Fixed