From 74a3ee90c74fe275a847088a0e1a3b35390ea87a Mon Sep 17 00:00:00 2001 From: undefined Date: Tue, 18 Mar 2025 01:07:34 +0800 Subject: [PATCH] ui-next: move to a seperate tsconfig --- .eslintignore | 4 -- .eslintrc.yaml | 20 ++++++- build/prepare.js | 59 ++++++++++++++++--- framework/eslint-config/react.yaml | 1 + package.json | 2 +- packages/hydrooj/package.json | 2 +- packages/hydrooj/src/service/api.ts | 3 +- .../components/zipDownloader/index.ts | 2 +- packages/ui-default/package.json | 8 +-- packages/ui-default/typed.d.ts | 15 +++++ packages/ui-default/vue.d.ts | 3 - packages/ui-next/package.json | 6 -- packages/ui-next/src/main.tsx | 2 +- 13 files changed, 93 insertions(+), 34 deletions(-) delete mode 100644 .eslintignore delete mode 100644 packages/ui-default/vue.d.ts diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 401c38a5c..000000000 --- a/.eslintignore +++ /dev/null @@ -1,4 +0,0 @@ -dist -*.d.ts -node_modules -public/**/*.js \ No newline at end of file diff --git a/.eslintrc.yaml b/.eslintrc.yaml index ed83c7448..3eb37b15f 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -4,6 +4,9 @@ extends: ignorePatterns: - public/**/*.js - packages/ui-default + - dist + - '*.d.ts' + - node_modules overrides: - files: - '**/{public,frontend}/**/*.{ts,tsx,page.js}' @@ -24,6 +27,15 @@ overrides: externalModules: true LOCALES: true LANGS: true + - files: + - 'packages/ui-next/src/**/*.{ts,tsx}' + rules: + '@stylistic/indent': + - warn + - 2 + env: + browser: true + es6: true rules: '@typescript-eslint/no-invalid-this': 1 simple-import-sort/imports: @@ -42,9 +54,13 @@ settings: - .ts - .js - .jsx + - .tsx import/resolver: - typescript: - alwaysTryTypes: true + webpack: + config: + resolve: + extensions: ['.js', '.jsx', '.ts', '.tsx', '.vue'] + parserOptions: sourceType: module # project: diff --git a/build/prepare.js b/build/prepare.js index 608527eb3..e03f440a7 100644 --- a/build/prepare.js +++ b/build/prepare.js @@ -34,6 +34,7 @@ const config = { compilerOptions: compilerOptionsBase, references: [ { path: 'tsconfig.ui.json' }, + { path: 'tsconfig.ui-next.json' }, { path: 'plugins/tsconfig.json' }, ], files: [], @@ -89,8 +90,7 @@ const UIConfig = { include: ['ts', 'tsx', 'vue', 'json'] .flatMap((ext) => ['plugins'] .flatMap((name) => [`${name}/**/public/**/*.${ext}`, `${name}/**/frontend/**/*.${ext}`]) - .concat(`packages/ui-default/**/*.${ext}`) - .concat(`packages/ui-next/src/**/*.${ext}`)), + .concat(`packages/ui-default/**/*.${ext}`)), compilerOptions: { ...compilerOptionsBase, module: 'ESNext', @@ -120,6 +120,48 @@ const UIConfig = { }, }; +const UINextConfig = { + exclude: [ + '**/node_modules', + ], + include: ['ts', 'tsx', 'vue', 'json'].map((ext) => `packages/ui-next/src/**/*.${ext}`), + compilerOptions: { + ...compilerOptionsBase, + module: 'ESNext', + skipLibCheck: true, + allowSyntheticDefaultImports: true, + baseUrl: '.', + jsx: 'react-jsx', + outDir: path.join(baseOutDir, 'ui-next'), + + strict: true, + + useDefineForClassFields: true, + lib: ['es2022', 'DOM', 'DOM.Iterable'], + + /* Bundler mode */ + moduleResolution: 'bundler', + moduleDetection: 'force', + noEmit: true, + + /* Linting */ + noFallthroughCasesInSwitch: true, + noUncheckedSideEffectImports: true, + + paths: { + '@/*': [ + './packages/ui-next/*', + ], + }, + }, +}; + +const tryUpdate = (location, content) => { + const current = fs.existsSync(location) ? fs.readFileSync(location, 'utf-8') : ''; + const expected = typeof content === 'string' ? content : JSON.stringify(content, null, 2); + if (expected !== current) fs.writeFileSync(location, expected); +}; + const nm = path.resolve(__dirname, '../node_modules'); fs.ensureDirSync(path.join(nm, '@hydrooj')); try { @@ -148,7 +190,7 @@ const pluginsConfig = { }, }, }; -fs.writeFileSync(path.resolve(process.cwd(), 'plugins', 'tsconfig.json'), JSON.stringify(pluginsConfig)); +tryUpdate(path.resolve(process.cwd(), 'plugins', 'tsconfig.json'), pluginsConfig); for (const pkg of modules) { const basedir = path.resolve(process.cwd(), pkg); @@ -162,9 +204,7 @@ for (const pkg of modules) { config.references.push({ path: pkg }); const origConfig = (files.includes('src') ? configSrc : configFlat)(pkg); const expectedConfig = JSON.stringify(pkg.startsWith('modules/') ? withoutTypes(origConfig) : origConfig); - const configPath = path.resolve(basedir, 'tsconfig.json'); - const currentConfig = fs.existsSync(configPath) ? fs.readFileSync(configPath, 'utf-8') : ''; - if (expectedConfig !== currentConfig) fs.writeFileSync(configPath, expectedConfig); + tryUpdate(path.resolve(basedir, 'tsconfig.json'), expectedConfig); if (!files.includes('src')) continue; // Create mapping entry for (const file of fs.readdirSync(path.resolve(basedir, 'src'))) { @@ -172,9 +212,10 @@ for (const pkg of modules) { const name = file.split('.')[0]; const filePath = path.resolve(basedir, `${name}.js`); if (name === 'index' && !fs.existsSync(filePath)) { - fs.writeFileSync(filePath, 'module.exports = require("./src/index");\n'); + tryUpdate(filePath, 'module.exports = require("./src/index");\n'); } } } -fs.writeFileSync(path.resolve(process.cwd(), 'tsconfig.ui.json'), JSON.stringify(UIConfig)); -fs.writeFileSync(path.resolve(process.cwd(), 'tsconfig.json'), JSON.stringify(config)); +tryUpdate(path.resolve(process.cwd(), 'tsconfig.ui.json'), UIConfig); +tryUpdate(path.resolve(process.cwd(), 'tsconfig.ui-next.json'), UINextConfig); +tryUpdate(path.resolve(process.cwd(), 'tsconfig.json'), config); diff --git a/framework/eslint-config/react.yaml b/framework/eslint-config/react.yaml index 390bd9d69..97ca98637 100644 --- a/framework/eslint-config/react.yaml +++ b/framework/eslint-config/react.yaml @@ -4,6 +4,7 @@ extends: plugins: - react - react-refresh +- react-hooks - jsx-a11y rules: react-hooks/exhaustive-deps: 0 diff --git a/package.json b/package.json index 6315aa786..5a93a28fc 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,7 @@ "cross-spawn": "^7.0.6", "esbuild": "0.25.0", "eslint": "^8.57.1", - "eslint-import-resolver-typescript": "^3.9.1", + "eslint-import-resolver-typescript": "^4.1.1", "eslint-import-resolver-webpack": "^0.13.10", "fs-extra": "^11.3.0", "globby": "~14.0.2", diff --git a/packages/hydrooj/package.json b/packages/hydrooj/package.json index 4987a42e1..f36acff64 100644 --- a/packages/hydrooj/package.json +++ b/packages/hydrooj/package.json @@ -16,7 +16,7 @@ "@aws-sdk/lib-storage": "3.726.1", "@aws-sdk/s3-presigned-post": "3.726.1", "@aws-sdk/s3-request-presigner": "3.726.1", - "@cordisjs/core": "4.0.0-alpha.5", + "@cordisjs/core": "4.0.0-alpha.6", "@cordisjs/logger": "1.0.0-alpha.3", "@cordisjs/plugin-timer": "1.0.0-alpha.0", "@graphql-tools/schema": "^10.0.23", diff --git a/packages/hydrooj/src/service/api.ts b/packages/hydrooj/src/service/api.ts index a6fd23840..bf4c655f5 100644 --- a/packages/hydrooj/src/service/api.ts +++ b/packages/hydrooj/src/service/api.ts @@ -13,7 +13,7 @@ const descriptions: Record> = Object.create(null) const handlers: Record> = { Query: Object.create(null), }; -let root: Record = Object.create(null); +const root: Record = handlers.Query; interface ApiContext extends ApiHandler { [key: string]: any; @@ -31,7 +31,6 @@ function setDescription(desc: string) { let schema: GraphQLSchema; let schemaStr = ''; -root = handlers.Query; const applyAuthDirective = (s) => mapSchema(s, { // eslint-disable-next-line consistent-return diff --git a/packages/ui-default/components/zipDownloader/index.ts b/packages/ui-default/components/zipDownloader/index.ts index b06549776..ca040fa01 100644 --- a/packages/ui-default/components/zipDownloader/index.ts +++ b/packages/ui-default/components/zipDownloader/index.ts @@ -90,7 +90,7 @@ declare module '../../api' { export async function downloadProblemSet(pids, name = 'Export') { Notification.info(i18n('Downloading...')); - const targets = []; + const targets: { filename: string; url?: string; content?: string }[] = []; try { await ctx.serial('problemset/download', pids, name, targets); for (const pid of pids) { diff --git a/packages/ui-default/package.json b/packages/ui-default/package.json index c405312c9..0c92deb83 100644 --- a/packages/ui-default/package.json +++ b/packages/ui-default/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@blueprintjs/core": "^5.17.6", - "@cordisjs/core": "4.0.0-alpha.5", + "@cordisjs/core": "4.0.0-alpha.6", "@fontsource/dm-mono": "^5.2.5", "@fontsource/fira-code": "^5.2.5", "@fontsource/inconsolata": "^5.2.5", @@ -25,7 +25,7 @@ "@fontsource/source-code-pro": "^5.2.5", "@fontsource/ubuntu-mono": "^5.2.5", "@hydrooj/utils": "workspace:^", - "@sentry/browser": "^9.5.0", + "@sentry/browser": "^9.6.0", "@sentry/webpack-plugin": "^3.2.2", "@simplewebauthn/browser": "13.1.0", "@svgr/webpack": "^8.1.0", @@ -52,7 +52,7 @@ "classnames": "^2.5.1", "clean-webpack-plugin": "^4.0.0", "clipboard": "^2.0.11", - "copy-webpack-plugin": "^12.0.2", + "copy-webpack-plugin": "^13.0.0", "core-js": "^3.41.0", "core-js-compat": "^3.41.0", "css-loader": "^6.11.0", @@ -70,7 +70,7 @@ "jquery.easing": "^1.4.1", "jquery.transit": "^0.9.12", "matchmedia-polyfill": "^0.3.2", - "md-editor-rt": "^5.4.1", + "md-editor-rt": "^5.4.2", "mini-css-extract-plugin": "^2.9.2", "moment": "^2.30.1", "monaco-editor": "0.52.2", diff --git a/packages/ui-default/typed.d.ts b/packages/ui-default/typed.d.ts index 1f72b0a9a..c54c3f715 100644 --- a/packages/ui-default/typed.d.ts +++ b/packages/ui-default/typed.d.ts @@ -3,3 +3,18 @@ declare module '*.svg?react' { const content: ComponentType; export default content; } +declare module '*.vue' { + export default {} as any; +} +declare module '*.css' { + const content: string; + export default content; +} +declare module '*.styl' { + const content: string; + export default content; +} +declare module '*.scss' { + const content: string; + export default content; +} diff --git a/packages/ui-default/vue.d.ts b/packages/ui-default/vue.d.ts deleted file mode 100644 index 4c40378d1..000000000 --- a/packages/ui-default/vue.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -declare module '*.vue' { - export default {} as any; -} diff --git a/packages/ui-next/package.json b/packages/ui-next/package.json index d022c14e2..b341e485c 100644 --- a/packages/ui-next/package.json +++ b/packages/ui-next/package.json @@ -5,7 +5,6 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", - "lint": "eslint .", "preview": "vite preview" }, "dependencies": { @@ -18,12 +17,7 @@ "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", "@vitejs/plugin-react-swc": "^3.8.0", - "eslint": "^9.22.0", - "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.19", - "globals": "^16.0.0", "typescript": "~5.8.2", - "typescript-eslint": "^8.26.1", "vite": "^6.2.2" } } diff --git a/packages/ui-next/src/main.tsx b/packages/ui-next/src/main.tsx index 136674de0..8b9bc3ccd 100644 --- a/packages/ui-next/src/main.tsx +++ b/packages/ui-next/src/main.tsx @@ -3,5 +3,5 @@ import { createRoot } from 'react-dom/client'; import App from './App'; createRoot(document.getElementById('root')!).render( - + );