diff --git a/eslint.config.js b/eslint.config.js index afafffce9f..955989f874 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -26,7 +26,6 @@ export default vuepress( }, vue: { overrides: { - 'vue/multi-word-component-names': 'off', 'no-useless-assignment': 'off', // TODO: false positive in vue sfc }, }, @@ -34,6 +33,7 @@ export default vuepress( { files: ['**/tests/**'], rules: { + 'import/no-unresolved': 'off', 'no-console': 'off', 'prefer-template': 'off', }, diff --git a/package.json b/package.json index b838469cc1..81672f1251 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "bumpp": "^9.5.1", "conventional-changelog-cli": "^5.0.0", "eslint": "^9.9.0", - "eslint-config-vuepress": "^5.1.0", + "eslint-config-vuepress": "^5.1.2", "husky": "^9.1.4", "lint-staged": "^15.2.9", "prettier": "^3.3.3", diff --git a/packages/bundler-webpack/src/build/types.ts b/packages/bundler-webpack/src/build/types.ts index 5cf926c25c..112392f4cf 100644 --- a/packages/bundler-webpack/src/build/types.ts +++ b/packages/bundler-webpack/src/build/types.ts @@ -21,7 +21,7 @@ export interface FileMeta { /** * Client file meta type, mainly used for */ -export type FileMetaType = 'script' | 'style' | 'image' | 'font' | '' +export type FileMetaType = '' | 'font' | 'image' | 'script' | 'style' /** * A "module request" to "client files meta" key-value map diff --git a/packages/bundler-webpack/src/config/createBaseConfig.ts b/packages/bundler-webpack/src/config/createBaseConfig.ts index b6d8bec3b0..0b6e0accc3 100644 --- a/packages/bundler-webpack/src/config/createBaseConfig.ts +++ b/packages/bundler-webpack/src/config/createBaseConfig.ts @@ -52,7 +52,7 @@ export const createBaseConfig = async ({ /** * module */ - handleModule({ app, options, config, isBuild, isServer }) + handleModule({ options, config, isBuild, isServer }) /** * plugins diff --git a/packages/bundler-webpack/src/config/handleEntry.ts b/packages/bundler-webpack/src/config/handleEntry.ts index 1c2c592b7d..0600895275 100644 --- a/packages/bundler-webpack/src/config/handleEntry.ts +++ b/packages/bundler-webpack/src/config/handleEntry.ts @@ -13,11 +13,13 @@ export const handleEntry = ({ config: Config }): void => { // set client app as entry point - config - .entry('app') - .add( - app.dir.client( - fs.readJsonSync(app.dir.client('package.json')).exports['./app'], - ), - ) + config.entry('app').add( + app.dir.client( + ( + fs.readJsonSync(app.dir.client('package.json')) as { + exports: { './app': string } + } + ).exports['./app'], + ), + ) } diff --git a/packages/bundler-webpack/src/config/handleModule.ts b/packages/bundler-webpack/src/config/handleModule.ts index fe857c7f11..be33ca6a73 100644 --- a/packages/bundler-webpack/src/config/handleModule.ts +++ b/packages/bundler-webpack/src/config/handleModule.ts @@ -1,4 +1,3 @@ -import type { App } from '@vuepress/core' import type Config from 'webpack-5-chain' import type { WebpackBundlerOptions } from '../types.js' import { handleModuleAssets } from './handleModuleAssets.js' @@ -12,13 +11,11 @@ import { handleModuleVue } from './handleModuleVue.js' * Set webpack module */ export const handleModule = ({ - app, options, config, isBuild, isServer, }: { - app: App options: WebpackBundlerOptions config: Config isBuild: boolean @@ -30,19 +27,19 @@ export const handleModule = ({ ) // vue files - handleModuleVue({ app, options, config, isServer }) + handleModuleVue({ options, config, isServer }) // pug files, for templates handleModulePug({ config }) // images & media & fonts - handleModuleAssets({ app, config }) + handleModuleAssets({ config }) // js files handleModuleJs({ options, config, isBuild, isServer }) // ts files - handleModuleTs({ app, config }) + handleModuleTs({ config }) // styles files handleModuleStyles({ options, config, isBuild, isServer }) diff --git a/packages/bundler-webpack/src/config/handleModuleAssets.ts b/packages/bundler-webpack/src/config/handleModuleAssets.ts index 0ccd291938..03f66337ae 100644 --- a/packages/bundler-webpack/src/config/handleModuleAssets.ts +++ b/packages/bundler-webpack/src/config/handleModuleAssets.ts @@ -1,16 +1,9 @@ -import type { App } from '@vuepress/core' import type Config from 'webpack-5-chain' /** * Set webpack config to handle assets files */ -export const handleModuleAssets = ({ - app, - config, -}: { - app: App - config: Config -}): void => { +export const handleModuleAssets = ({ config }: { config: Config }): void => { // images config.module .rule('images') diff --git a/packages/bundler-webpack/src/config/handleModuleJs.ts b/packages/bundler-webpack/src/config/handleModuleJs.ts index d0e3efb386..89a51d698d 100644 --- a/packages/bundler-webpack/src/config/handleModuleJs.ts +++ b/packages/bundler-webpack/src/config/handleModuleJs.ts @@ -45,7 +45,7 @@ export const handleModuleJs = ({ return false } // don't transpile node_modules - return /node_modules/.test(filePath) + return filePath.includes('node_modules') }) .end() // use esbuild-loader diff --git a/packages/bundler-webpack/src/config/handleModuleStyles.ts b/packages/bundler-webpack/src/config/handleModuleStyles.ts index 45b5bede25..6a99b02206 100644 --- a/packages/bundler-webpack/src/config/handleModuleStyles.ts +++ b/packages/bundler-webpack/src/config/handleModuleStyles.ts @@ -3,10 +3,7 @@ import autoprefixer from 'autoprefixer' import MiniCssExtractPlugin from 'mini-css-extract-plugin' import type Config from 'webpack-5-chain' import type { - LessLoaderOptions, - SassLoaderOptions, StylePreprocessorLoaderOptions, - StylusLoaderOptions, WebpackBundlerOptions, } from '../types.js' @@ -26,9 +23,7 @@ export const handleModuleStyles = ({ isBuild: boolean isServer: boolean }): void => { - const handleStyle = < - T extends StylePreprocessorLoaderOptions = StylePreprocessorLoaderOptions, - >({ + const handleStyle = ({ lang, test, loaderName, @@ -37,7 +32,7 @@ export const handleModuleStyles = ({ lang: string test: RegExp loaderName?: string - loaderOptions?: T + loaderOptions?: StylePreprocessorLoaderOptions }): void => { const rule = config.module.rule(lang).test(test) @@ -94,28 +89,28 @@ export const handleModuleStyles = ({ test: /\.p(ost)?css$/, }) - handleStyle({ + handleStyle({ lang: 'scss', test: /\.scss$/, loaderName: 'sass-loader', loaderOptions: options.scss, }) - handleStyle({ + handleStyle({ lang: 'sass', test: /\.sass$/, loaderName: 'sass-loader', loaderOptions: options.sass, }) - handleStyle({ + handleStyle({ lang: 'less', test: /\.less$/, loaderName: 'less-loader', loaderOptions: options.less, }) - handleStyle({ + handleStyle({ lang: 'stylus', test: /\.styl(us)?$/, loaderName: 'stylus-loader', diff --git a/packages/bundler-webpack/src/config/handleModuleTs.ts b/packages/bundler-webpack/src/config/handleModuleTs.ts index 74e045a372..db254558d5 100644 --- a/packages/bundler-webpack/src/config/handleModuleTs.ts +++ b/packages/bundler-webpack/src/config/handleModuleTs.ts @@ -1,5 +1,4 @@ import { createRequire } from 'node:module' -import type { App } from '@vuepress/core' import type Config from 'webpack-5-chain' import { resolveEsbuildJsxOptions } from './resolveEsbuildJsxOptions.js' @@ -8,13 +7,7 @@ const require = createRequire(import.meta.url) /** * Set webpack module to handle ts files */ -export const handleModuleTs = ({ - app, - config, -}: { - app: App - config: Config -}): void => { +export const handleModuleTs = ({ config }: { config: Config }): void => { config.module .rule('ts') .test(/\.tsx?/) diff --git a/packages/bundler-webpack/src/config/handleModuleVue.ts b/packages/bundler-webpack/src/config/handleModuleVue.ts index ecfdbc7069..335159cc1b 100644 --- a/packages/bundler-webpack/src/config/handleModuleVue.ts +++ b/packages/bundler-webpack/src/config/handleModuleVue.ts @@ -1,7 +1,6 @@ import { createRequire } from 'node:module' -import type { App } from '@vuepress/core' -import { VueLoaderPlugin } from 'vue-loader' import type { VueLoaderOptions } from 'vue-loader' +import { VueLoaderPlugin } from 'vue-loader' import type Config from 'webpack-5-chain' import type { WebpackBundlerOptions } from '../types.js' @@ -11,12 +10,10 @@ const require = createRequire(import.meta.url) * Set webpack module to handle vue files */ export const handleModuleVue = ({ - app, options, config, isServer, }: { - app: App options: WebpackBundlerOptions config: Config isServer: boolean diff --git a/packages/bundler-webpack/src/config/handleOtherOptions.ts b/packages/bundler-webpack/src/config/handleOtherOptions.ts index ef8e1d8816..57c9b67392 100644 --- a/packages/bundler-webpack/src/config/handleOtherOptions.ts +++ b/packages/bundler-webpack/src/config/handleOtherOptions.ts @@ -35,9 +35,13 @@ export const handleOtherOptions = ({ isServer, 'version': app.version, // dependencies - 'esbuild-loader': require('esbuild-loader/package.json').version, - 'vue-loader': require('vue-loader/package.json').version, - 'webpack': require('webpack/package.json').version, + 'esbuild-loader': ( + require('esbuild-loader/package.json') as { version: string } + ).version, + 'vue-loader': (require('vue-loader/package.json') as { version: string }) + .version, + 'webpack': (require('webpack/package.json') as { version: string }) + .version, }), }) } diff --git a/packages/bundler-webpack/src/config/handleResolve.ts b/packages/bundler-webpack/src/config/handleResolve.ts index 6081614be2..b20704b52a 100644 --- a/packages/bundler-webpack/src/config/handleResolve.ts +++ b/packages/bundler-webpack/src/config/handleResolve.ts @@ -44,9 +44,9 @@ export const handleResolve = async ({ const aliasResult = await app.pluginApi.hooks.alias.process(app, isServer) // set aliases - aliasResult.forEach((aliasObject) => + aliasResult.forEach((aliasObject) => { Object.entries(aliasObject).forEach(([key, value]) => { - config.resolve.alias.set(key, value) - }), - ) + config.resolve.alias.set(key, value as string) + }) + }) } diff --git a/packages/bundler-webpack/src/webpackBundler.ts b/packages/bundler-webpack/src/webpackBundler.ts index 6a219eea14..1cfb1f9ba2 100644 --- a/packages/bundler-webpack/src/webpackBundler.ts +++ b/packages/bundler-webpack/src/webpackBundler.ts @@ -7,6 +7,6 @@ export const webpackBundler = ( options: WebpackBundlerOptions = {}, ): Bundler => ({ name: '@vuepress/bundler-webpack', - dev: (app) => dev(options, app), - build: (app) => build(options, app), + dev: async (app) => dev(options, app), + build: async (app) => build(options, app), }) diff --git a/packages/cli/src/commands/dev/watchPageFiles.ts b/packages/cli/src/commands/dev/watchPageFiles.ts index 48dcee2060..d9b884a2ee 100644 --- a/packages/cli/src/commands/dev/watchPageFiles.ts +++ b/packages/cli/src/commands/dev/watchPageFiles.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/no-misused-promises */ import type { App, Page } from '@vuepress/core' import { colors, logger } from '@vuepress/utils' -import chokidar from 'chokidar' import type { FSWatcher } from 'chokidar' +import chokidar from 'chokidar' import { handlePageAdd } from './handlePageAdd.js' import { handlePageChange } from './handlePageChange.js' import { handlePageUnlink } from './handlePageUnlink.js' @@ -27,7 +28,6 @@ export const watchPageFiles = (app: App): FSWatcher[] => { } const depsListener = async (dep: string): Promise => { const pagePaths = depsHelper.get(dep) - if (!pagePaths) return for (const filePathRelative of pagePaths) { logger.info( `dependency of page ${colors.magenta(filePathRelative)} is modified`, @@ -38,7 +38,9 @@ export const watchPageFiles = (app: App): FSWatcher[] => { depsWatcher.on('add', depsListener) depsWatcher.on('change', depsListener) depsWatcher.on('unlink', depsListener) - app.pages.forEach((page) => addDeps(page)) + app.pages.forEach((page) => { + addDeps(page) + }) // watch page files const pagesWatcher = chokidar.watch(app.options.pagePatterns, { diff --git a/packages/cli/src/config/types.ts b/packages/cli/src/config/types.ts index 570c825dcc..ec2da48e4a 100644 --- a/packages/cli/src/config/types.ts +++ b/packages/cli/src/config/types.ts @@ -5,6 +5,5 @@ import type { AppConfig, PluginObject } from '@vuepress/core' * * It will be transformed to `AppConfig` by cli */ -export type UserConfig = Partial & - // user config can be used as a plugin - Omit +export type UserConfig = Omit & + Partial diff --git a/packages/client/src/components/RouteLink.ts b/packages/client/src/components/RouteLink.ts index 4f861c5baa..ffff10e430 100644 --- a/packages/client/src/components/RouteLink.ts +++ b/packages/client/src/components/RouteLink.ts @@ -12,6 +12,7 @@ const guardEvent = (event: MouseEvent): boolean | void => { // don't redirect when preventDefault called if (event.defaultPrevented) return // don't redirect on right click + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition if (event.button !== undefined && event.button !== 0) return // don't redirect if `target="_blank"` if (event.currentTarget) { diff --git a/packages/client/src/composables/clientDataUtils.ts b/packages/client/src/composables/clientDataUtils.ts index c9338284f8..3dc3109670 100644 --- a/packages/client/src/composables/clientDataUtils.ts +++ b/packages/client/src/composables/clientDataUtils.ts @@ -21,11 +21,11 @@ export const usePageComponent = (): PageComponentRef => useClientData().pageComponent export const usePageData = < - T extends Record = Record, + T extends Record = Record, >(): PageDataRef => useClientData().pageData as PageDataRef export const usePageFrontmatter = < - T extends Record = Record, + T extends Record = Record, >(): PageFrontmatterRef => useClientData().pageFrontmatter as PageFrontmatterRef diff --git a/packages/client/src/composables/updateHead.ts b/packages/client/src/composables/updateHead.ts index 630c378b4a..6fa83074ec 100644 --- a/packages/client/src/composables/updateHead.ts +++ b/packages/client/src/composables/updateHead.ts @@ -1,5 +1,5 @@ -import { inject } from 'vue' import type { InjectionKey } from 'vue' +import { inject } from 'vue' /** * A util function to force update `` of current page diff --git a/packages/client/src/internal/routes.ts b/packages/client/src/internal/routes.ts index 796e34bebf..3d395e53f9 100644 --- a/packages/client/src/internal/routes.ts +++ b/packages/client/src/internal/routes.ts @@ -2,8 +2,8 @@ import { redirects as redirectsRaw, routes as routesRaw, } from '@internal/routes' -import { shallowRef } from 'vue' import type { Ref } from 'vue' +import { shallowRef } from 'vue' import type { Redirects, Routes } from '../types/index.js' /** diff --git a/packages/client/src/resolvers.ts b/packages/client/src/resolvers.ts index 7b1fc0f18f..46e85c8da3 100644 --- a/packages/client/src/resolvers.ts +++ b/packages/client/src/resolvers.ts @@ -85,6 +85,7 @@ export const resolvers = reactive({ const layoutName = isString(pageData.frontmatter.layout) ? pageData.frontmatter.layout : LAYOUT_NAME_DEFAULT + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- unsafe indexed access if (!layouts[layoutName]) { throw new Error(`[vuepress] Cannot resolve layout: ${layoutName}`) } @@ -113,8 +114,9 @@ export const resolvers = reactive({ head: [ // when merging head, the locales head should be placed before root head // to get higher priority + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- unsafe indexed access ...(locales[routeLocale]?.head ?? []), - ...(siteData.head ?? []), + ...siteData.head, ], }), }) diff --git a/packages/client/src/setupDevtools.ts b/packages/client/src/setupDevtools.ts index ab57f1e43e..a22a731140 100644 --- a/packages/client/src/setupDevtools.ts +++ b/packages/client/src/setupDevtools.ts @@ -1,6 +1,6 @@ import { setupDevtoolsPlugin } from '@vue/devtools-api' -import { watch } from 'vue' import type { App } from 'vue' +import { watch } from 'vue' import type { ClientData } from './types/index.js' const PLUGIN_ID = 'org.vuejs.vuepress' @@ -12,11 +12,14 @@ const INSPECTOR_LABEL = PLUGIN_LABEL const INSPECTOR_CLIENT_DATA_ID = 'client-data' const INSPECTOR_CLIENT_DATA_LABEL = 'Client Data' +type ClientDataKey = keyof ClientData +type ClientDataValue = ClientData[ClientDataKey] + export const setupDevtools = (app: App, clientData: ClientData): void => { setupDevtoolsPlugin( { // fix recursive reference - app: app as any, + app: app as never, id: PLUGIN_ID, label: PLUGIN_LABEL, packageName: '@vuepress/client', @@ -25,9 +28,12 @@ export const setupDevtools = (app: App, clientData: ClientData): void => { componentStateTypes: [PLUGIN_COMPONENT_STATE_TYPE], }, (api) => { - const clientDataEntries = Object.entries(clientData) - const clientDataKeys = Object.keys(clientData) - const clientDataValues = Object.values(clientData) + const clientDataEntries = Object.entries(clientData) as [ + ClientDataKey, + ClientDataValue, + ][] + const clientDataKeys = Object.keys(clientData) as ClientDataKey[] + const clientDataValues = Object.values(clientData) as ClientDataValue[] // setup component state api.on.inspectComponent((payload) => { @@ -72,12 +78,12 @@ export const setupDevtools = (app: App, clientData: ClientData): void => { ), } } - if (clientDataKeys.includes(payload.nodeId)) { + if (clientDataKeys.includes(payload.nodeId as ClientDataKey)) { payload.state = { [INSPECTOR_CLIENT_DATA_LABEL]: [ { key: payload.nodeId, - value: clientData[payload.nodeId].value, + value: clientData[payload.nodeId as ClientDataKey].value, }, ], } diff --git a/packages/client/types.d.ts b/packages/client/types.d.ts index 2d55050eb3..f694351554 100644 --- a/packages/client/types.d.ts +++ b/packages/client/types.d.ts @@ -1,7 +1,8 @@ +/* eslint-disable @typescript-eslint/naming-convention, no-underscore-dangle */ declare const __VUEPRESS_VERSION__: string declare const __VUEPRESS_BASE__: string declare const __VUEPRESS_DEV__: boolean declare const __VUEPRESS_SSR__: boolean -declare const __VUE_HMR_RUNTIME__: Record +declare const __VUE_HMR_RUNTIME__: Record declare const __VUE_OPTIONS_API__: boolean declare const __VUE_PROD_DEVTOOLS__: boolean diff --git a/packages/shared/src/types/page.ts b/packages/shared/src/types/page.ts index a219ea773b..a1d05f2372 100644 --- a/packages/shared/src/types/page.ts +++ b/packages/shared/src/types/page.ts @@ -47,7 +47,7 @@ export interface PageBase< * Vuepress page data */ export type PageData< - ExtraPageData extends Record = Record, + ExtraPageData extends Record = Record, ExtraPageFrontmatter extends Record = Record< string, unknown diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e4dc5e8d88..0cf6fbe334 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -36,8 +36,8 @@ importers: specifier: ^9.9.0 version: 9.9.0(jiti@1.21.6) eslint-config-vuepress: - specifier: ^5.1.0 - version: 5.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6))) + specifier: ^5.1.2 + version: 5.1.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6))) husky: specifier: ^9.1.4 version: 9.1.4 @@ -2394,8 +2394,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-config-vuepress@5.1.0: - resolution: {integrity: sha512-7rMq5I2Io6tcMAkcaqzI0mowQyQrd11EEDBcHmFRbhSuxsjDt6VF8FGRUNRhkBQGCc3WqdTcoIzI2KYdjj5Q4A==} + eslint-config-vuepress@5.1.2: + resolution: {integrity: sha512-JkspJeMslF7k7XrloW6ZkRNKJQLm1e4lVuV+xkDQwDn2INScDneEkMgIGZT7l14nA7ElAHh5Zt+pz4bYxW1rxw==} eslint-import-resolver-node@0.3.9: resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} @@ -7307,7 +7307,7 @@ snapshots: dependencies: eslint: 9.9.0(jiti@1.21.6) - eslint-config-vuepress@5.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6))): + eslint-config-vuepress@5.1.2(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6))): dependencies: '@meteorlxy/eslint-config': 4.2.2(eslint-plugin-vue@9.27.0(eslint@9.9.0(jiti@1.21.6)))(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)(vue-eslint-parser@9.4.3(eslint@9.9.0(jiti@1.21.6))) '@typescript-eslint/utils': 8.1.0(eslint@9.9.0(jiti@1.21.6))(typescript@5.5.4)