Skip to content

Commit

Permalink
[migrate] upgrade to Node.js 22, Next.js 15, ESLint 9 & other latest …
Browse files Browse the repository at this point in the history
…Upstream packages

[optimize] merge GitHub actions of main & other branches
[remove] useless Example pages
  • Loading branch information
TechQuery committed Feb 1, 2025
1 parent 98bd4b6 commit 2797031
Show file tree
Hide file tree
Showing 23 changed files with 2,728 additions and 2,807 deletions.
10 changes: 0 additions & 10 deletions .eslintrc.json

This file was deleted.

4 changes: 2 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI & CD
on:
push:
branches:
- main
- '*'
jobs:
Build-and-Deploy:
env:
Expand All @@ -25,4 +25,4 @@ jobs:
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: ./
vercel-args: --prod
vercel-args: ${{ github.ref == 'refs/heads/main' && ' --prod' || '' }}
27 changes: 0 additions & 27 deletions .github/workflows/pull-request.yml

This file was deleted.

2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM node:20-slim AS base
FROM node:22-slim AS base
RUN apt-get update && \
apt-get install ca-certificates curl libjemalloc-dev -y --no-install-recommends && \
rm -rf /var/lib/apt/lists/*
Expand Down
1 change: 1 addition & 0 deletions components/DrawerNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class DrawerNav extends Component {
break;
}
scrollTop = document.scrollingElement?.scrollTop;
// eslint-disable-next-line no-constant-condition
} while (true);
};

Expand Down
2 changes: 1 addition & 1 deletion components/Git/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export const GitCard: FC<GitCardProps> = observer(
</nav>
<Row as="ul" className="list-unstyled g-4" xs={4}>
{languages.map(language => (
<Col as="li" key={language}>
<Col key={language} as="li">
<GitLogo name={language} />
</Col>
))}
Expand Down
2 changes: 1 addition & 1 deletion components/conference/Guest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export const GuestInfo: FC = () => (
<Row as="ul" className="list-unstyled" xs={2} sm={4}>
{guestData.map(({ pic, name, position }) => (
<PersonCard
avatar={`/image/speaker/${pic}`}
key={name}
avatar={`/image/speaker/${pic}`}
{...{ name, position }}
/>
))}
Expand Down
6 changes: 3 additions & 3 deletions components/conference/Organization.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,14 @@ export const OrganizationInfo: FC = () => (

{Object.values(groupBy(sponsors, 'level')).map(sponsors => (
<Row
key={sponsors[0].level}
as="ul"
className="list-unstyled justify-content-around p-0"
xs={2}
sm={5}
key={sponsors[0].level}
>
{sponsors.map(({ level, href, imgSrc }) => (
<Col as="li" className={styles.sponsor_item} key={imgSrc}>
<Col key={imgSrc} as="li" className={styles.sponsor_item}>
<Badge className="d-inline-block align-middle m-1 w-75" bg="info">
{renderLevel(level)}
</Badge>
Expand Down Expand Up @@ -89,7 +89,7 @@ export const OrganizationInfo: FC = () => (
sm={5}
>
{partners.map(({ href, imgSrc }) => (
<Col as="li" className={styles.partner} key={href}>
<Col key={href} as="li" className={styles.partner}>
<a href={href} target="_blank" rel="noreferrer">
<Image className="object-fit-contain" src={imgSrc} />
</a>
Expand Down
76 changes: 76 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
// @ts-check
import { fixupConfigRules, fixupPluginRules } from '@eslint/compat';
import { FlatCompat } from '@eslint/eslintrc';
import eslint from '@eslint/js';
import eslintConfigPrettier from 'eslint-config-prettier';
import reactPlugin from 'eslint-plugin-react';
import simpleImportSortPlugin from 'eslint-plugin-simple-import-sort';
import globals from 'globals';
import tsEslint from 'typescript-eslint';
import { fileURLToPath } from 'url';

const tsconfigRootDir = fileURLToPath(new URL('.', import.meta.url)),
flatCompat = new FlatCompat();

export default tsEslint.config(
// register all of the plugins up-front
{
plugins: {
'@typescript-eslint': tsEslint.plugin,
react: fixupPluginRules(reactPlugin),
'simple-import-sort': simpleImportSortPlugin,
},
},
{
// config with just ignores is the replacement for `.eslintignore`
ignores: ['**/node_modules/**', '**/public/**', '**/.next/**'],
},

// extends ...
eslint.configs.recommended,
...tsEslint.configs.recommended,
...fixupConfigRules(flatCompat.extends('plugin:@next/next/core-web-vitals')),

// base config
{
languageOptions: {
globals: { ...globals.es2020, ...globals.browser, ...globals.node },
parserOptions: {
projectService: true,
tsconfigRootDir,
warnOnUnsupportedTypeScriptVersion: false,
},
},
rules: {
'no-empty-pattern': 'warn',
'simple-import-sort/exports': 'error',
'simple-import-sort/imports': 'error',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-empty-object-type': 'off',
'@typescript-eslint/no-unsafe-declaration-merging': 'warn',
'react/jsx-no-target-blank': 'warn',
'react/jsx-sort-props': [
'error',
{
reservedFirst: true,
callbacksLast: true,
noSortAlphabetically: true,
},
],
'@next/next/no-sync-scripts': 'warn',
},
},
{
files: ['**/*.js'],
extends: [tsEslint.configs.disableTypeChecked],
rules: {
// turn off other type-aware rules
'@typescript-eslint/internal/no-poorly-typed-ts-props': 'off',

// turn off rules that don't apply to JS code
'@typescript-eslint/explicit-function-return-type': 'off',
},
},
eslintConfigPrettier,
);
2 changes: 2 additions & 0 deletions models/Translation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const i18n = new TranslationModel({
'en-US': () => import('../translation/en-US'),
});

export const { t } = i18n;

export const LanguageName: Record<(typeof i18n)['currentLanguage'], string> = {
'zh-CN': '简体中文',
'zh-TW': '繁體中文',
Expand Down
2 changes: 1 addition & 1 deletion next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.
2 changes: 1 addition & 1 deletion next.config.mjs → next.config.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import setPWA from 'next-pwa';
// @ts-ignore
// @ts-expect-error No types available
import withLess from 'next-with-less';

const { NODE_ENV, CI } = process.env,
Expand Down
90 changes: 51 additions & 39 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,69 +7,81 @@
"node": ">=18"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^6.6.0",
"@fortawesome/free-brands-svg-icons": "^6.6.0",
"@fortawesome/free-solid-svg-icons": "^6.6.0",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
"@giscus/react": "^3.0.0",
"idea-react": "^2.0.0-rc.2",
"koajax": "^3.0.1",
"less": "^4.2.0",
"@giscus/react": "^3.1.0",
"idea-react": "^2.0.0-rc.8",
"koajax": "^3.1.1",
"less": "^4.2.2",
"less-loader": "^12.2.0",
"lodash": "^4.17.21",
"marked": "^14.1.1",
"mobx": "^6.13.1",
"mobx-github": "^0.3.4",
"mobx-i18n": "^0.5.0",
"mobx-react": "^9.1.1",
"mobx-restful": "^1.0.1",
"mobx-restful-table": "^2.0.0",
"next": "^14.2.7",
"marked": "^15.0.6",
"mobx": "^6.13.6",
"mobx-github": "^0.3.5",
"mobx-i18n": "^0.6.0",
"mobx-react": "^9.2.0",
"mobx-restful": "^2.1.0",
"mobx-restful-table": "^2.0.1",
"next": "^15.1.6",
"next-pwa": "~5.6.0",
"next-ssr-middleware": "^0.8.7",
"next-ssr-middleware": "^0.8.9",
"next-with-less": "^3.0.1",
"react": "^18.3.1",
"react-bootstrap": "^2.10.4",
"react-bootstrap": "^2.10.9",
"react-dom": "^18.3.1",
"undici": "^6.19.8",
"web-utility": "^4.4.0"
"undici": "^7.3.0",
"web-utility": "^4.4.2"
},
"devDependencies": {
"@babel/plugin-proposal-decorators": "^7.24.7",
"@babel/plugin-transform-typescript": "^7.25.2",
"@babel/preset-react": "^7.24.7",
"@types/lodash": "^4.17.7",
"@babel/plugin-proposal-decorators": "^7.25.9",
"@babel/plugin-transform-typescript": "^7.26.7",
"@babel/preset-react": "^7.26.3",
"@eslint/compat": "^1.2.6",
"@eslint/eslintrc": "^3.2.0",
"@eslint/js": "^9.19.0",
"@softonus/prettier-plugin-duplicate-remover": "^1.1.2",
"@types/eslint-config-prettier": "^6.11.3",
"@types/eslint__eslintrc": "^2.1.2",
"@types/lodash": "^4.17.15",
"@types/next-pwa": "^5.6.9",
"@types/node": "^20.16.4",
"@types/react": "^18.3.5",
"eslint": "^8.57.0",
"eslint-config-next": "^14.2.7",
"eslint-config-prettier": "^9.1.0",
"@types/node": "^22.13.0",
"@types/react": "^18.3.18",
"eslint": "^9.19.0",
"eslint-config-next": "^15.1.6",
"eslint-config-prettier": "^10.0.1",
"eslint-plugin-react": "^7.37.4",
"eslint-plugin-simple-import-sort": "^12.1.1",
"husky": "^9.1.5",
"lint-staged": "^15.2.10",
"prettier": "^3.3.3",
"typescript": "~5.5.4"
"globals": "^15.14.0",
"husky": "^9.1.7",
"lint-staged": "^15.4.3",
"prettier": "^3.4.2",
"prettier-plugin-css-order": "^2.1.2",
"typescript": "~5.7.3",
"typescript-eslint": "^8.22.0"
},
"resolutions": {
"native-file-system-adapter": "npm:@tech_query/native-file-system-adapter@^3.0.1"
"next": "$next"
},
"prettier": {
"singleQuote": true,
"trailingComma": "all",
"arrowParens": "avoid"
"arrowParens": "avoid",
"plugins": [
"prettier-plugin-css-order",
"@softonus/prettier-plugin-duplicate-remover"
]
},
"lint-staged": {
"*.{html,md,less,json,yml,js,mjs,ts,tsx}": "prettier --write",
"*.{js,mjs,ts,tsx}": "eslint --fix"
"*.{html,md,less,json,yml,js,mjs,ts,tsx}": "prettier --write"
},
"scripts": {
"prepare": "husky install",
"prepare": "husky",
"dev": "next dev",
"build": "next build",
"export": "next build && next export",
"start": "next start",
"lint": "next lint",
"lint": "next lint --fix && git add .",
"test": "lint-staged && npm run lint && tsc --noEmit",
"pack-image": "docker build -t next-bootstrap-ts:latest .",
"container": "docker rm -f next-bootstrap-ts && docker run --name next-bootstrap-ts -p 3000:3000 -d next-bootstrap-ts:latest"
Expand Down
10 changes: 4 additions & 6 deletions pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ import { Image } from 'react-bootstrap';
import { MainNavigator } from '../components/MainNavigator';
import { SocialIconBar } from '../components/SocialIconBar';
import { isServer } from '../models/Base';
import { i18n } from '../models/Translation';
import { i18n, t } from '../models/Translation';

configure({ enforceActions: 'never' });

enableStaticRendering(isServer());

const { t } = i18n;

globalThis.addEventListener?.('unhandledrejection', ({ reason }) => {
var { message, response } = reason as HTTPError;
const { message, response } = reason as HTTPError;
const { statusText, body } = response || {};

message = body?.message || statusText || message;
const tips = body?.message || statusText || message;

if (message) alert(message);
if (tips) alert(tips);
});

const AppShell = observer(({ Component, pageProps }: AppProps) => (
Expand Down
4 changes: 2 additions & 2 deletions pages/api/GitHub/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ export const proxyGithub = <T>(dataFilter?: (path: string, data: T) => T) =>
const path = url!.slice(`/api/GitHub/`.length);

const { status, body: data } = await githubClient.request<T>({
// @ts-ignore
// @ts-expect-error Upstream Type compatibility issue
method,
path,
// @ts-ignore
// @ts-expect-error Upstream Type compatibility issue
headers,
body: body || undefined,
});
Expand Down
9 changes: 5 additions & 4 deletions pages/api/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export function safeAPI(handler: NextAPI): NextAPI {
return res.send({ message: (error as Error).message });
}
const { message, response } = error;
let { status, body } = response;
let { body } = response;

res.status(status);
res.status(response.status);
res.statusMessage = message;

if (body instanceof ArrayBuffer)
Expand All @@ -35,8 +35,9 @@ export function safeAPI(handler: NextAPI): NextAPI {

body = JSON.parse(body);
console.error(body);
} catch {}

} catch {
//
}
res.send(body);
}
};
Expand Down
Loading

1 comment on commit 2797031

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for fcc-china ready!

✅ Preview
https://fcc-china-msg3thera-techquerys-projects.vercel.app

Built with commit 2797031.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.