diff --git a/eslint.config.ts b/eslint.config.ts index 5967bd1..821778e 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -1,116 +1,20 @@ -import cspellPlugin from '@cspell/eslint-plugin'; -import eslint from '@eslint/js'; -import nextPlugin from '@next/eslint-plugin-next'; -import stylistic from '@stylistic/eslint-plugin'; -import { defineConfig } from 'eslint/config'; -import eslintConfigPrettier from 'eslint-config-prettier'; -import react 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'; +import nextJS from 'eslint-idea2app-next-js'; -/** - * @see{@link https://github.com/typescript-eslint/typescript-eslint/blob/main/eslint.config.mjs} - * @see{@link https://github.com/vercel/next.js/issues/71763#issuecomment-2476838298} - */ - -const tsconfigRootDir = fileURLToPath(new URL('.', import.meta.url)); - -export default defineConfig( - // register all of the plugins up-front - { - plugins: { - '@cspell': cspellPlugin, - '@stylistic': stylistic, - 'simple-import-sort': simpleImportSortPlugin, - '@typescript-eslint': tsEslint.plugin, - react, - '@next/next': nextPlugin, - }, - }, +export default [ + ...nextJS, { - // config with just ignores is the replacement for `.eslintignore` ignores: ['**/node_modules/**', '**/public/**', '**/.next/**', '.github/scripts/**'], }, - - // extends ... - eslint.configs.recommended, - ...tsEslint.configs.recommended, - - // base config { - languageOptions: { - globals: { ...globals.es2020, ...globals.browser, ...globals.node }, - parserOptions: { - projectService: true, - tsconfigRootDir, - warnOnUnsupportedTypeScriptVersion: false, - }, - }, rules: { - // spellchecker '@cspell/spellchecker': [ 'warn', { cspell: { - language: 'en', - dictionaries: ['typescript', 'node', 'html', 'css', 'bash', 'npm', 'pnpm'], - words: ['hackathon'], + words: ['aliyun', 'datav', 'Giscus', 'hackathon', 'Serwist'], }, }, ], - // stylistic - '@stylistic/padding-line-between-statements': [ - 'error', - { blankLine: 'always', prev: '*', next: 'return' }, - { blankLine: 'always', prev: 'directive', next: '*' }, - { blankLine: 'any', prev: 'directive', next: 'directive' }, - { - blankLine: 'always', - prev: '*', - next: ['enum', 'interface', 'type'], - }, - ], - 'arrow-body-style': ['error', 'as-needed'], - 'no-empty-pattern': 'warn', - 'no-console': ['error', { allow: ['warn', 'error', 'info'] }], - 'no-restricted-syntax': [ - 'error', - { - selector: "TSPropertySignature[key.name='children']", - message: 'Please use PropsWithChildren instead of defining children manually', - }, - ], - 'consistent-return': 'warn', - 'prefer-destructuring': ['error', { object: true, array: true }], - // simple-import-sort - 'simple-import-sort/exports': 'error', - 'simple-import-sort/imports': 'error', - // TypeScript - '@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', - '@typescript-eslint/consistent-type-definitions': ['error', 'interface'], - // React - 'react/no-unescaped-entities': 'off', - 'react/self-closing-comp': ['error', { component: true, html: true }], - 'react/jsx-curly-brace-presence': ['error', { props: 'never', children: 'never' }], - 'react/jsx-no-target-blank': 'warn', - 'react/jsx-sort-props': [ - 'error', - { - reservedFirst: true, - callbacksLast: true, - noSortAlphabetically: true, - }, - ], - // Next.js - ...nextPlugin.configs.recommended.rules, - ...nextPlugin.configs['core-web-vitals'].rules, - '@next/next/no-sync-scripts': 'warn', }, }, - eslintConfigPrettier, -); +]; diff --git a/models/configuration.ts b/models/configuration.ts index a139830..4d7770a 100644 --- a/models/configuration.ts +++ b/models/configuration.ts @@ -41,6 +41,7 @@ export const LarkAppMeta = { id: process.env.NEXT_PUBLIC_LARK_APP_ID!, secret: process.env.LARK_APP_SECRET!, }; +export const hasLarkServerAccess = Boolean(process.env.LARK_APP_SECRET); const { hostname, pathname } = new URL(process.env.NEXT_PUBLIC_LARK_WIKI_URL!); export const LarkWikiDomain = hostname; diff --git a/next.config.ts b/next.config.ts index f07240c..954e858 100644 --- a/next.config.ts +++ b/next.config.ts @@ -1,6 +1,6 @@ import setMDX from '@next/mdx'; +import withSerwistInit from '@serwist/next'; import { NextConfig } from 'next'; -import setPWA from 'next-pwa'; // @ts-expect-error no official types import withLess from 'next-with-less'; import remarkFrontmatter from 'remark-frontmatter'; @@ -17,10 +17,9 @@ const withMDX = setMDX({ }, extension: /\.mdx?$/, }), - withPWA = setPWA({ - dest: 'public', - register: true, - skipWaiting: true, + withSerwist = withSerwistInit({ + swSrc: 'service-worker.ts', + swDest: 'public/sw.js', disable: isDev, }); @@ -51,7 +50,7 @@ const redirects: NextConfig['redirects'] = async () => }, ]); -export default withPWA( +export default withSerwist( withLess( withMDX({ pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'], diff --git a/package.json b/package.json index 59f0336..27b5948 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "@koa/router": "^15.7.0", "@mdx-js/loader": "^3.1.1", "@mdx-js/react": "^3.1.1", - "@next/mdx": "16.3.0", + "@next/mdx": "16.3.5", "core-js": "^3.49.0", "echarts-jsx": "^0.6.0", "file-type": "^22.0.1", @@ -38,9 +38,9 @@ "mobx-restful": "^2.1.4", "mobx-restful-table": "^2.6.6", "mobx-strapi": "^0.8.1", - "next": "16.3.0", - "next-pwa": "^5.6.0", + "next": "16.3.5", "next-ssr-middleware": "^1.1.1", + "@serwist/next": "^9.5.12", "nodemailer": "^9.0.4", "open-react-map": "^0.9.1", "react": "^19.2.8", @@ -49,30 +49,23 @@ "react-typed-component": "^1.0.6", "remark-frontmatter": "^5.0.0", "remark-mdx-frontmatter": "^5.2.0", + "serwist": "^9.5.12", "web-utility": "^4.7.2", "yaml": "^2.9.0" }, "devDependencies": { - "@cspell/eslint-plugin": "^10.0.1", - "@eslint/js": "^10.0.1", - "@next/eslint-plugin-next": "16.3.0", + "@next/eslint-plugin-next": "16.3.5", "@softonus/prettier-plugin-duplicate-remover": "^1.1.2", - "@stylistic/eslint-plugin": "^5.10.0", - "@types/eslint-config-prettier": "^6.11.3", "@types/jsonwebtoken": "^9.0.10", "@types/koa": "^3.0.3", - "@types/next-pwa": "^5.6.9", "@types/node": "^24.13.3", "@types/nodemailer": "^8.0.1", "@types/react": "^19.2.18", "@types/react-dom": "^19.2.4", "cross-env": "^10.1.0", - "eslint": "^10.8.0", - "eslint-config-next": "16.3.0", - "eslint-config-prettier": "^10.1.8", - "eslint-plugin-react": "^7.37.5", - "eslint-plugin-simple-import-sort": "^14.0.0", - "globals": "^17.9.0", + "eslint": "^10.10.0", + "eslint-config-next": "16.3.5", + "eslint-idea2app-next-js": "^0.1.1", "husky": "^9.1.7", "jiti": "^2.7.0", "less": "^4.8.1", @@ -81,8 +74,7 @@ "next-with-less": "^3.0.1", "prettier": "^3.9.6", "prettier-plugin-css-order": "^2.2.0", - "typescript": "~6.0.3", - "typescript-eslint": "^8.66.0" + "typescript": "~6.0.3" }, "resolutions": { "next": "$next" diff --git a/pages/_app.tsx b/pages/_app.tsx index 4390ea5..79cbaac 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,5 +1,6 @@ import '../styles/globals.css'; +import { SerwistProvider } from '@serwist/next/react'; import { HTTPError } from 'koajax'; import { configure } from 'mobx'; import { enableStaticRendering, observer } from 'mobx-react'; @@ -70,6 +71,7 @@ export default class CustomApp extends App { render() { const { Component, pageProps, router } = this.props, { t } = this.i18nStore; + const isDev = process.env.NODE_ENV === 'development'; const { asPath } = router; const isArticlePage = asPath.startsWith('/article/') || asPath.startsWith('/policy/'), isActivityPage = asPath.startsWith('/hackathon'), @@ -91,7 +93,7 @@ export default class CustomApp extends App { ], }; - return ( + const frame = ( @@ -109,5 +111,13 @@ export default class CustomApp extends App {