Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Eslint migration #16

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"trailingComma": "all",
"trailingComma": "none",
"semi": false,
"singleQuote": true
}
42 changes: 42 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";
import pluginReact from "eslint-plugin-react";

export default [
{ files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"] },
{
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: globals.browser
}
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
pluginReact.configs.flat.recommended,
pluginReact.configs.flat['jsx-runtime'],
{ ignores: ["build/**", "node_modules/**"] },
{
rules: {
'react/jsx-uses-react': 'error',
'react/jsx-uses-vars': 'error'
}
},
{
settings: {
react: {
pragma: 'React',
fragment: 'Fragment',
version: 'detect',
flowVersion: '0.53'
},
propWrapperFunctions: [],
componentWrapperFunctions: [],
formComponents: [],
linkComponents: [
{ name: 'Link', linkAttribute: 'to' }
]
}
}
];
80 changes: 40 additions & 40 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,59 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@google-analytics/data": "^4.9.0",
"bootstrap": "5.3.3",
"classnames": "^2.3.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-ga": "^3.3.1",
"react-helmet-async": "^2.0.3",
"react-router-dom": "^6.14.0",
"reactstrap": "^9.2.0",
"styled-components": "^6.0.1",
"web-vitals": "^3.3.2",
"workbox-background-sync": "^7.0.0",
"workbox-broadcast-update": "^7.0.0",
"workbox-cacheable-response": "^7.0.0",
"workbox-core": "^7.0.0",
"workbox-expiration": "^7.0.0",
"workbox-google-analytics": "^7.0.0",
"workbox-navigation-preload": "^7.0.0",
"workbox-precaching": "^7.0.0",
"workbox-range-requests": "^7.0.0",
"workbox-routing": "^7.0.0",
"workbox-strategies": "^7.0.0",
"workbox-streams": "^7.0.0"
"classnames": "^2.5.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-ga4": "^2.1.0",
"react-helmet-async": "^2.0.5",
"react-router-dom": "^6.27.0",
"reactstrap": "^9.2.3",
"styled-components": "^6.1.13",
"web-vitals": "^4.2.3",
"workbox-background-sync": "^7.1.0",
"workbox-broadcast-update": "^7.1.0",
"workbox-cacheable-response": "^7.1.0",
"workbox-core": "^7.1.0",
"workbox-expiration": "^7.1.0",
"workbox-navigation-preload": "^7.1.0",
"workbox-precaching": "^7.1.0",
"workbox-range-requests": "^7.1.0",
"workbox-routing": "^7.1.0",
"workbox-strategies": "^7.1.0",
"workbox-streams": "^7.1.0"
},
"devDependencies": {
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
"@testing-library/jest-dom": "^6.1.2",
"@testing-library/react": "^15.0.5",
"@testing-library/user-event": "^14.4.3",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/react": "^18.2.14",
"@types/react-dom": "^18.2.6",
"@types/styled-components": "^5.1.26",
"prettier": "^3.0.3",
"tslint": "^6.1.3",
"tslint-config-prettier": "^1.18.0",
"tslint-config-standard": "^9.0.0",
"tslint-react": "^5.0.0",
"typescript": "^5.1.3",
"react-scripts": "5.0.1"
"@testing-library/jest-dom": "^6.6.2",
"@testing-library/react": "^16.0.1",
"@testing-library/user-event": "^14.5.2",
"@types/jest": "^29.5.13",
"@types/node": "^22.7.7",
"@types/react": "^18.3.11",
"@types/react-dom": "^18.3.1",
"@types/styled-components": "^5.1.34",
"prettier": "^3.3.3",
"react-scripts": "5.0.1",
"typescript": "^5.6.3",
"@eslint/js": "^9.13.0",
"eslint": "^9.13.0",
"eslint-plugin-react": "^7.37.1",
"globals": "^15.11.0",
"typescript-eslint": "^8.10.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"deploy-local": "npm run build && npx serve -s build",
"lint": "tslint src/**/*.{ts,tsx}",
"lint-fix": "tslint src/**/*.{ts,tsx} --fix",
"lint": "npx eslint",
"lint-fix": "npx eslint --fix",
"prettier": "./node_modules/.bin/prettier -l src/**/*.{ts,tsx}"
},
"overrides": {
"typescript": "$typescript",
"typescript": "^5.6.3",
"@svgr/webpack": "^8.0.1",
"semver": "^7.5.3"
},
Expand Down
2 changes: 1 addition & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import NotFound from './pages/NotFound'
// const Content = lazy(() => import('./pages/Content'))
// const NotFound = lazy(() => import('./pages/NotFound'))

const App = () => (
const App = (): JSX.Element => (
<BrowserRouter>
{/* <Suspense fallback={<div />}> */}
<Routes>
Expand Down
8 changes: 6 additions & 2 deletions src/components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ import Labels from '../constants/Labels'
import RouterNavBrand from './RouterNavBrand'
import RouterNavLink from './RouterNavLink'

const NavBar = () => {
const NavBar = (): JSX.Element => {
const [isOpen, setOpen] = useState(false)

return (
<Navbar fixed="top" color="dark" expand="md" dark>
<RouterNavBrand to="/">{Labels.MAIN_PAGE_BRAND}</RouterNavBrand>
<NavbarToggler onClick={() => setOpen(!isOpen)} />
<NavbarToggler
onClick={() => {
setOpen(!isOpen)
}}
/>
<Collapse isOpen={isOpen} navbar>
<Nav className="mr-auto" navbar>
<NavItem>
Expand Down
6 changes: 3 additions & 3 deletions src/components/PageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ interface IPageContentProps {
children?: React.ReactNode | JSX.Element
}

const PageContent = (props: IPageContentProps) => {
const PageContent = (props: IPageContentProps): JSX.Element => {
const { pageTitle, pageDescription, children, withMargin } = props

const Body = withMargin ? PageContentContainer : 'div'
const Body = withMargin ?? false ? PageContentContainer : 'div'

return (
<HelmetProvider>
<Helmet>
<title>{`${pageTitle} | ${Labels.MAIN_PAGE_BRAND}`}</title>
{pageDescription && (
{pageDescription != null && (
<meta name="description" content={pageDescription} />
)}
</Helmet>
Expand Down
7 changes: 3 additions & 4 deletions src/components/RouterNavBrand.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Link, LinkProps } from 'react-router-dom'
import { Link, type LinkProps } from 'react-router-dom'

type RouterNavBrandProps = React.PropsWithoutRef<LinkProps> &
React.RefAttributes<HTMLAnchorElement>
type RouterNavBrandProps = React.PropsWithoutRef<LinkProps> & React.RefAttributes<HTMLAnchorElement>

const RouterNavBrand = (props: RouterNavBrandProps) => (
const RouterNavBrand = (props: RouterNavBrandProps): JSX.Element => (
<Link {...props} className="navbar-brand" />
)

Expand Down
6 changes: 3 additions & 3 deletions src/components/RouterNavLink.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { NavLink, NavLinkProps } from 'react-router-dom'
import { NavLink, type NavLinkProps } from 'react-router-dom'

type RouterNavLinkProps = React.PropsWithoutRef<NavLinkProps> &
React.RefAttributes<HTMLAnchorElement>
React.RefAttributes<HTMLAnchorElement>

const RouterNavLink = (props: RouterNavLinkProps) => (
const RouterNavLink = (props: RouterNavLinkProps): JSX.Element => (
<NavLink className="nav-link" {...props} />
)

Expand Down
2 changes: 1 addition & 1 deletion src/components/Viewport.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ interface IViewportProps {
children?: React.ReactNode | JSX.Element
}

const Viewport = ({ children }: IViewportProps) => (
const Viewport = ({ children }: IViewportProps): JSX.Element => (
<NavbarContainer>
<NavBar />
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/constants/Labels.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const Labels = {
MAIN_PAGE_BRAND: 'Practice PWA',
MAIN_PAGE_BRAND: 'Practice PWA'
}

export default Labels
20 changes: 12 additions & 8 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { type Root, createRoot } from 'react-dom/client'
import App from './App'
import * as serviceWorkerRegistration from './serviceWorkerRegistration'
import reportWebVitals from './reportWebVitals'
import 'bootstrap/dist/css/bootstrap.min.css'
// import GoogleAnalytics from './webvitals/GoogleAnalytics'

const container = document.getElementById('root')
const root = createRoot(container!)
root.render(
<StrictMode>
<App />
</StrictMode>,
)

let root: Root

if (container != null) {
root = createRoot(container)
root.render(
<StrictMode>
<App />
</StrictMode>
)
}

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
Expand All @@ -28,7 +33,6 @@ serviceWorkerRegistration.unregister()
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// tslint:disable-next-line:no-console
reportWebVitals(console.log)

// reportWebVitals(GoogleAnalytics.performance('UA-XXXXXX-YY', 'Web Vitals', true))
9 changes: 9 additions & 0 deletions src/interfaces/IWebVitalsGaInitOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { GaOptions } from 'react-ga4/types/ga4'

export default interface IWebVitalsGaInitOptions {
nonce?: string
testMode?: boolean
gtagUrl?: string
gaOptions?: GaOptions | any
gtagOptions?: any
}
2 changes: 1 addition & 1 deletion src/pages/About.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PageContent from '../components/PageContent'

const About = () => (
const About = (): JSX.Element => (
<PageContent pageTitle="About">
<h1>About</h1>
</PageContent>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PageContent from '../components/PageContent'

const Content = () => (
const Content = (): JSX.Element => (
<PageContent pageTitle="Content">
<h1>Content</h1>
</PageContent>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PageContent from '../components/PageContent'

const Home = () => (
const Home = (): JSX.Element => (
<PageContent pageTitle="Home">
<h1>Hello world</h1>
</PageContent>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Outlet, useLocation } from 'react-router-dom'
import Viewport from '../components/Viewport'
import Home from './Home'

const Main = () => {
const Main = (): JSX.Element => {
const location = useLocation()
const currentPath = location.pathname

Expand Down
2 changes: 1 addition & 1 deletion src/pages/NotFound.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import PageContent from '../components/PageContent'

const NotFound = () => (
const NotFound = (): JSX.Element => (
<PageContent pageTitle="Sorry! Page not found">
<h1>404</h1>
</PageContent>
Expand Down
20 changes: 10 additions & 10 deletions src/reportWebVitals.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ReportHandler } from 'web-vitals'
import { Metric } from 'web-vitals'

const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
// tslint:disable-next-line: no-floating-promises
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry)
getFID(onPerfEntry)
getFCP(onPerfEntry)
getLCP(onPerfEntry)
getTTFB(onPerfEntry)
type ReportHandler = (metric: Metric) => void

const reportWebVitals = async (onPerfEntry?: ReportHandler): Promise<void> => {
if (onPerfEntry != null) {
void import('web-vitals').then(({ onCLS, onFCP, onLCP, onTTFB }) => {
onCLS(onPerfEntry)
onFCP(onPerfEntry)
onLCP(onPerfEntry)
onTTFB(onPerfEntry)
})
}
}
Expand Down
Loading