From 9db2229f705efaae38e743f3e3e61293956feb29 Mon Sep 17 00:00:00 2001 From: Anthony Fu Date: Fri, 26 Aug 2022 23:47:29 +0800 Subject: [PATCH] refactor: enable strict type checking everywhere (#6943) --- docs/package.json | 2 +- packages/kit/package.json | 2 +- packages/kit/tsconfig.json | 11 ----- packages/nuxi/package.json | 1 + packages/nuxi/src/commands/dev.ts | 11 +++-- packages/nuxi/src/commands/index.ts | 2 +- packages/nuxi/src/commands/info.ts | 23 +++++---- packages/nuxi/src/commands/init.ts | 13 ++--- packages/nuxi/src/utils/cjs.ts | 6 +-- packages/nuxi/src/utils/diff.ts | 20 ++++---- packages/nuxi/src/utils/help.ts | 16 +++--- packages/nuxi/src/utils/kit.ts | 2 +- packages/nuxi/src/utils/nuxt.ts | 2 +- packages/nuxi/src/utils/packageManagers.ts | 7 ++- packages/nuxi/src/utils/prepare.ts | 3 +- packages/nuxt/package.json | 2 +- .../nuxt/src/app/composables/asyncData.ts | 2 +- packages/nuxt/src/app/nuxt.ts | 2 +- packages/nuxt/tsconfig.json | 11 ----- packages/schema/build.config.ts | 3 +- packages/schema/package.json | 1 + packages/schema/src/config/_adhoc.ts | 6 ++- packages/schema/src/config/_app.ts | 19 ++++--- packages/schema/src/config/_common.ts | 30 +++++++----- packages/schema/src/config/_internal.ts | 6 ++- packages/schema/src/config/build.ts | 24 +++++---- packages/schema/src/config/cli.ts | 6 ++- packages/schema/src/config/experimental.ts | 8 +-- packages/schema/src/config/generate.ts | 17 +++++-- packages/schema/src/config/messages.ts | 4 +- packages/schema/src/config/nitro.ts | 6 ++- packages/schema/src/config/postcss.ts | 5 +- packages/schema/src/config/render.ts | 14 ++++-- packages/schema/src/config/router.ts | 5 +- packages/schema/src/config/server.ts | 4 +- packages/schema/src/config/typescript.ts | 6 ++- packages/schema/src/config/vite.ts | 7 +-- packages/schema/src/config/webpack.ts | 17 ++++--- packages/schema/src/types/module.ts | 4 +- packages/test-utils/src/browser.ts | 2 +- packages/test-utils/src/context.ts | 8 +-- packages/test-utils/src/nuxt.ts | 2 +- packages/test-utils/src/run.ts | 1 + packages/test-utils/src/server.ts | 4 +- packages/vite/tsconfig.json | 11 ----- packages/webpack/package.json | 1 + packages/webpack/src/configs/client.ts | 1 + packages/webpack/src/configs/server.ts | 15 ++++-- packages/webpack/src/plugins/dynamic-base.ts | 4 +- packages/webpack/src/plugins/vue/client.ts | 49 ++++++++++--------- packages/webpack/src/plugins/vue/server.ts | 35 ++++++------- packages/webpack/src/plugins/vue/util.ts | 11 +++-- packages/webpack/src/presets/assets.ts | 2 +- packages/webpack/src/presets/base.ts | 16 ++++-- packages/webpack/src/presets/esbuild.ts | 4 +- packages/webpack/src/presets/node.ts | 2 +- packages/webpack/src/presets/pug.ts | 2 +- packages/webpack/src/presets/style.ts | 22 ++++----- packages/webpack/src/presets/vue.ts | 8 +-- packages/webpack/src/utils/config.ts | 6 +-- packages/webpack/src/utils/mfs.ts | 2 +- packages/webpack/src/utils/postcss.ts | 10 ++-- packages/webpack/src/virtual-modules.ts | 2 +- packages/webpack/src/webpack.ts | 20 ++++---- scripts/bump-edge.ts | 10 +++- test/basic.test.ts | 8 +-- test/utils.ts | 8 +-- tsconfig.json | 5 +- yarn.lock | 37 ++++++++++++-- 69 files changed, 365 insertions(+), 273 deletions(-) delete mode 100644 packages/kit/tsconfig.json delete mode 100644 packages/nuxt/tsconfig.json delete mode 100644 packages/vite/tsconfig.json diff --git a/docs/package.json b/docs/package.json index 8dd8a352a0..d17d736822 100644 --- a/docs/package.json +++ b/docs/package.json @@ -20,7 +20,7 @@ "pathe": "^0.3.5", "rimraf": "^3.0.2", "scule": "^0.3.2", - "untyped": "^0.4.5", + "untyped": "^0.4.7", "vue-mq": "^1.0.1", "vue-plausible": "^1.3.2" }, diff --git a/packages/kit/package.json b/packages/kit/package.json index d357efc913..7ae2022be9 100644 --- a/packages/kit/package.json +++ b/packages/kit/package.json @@ -30,7 +30,7 @@ "semver": "^7.3.7", "unctx": "^2.0.1", "unimport": "^0.6.7", - "untyped": "^0.4.5" + "untyped": "^0.4.7" }, "devDependencies": { "@types/lodash.template": "^4", diff --git a/packages/kit/tsconfig.json b/packages/kit/tsconfig.json deleted file mode 100644 index 35a35f0192..0000000000 --- a/packages/kit/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "noImplicitAny": true - }, - "include": [ - "./src/**/*.ts", - "./test/**/*.ts" - ] -} diff --git a/packages/nuxi/package.json b/packages/nuxi/package.json index 17e7902b39..532fa8de0b 100644 --- a/packages/nuxi/package.json +++ b/packages/nuxi/package.json @@ -21,6 +21,7 @@ "@nuxt/kit": "3.0.0-rc.8", "@nuxt/schema": "3.0.0-rc.8", "@types/clear": "^0", + "@types/flat": "^5.0.2", "@types/mri": "^1.1.1", "@types/semver": "^7", "c12": "^0.2.9", diff --git a/packages/nuxi/src/commands/dev.ts b/packages/nuxi/src/commands/dev.ts index d63de0dbe0..aa8edeb450 100644 --- a/packages/nuxi/src/commands/dev.ts +++ b/packages/nuxi/src/commands/dev.ts @@ -1,4 +1,5 @@ import type { AddressInfo } from 'node:net' +import { RequestListener } from 'node:http' import { resolve, relative, normalize } from 'pathe' import chokidar from 'chokidar' import { debounce } from 'perfect-debounce' @@ -24,15 +25,15 @@ export default defineNuxtCommand({ overrideEnv('development') const { listen } = await import('listhen') - let currentHandler + let currentHandler: RequestListener | undefined let loadingMessage = 'Nuxt is starting...' - const loadingHandler = async (_req, res) => { + const loadingHandler: RequestListener = async (_req, res) => { const { loading: loadingTemplate } = await importModule('@nuxt/ui-templates') res.setHeader('Content-Type', 'text/html; charset=UTF-8') res.statusCode = 503 // Service Unavailable res.end(loadingTemplate({ loading: loadingMessage })) } - const serverHandler = (req, res) => { + const serverHandler: RequestListener = (req, res) => { return currentHandler ? currentHandler(req, res) : loadingHandler(req, res) } @@ -64,7 +65,7 @@ export default defineNuxtCommand({ const load = async (isRestart: boolean, reason?: string) => { try { loadingMessage = `${reason ? reason + '. ' : ''}${isRestart ? 'Restarting' : 'Starting'} nuxt...` - currentHandler = null + currentHandler = undefined if (isRestart) { consola.info(loadingMessage) } @@ -103,7 +104,7 @@ export default defineNuxtCommand({ } } catch (err) { consola.error(`Cannot ${isRestart ? 'restart' : 'start'} nuxt: `, err) - currentHandler = null + currentHandler = undefined loadingMessage = 'Error while loading nuxt. Please check console and fix errors.' } } diff --git a/packages/nuxi/src/commands/index.ts b/packages/nuxi/src/commands/index.ts index b2469131f0..4771e7c4da 100644 --- a/packages/nuxi/src/commands/index.ts +++ b/packages/nuxi/src/commands/index.ts @@ -1,6 +1,6 @@ import type { Argv } from 'mri' -const _rDefault = r => r.default || r +const _rDefault = (r: any) => r.default || r export const commands = { dev: () => import('./dev').then(_rDefault), diff --git a/packages/nuxi/src/commands/info.ts b/packages/nuxi/src/commands/info.ts index 66753eda94..06ce952edd 100644 --- a/packages/nuxi/src/commands/info.ts +++ b/packages/nuxi/src/commands/info.ts @@ -6,6 +6,7 @@ import jiti from 'jiti' import destr from 'destr' import { splitByCase } from 'scule' import clipboardy from 'clipboardy' +import { NuxtModule } from '@nuxt/schema' import { getPackageManager, getPackageManagerVersion } from '../utils/packageManagers' import { findup } from '../utils/fs' import { defineNuxtCommand } from './index' @@ -27,13 +28,13 @@ export default defineNuxtCommand({ const { dependencies = {}, devDependencies = {} } = findPackage(rootDir) // Utils to query a dependency version - const getDepVersion = name => getPkg(name, rootDir)?.version || dependencies[name] || devDependencies[name] + const getDepVersion = (name: string) => getPkg(name, rootDir)?.version || dependencies[name] || devDependencies[name] const listModules = (arr = []) => arr - .map(normalizeConfigModule) + .map(m => normalizeConfigModule(m, rootDir)) .filter(Boolean) .map((name) => { - const npmName = name.split('/').splice(0, 2).join('/') // @foo/bar/baz => @foo/bar + const npmName = name!.split('/').splice(0, 2).join('/') // @foo/bar/baz => @foo/bar const v = getDepVersion(npmName) return '`' + (v ? `${name}@${v}` : name) + '`' }) @@ -54,6 +55,7 @@ export default defineNuxtCommand({ if (packageManager) { packageManager += '@' + getPackageManagerVersion(packageManager) } else { + // @ts-expect-error packageManager = 'unknown' } @@ -95,14 +97,14 @@ export default defineNuxtCommand({ } }) -function normalizeConfigModule (module, rootDir) { +function normalizeConfigModule (module: NuxtModule | string | null | undefined, rootDir: string): string | null { if (!module) { return null } if (typeof module === 'string') { return module - .split(rootDir).pop() // Strip rootDir - .split('node_modules').pop() // Strip node_modules + .split(rootDir).pop()! // Strip rootDir + .split('node_modules').pop()! // Strip node_modules .replace(/^\//, '') } if (typeof module === 'function') { @@ -111,9 +113,10 @@ function normalizeConfigModule (module, rootDir) { if (Array.isArray(module)) { return normalizeConfigModule(module[0], rootDir) } + return null } -function getNuxtConfig (rootDir) { +function getNuxtConfig (rootDir: string) { try { return jiti(rootDir, { interopDefault: true, esmResolve: true })('./nuxt.config') } catch (err) { @@ -122,7 +125,7 @@ function getNuxtConfig (rootDir) { } } -function getPkg (name, rootDir) { +function getPkg (name: string, rootDir: string) { // Assume it is in {rootDir}/node_modules/${name}/package.json let pkgPath = resolve(rootDir, 'node_modules', name, 'package.json') @@ -135,7 +138,7 @@ function getPkg (name, rootDir) { return readJSONSync(pkgPath) } -function findPackage (rootDir) { +function findPackage (rootDir: string) { return findup(rootDir, (dir) => { const p = resolve(dir, 'package.json') if (existsSync(p)) { @@ -144,7 +147,7 @@ function findPackage (rootDir) { }) || {} } -function readJSONSync (filePath) { +function readJSONSync (filePath: string) { try { return destr(readFileSync(filePath, 'utf-8')) } catch (err) { diff --git a/packages/nuxi/src/commands/init.ts b/packages/nuxi/src/commands/init.ts index bf858633f2..6022aeaa34 100644 --- a/packages/nuxi/src/commands/init.ts +++ b/packages/nuxi/src/commands/init.ts @@ -1,13 +1,14 @@ import { existsSync, readdirSync } from 'node:fs' +// @ts-expect-error missing types import createTiged from 'tiged' import { relative, resolve } from 'pathe' import superb from 'superb' import consola from 'consola' import { defineNuxtCommand } from './index' -const rpath = p => relative(process.cwd(), p) +const rpath = (p: string) => relative(process.cwd(), p) -const resolveTemplate = (template) => { +const resolveTemplate = (template: string | boolean) => { if (typeof template === 'boolean') { consola.error('Please specify a template!') process.exit(1) @@ -39,12 +40,12 @@ export default defineNuxtCommand({ consola.error(`Directory ${dstDir} is not empty. Please pick another name or remove it first. Aborting.`) process.exit(1) } - const formatArgs = msg => msg.replace('options.', '--') - tiged.on('warn', event => consola.warn(formatArgs(event.message))) - tiged.on('info', event => consola.info(formatArgs(event.message))) + const formatArgs = (msg: string) => msg.replace('options.', '--') + tiged.on('warn', (event: any) => consola.warn(formatArgs(event.message))) + tiged.on('info', (event: any) => consola.info(formatArgs(event.message))) try { await tiged.clone(dstDir) - } catch (e) { + } catch (e: any) { if (e.toString().includes('could not find commit hash')) { consola.error(`Failed to clone template from \`${src}\`. Please check the repo is valid and that you have installed \`git\` correctly.`) process.exit(1) diff --git a/packages/nuxi/src/utils/cjs.ts b/packages/nuxi/src/utils/cjs.ts index 27cfa1dabd..0acdb9b06f 100644 --- a/packages/nuxi/src/utils/cjs.ts +++ b/packages/nuxi/src/utils/cjs.ts @@ -3,14 +3,14 @@ import { pathToFileURL } from 'node:url' import { normalize, dirname } from 'pathe' export function getModulePaths (paths?: string | string[]): string[] { - return [].concat( + return [ // @ts-ignore global.__NUXT_PREPATHS__, - ...(Array.isArray(paths) ? paths : [paths]), + ...(paths ? [] : Array.isArray(paths) ? paths : [paths]), process.cwd(), // @ts-ignore global.__NUXT_PATHS__ - ).filter(Boolean) + ].filter(Boolean) } const _require = createRequire(process.cwd()) diff --git a/packages/nuxi/src/utils/diff.ts b/packages/nuxi/src/utils/diff.ts index 9b6ba04e76..515f0a9c98 100644 --- a/packages/nuxi/src/utils/diff.ts +++ b/packages/nuxi/src/utils/diff.ts @@ -2,19 +2,19 @@ import flatten from 'flat' import { detailedDiff } from 'deep-object-diff' import { green, red, blue, cyan } from 'colorette' -function normalizeDiff (diffObj, type, ignore) { - return Object.entries(flatten(diffObj)) +function normalizeDiff (diffObj: any, type: 'added' | 'deleted' | 'updated', ignore: string[]) { + return Object.entries(flatten(diffObj) as Record) .map(([key, value]) => ({ key, value, type })) .filter(item => !ignore.includes(item.key) && typeof item.value !== 'function') } -export function diff (a, b, ignore) { +export function diff (a: any, b: any, ignore: string[]) { const _diff: any = detailedDiff(a, b) - return [].concat( - normalizeDiff(_diff.added, 'added', ignore), - normalizeDiff(_diff.deleted, 'deleted', ignore), - normalizeDiff(_diff.updated, 'updated', ignore) - ) + return [ + ...normalizeDiff(_diff.added, 'added', ignore), + ...normalizeDiff(_diff.deleted, 'deleted', ignore), + ...normalizeDiff(_diff.updated, 'updated', ignore) + ] } const typeMap = { @@ -23,9 +23,9 @@ const typeMap = { updated: blue('updated') } -export function printDiff (diff) { +export function printDiff (diff: any) { for (const item of diff) { - console.log(' ', typeMap[item.type] || item.type, cyan(item.key), item.value ? `~> ${cyan(item.value)}` : '') + console.log(' ', typeMap[item.type as keyof typeof typeMap] || item.type, cyan(item.key), item.value ? `~> ${cyan(item.value)}` : '') } console.log() } diff --git a/packages/nuxi/src/utils/help.ts b/packages/nuxi/src/utils/help.ts index 1bcf609e53..1274da3a8e 100644 --- a/packages/nuxi/src/utils/help.ts +++ b/packages/nuxi/src/utils/help.ts @@ -1,13 +1,17 @@ import { cyan, magenta } from 'colorette' -export function showHelp (meta?) { +import { NuxtCommandMeta } from '../commands' + +export function showHelp (meta?: Partial) { const sections: string[] = [] - if (meta.usage) { - sections.push(magenta('> ') + 'Usage: ' + cyan(meta.usage)) - } + if (meta) { + if (meta.usage) { + sections.push(magenta('> ') + 'Usage: ' + cyan(meta.usage)) + } - if (meta.description) { - sections.push(magenta('⋮ ') + meta.description) + if (meta.description) { + sections.push(magenta('⋮ ') + meta.description) + } } sections.push(`Use ${cyan('npx nuxi [command] --help')} to see help for each command`) diff --git a/packages/nuxi/src/utils/kit.ts b/packages/nuxi/src/utils/kit.ts index d6812cd17c..f2568cf527 100644 --- a/packages/nuxi/src/utils/kit.ts +++ b/packages/nuxi/src/utils/kit.ts @@ -3,7 +3,7 @@ import { importModule } from './cjs' export const loadKit = async (rootDir: string): Promise => { try { return await importModule('@nuxt/kit', rootDir) as typeof import('@nuxt/kit') - } catch (e) { + } catch (e: any) { if (e.toString().includes("Cannot find module '@nuxt/kit'")) { throw new Error('nuxi requires `@nuxt/kit` to be installed in your project. Try installing `nuxt3` or `@nuxt/bridge` first.') } diff --git a/packages/nuxi/src/utils/nuxt.ts b/packages/nuxi/src/utils/nuxt.ts index d24a7c8951..d8d26698fc 100644 --- a/packages/nuxi/src/utils/nuxt.ts +++ b/packages/nuxi/src/utils/nuxt.ts @@ -6,7 +6,7 @@ import type { Nuxt } from '@nuxt/schema' import { rmRecursive } from './fs' export interface NuxtProjectManifest { - _hash: string + _hash: string | null project: { rootDir: string }, diff --git a/packages/nuxi/src/utils/packageManagers.ts b/packages/nuxi/src/utils/packageManagers.ts index 8b301f249a..ba43eaeb92 100644 --- a/packages/nuxi/src/utils/packageManagers.ts +++ b/packages/nuxi/src/utils/packageManagers.ts @@ -9,14 +9,17 @@ export const packageManagerLocks = { pnpm: 'pnpm-lock.yaml' } +type PackageManager = keyof typeof packageManagerLocks + export function getPackageManager (rootDir: string) { return findup(rootDir, (dir) => { for (const name in packageManagerLocks) { - if (existsSync(resolve(dir, packageManagerLocks[name]))) { + const path = packageManagerLocks[name as PackageManager] + if (path && existsSync(resolve(dir, path))) { return name } } - }) + }) as PackageManager | null } export function getPackageManagerVersion (name: string) { diff --git a/packages/nuxi/src/utils/prepare.ts b/packages/nuxi/src/utils/prepare.ts index 0710d9961f..533e33eefe 100644 --- a/packages/nuxi/src/utils/prepare.ts +++ b/packages/nuxi/src/utils/prepare.ts @@ -31,7 +31,7 @@ export const writeTypes = async (nuxt: Nuxt) => { ] }) - const aliases = { + const aliases: Record = { ...nuxt.options.alias, '#build': nuxt.options.buildDir } @@ -48,6 +48,7 @@ export const writeTypes = async (nuxt: Nuxt) => { : aliases[alias] const stats = await fsp.stat(resolve(nuxt.options.rootDir, relativePath)).catch(() => null /* file does not exist */) + tsConfig.compilerOptions = tsConfig.compilerOptions || {} if (stats?.isDirectory()) { tsConfig.compilerOptions.paths[alias] = [relativePath] tsConfig.compilerOptions.paths[`${alias}/*`] = [`${relativePath}/*`] diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index f70f44a788..d7fa95b46a 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -65,7 +65,7 @@ "unenv": "^0.6.1", "unimport": "^0.6.7", "unplugin": "^0.9.2", - "untyped": "^0.4.5", + "untyped": "^0.4.7", "vue": "^3.2.37", "vue-bundle-renderer": "^0.4.2", "vue-devtools-stub": "^0.1.0", diff --git a/packages/nuxt/src/app/composables/asyncData.ts b/packages/nuxt/src/app/composables/asyncData.ts index 5b191ef2f1..7318718bec 100644 --- a/packages/nuxt/src/app/composables/asyncData.ts +++ b/packages/nuxt/src/app/composables/asyncData.ts @@ -144,7 +144,7 @@ export function useAsyncData< result = options.transform(result) } if (options.pick) { - result = pick(result, options.pick) as DataT + result = pick(result as any, options.pick) as DataT } asyncData.data.value = result asyncData.error.value = null diff --git a/packages/nuxt/src/app/nuxt.ts b/packages/nuxt/src/app/nuxt.ts index 0795cfee85..812022729d 100644 --- a/packages/nuxt/src/app/nuxt.ts +++ b/packages/nuxt/src/app/nuxt.ts @@ -231,7 +231,7 @@ export function normalizePlugins (_plugins: Plugin[]) { return plugins as Plugin[] } -export function defineNuxtPlugin (plugin: Plugin) { +export function defineNuxtPlugin> (plugin: Plugin) { plugin[NuxtPluginIndicator] = true return plugin } diff --git a/packages/nuxt/tsconfig.json b/packages/nuxt/tsconfig.json deleted file mode 100644 index 35a35f0192..0000000000 --- a/packages/nuxt/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "noImplicitAny": true - }, - "include": [ - "./src/**/*.ts", - "./test/**/*.ts" - ] -} diff --git a/packages/schema/build.config.ts b/packages/schema/build.config.ts index 285a00ae19..7b84dbfcce 100644 --- a/packages/schema/build.config.ts +++ b/packages/schema/build.config.ts @@ -41,6 +41,7 @@ export default defineBuildConfig({ 'ignore', // Implicit '@vue/compiler-core', - '@vue/shared' + '@vue/shared', + 'untyped' ] }) diff --git a/packages/schema/package.json b/packages/schema/package.json index 0fddc1f6f7..15fbf21c4c 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -17,6 +17,7 @@ "@types/lodash.template": "^4", "@types/semver": "^7", "unbuild": "latest", + "untyped": "^0.4.7", "vite": "~3.0.9" }, "dependencies": { diff --git a/packages/schema/src/config/_adhoc.ts b/packages/schema/src/config/_adhoc.ts index af4e4707ea..d6926ab68d 100644 --- a/packages/schema/src/config/_adhoc.ts +++ b/packages/schema/src/config/_adhoc.ts @@ -1,4 +1,6 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** * Configure Nuxt component auto-registration. * @@ -57,4 +59,4 @@ export default { * @version 3 */ telemetry: undefined -} +}) diff --git a/packages/schema/src/config/_app.ts b/packages/schema/src/config/_app.ts index 045bd6ee37..a6dec3d01b 100644 --- a/packages/schema/src/config/_app.ts +++ b/packages/schema/src/config/_app.ts @@ -1,8 +1,11 @@ import { resolve, join } from 'pathe' import { existsSync, readdirSync } from 'node:fs' import defu from 'defu' +import { defineUntypedSchema } from 'untyped' -export default { +import { MetaObject } from '../types/meta' + +export default defineUntypedSchema({ /** * Vue.js config * @version 2 @@ -17,8 +20,12 @@ export default { * @version 2 */ config: { - silent: { $resolve: (val, get) => val ?? !get('dev') }, - performance: { $resolve: (val, get) => val ?? get('dev') }, + silent: { + $resolve: (val, get) => val ?? !get('dev') + }, + performance: { + $resolve: (val, get) => val ?? get('dev') + }, }, /** * Options for the Vue compiler that will be passed at build time. @@ -105,7 +112,7 @@ export default { */ head: { $resolve: (val, get) => { - const resolved = defu(val, get('meta'), { + const resolved: Required = defu(val, get('meta'), { meta: [], link: [], style: [], @@ -306,7 +313,7 @@ export default { * @version 3 */ css: { - $resolve: val => (val ?? []).map(c => c.src || c) + $resolve: val => (val ?? []).map((c: any) => c.src || c) }, /** @@ -460,4 +467,4 @@ export default { /** Set to false to disable the `` component (see [docs](https://github.com/egoist/vue-client-only)) */ componentClientOnly: true } -} +}) diff --git a/packages/schema/src/config/_common.ts b/packages/schema/src/config/_common.ts index e69f134e11..d6067f441b 100644 --- a/packages/schema/src/config/_common.ts +++ b/packages/schema/src/config/_common.ts @@ -4,9 +4,12 @@ import createRequire from 'create-require' import { pascalCase } from 'scule' import jiti from 'jiti' import defu from 'defu' + import { RuntimeConfig } from '../types/config' -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** * Extend nested configurations from multiple local or remote sources. * @@ -152,12 +155,13 @@ export default { createRequire: { $resolve: (val: any) => { val = process.env.NUXT_CREATE_REQUIRE || val || + // @ts-expect-error global type (typeof globalThis.jest !== 'undefined' ? 'native' : 'jiti') if (val === 'jiti') { - return p => jiti(typeof p === 'string' ? p : p.filename, { esmResolve: true }) + return (p: string | { filename: string }) => jiti(typeof p === 'string' ? p : p.filename, { esmResolve: true }) } if (val === 'native') { - return p => createRequire(typeof p === 'string' ? p : p.filename) + return (p: string | { filename: string }) => createRequire(typeof p === 'string' ? p : p.filename) } return val } @@ -312,17 +316,17 @@ export default { */ globals: { /** @type {(globalName: string) => string} */ - id: globalName => `__${globalName}`, + id: (globalName: string) => `__${globalName}`, /** @type {(globalName: string) => string} */ - nuxt: globalName => `$${globalName}`, + nuxt: (globalName: string) => `$${globalName}`, /** @type {(globalName: string) => string} */ - context: globalName => `__${globalName.toUpperCase()}__`, + context: (globalName: string) => `__${globalName.toUpperCase()}__`, /** @type {(globalName: string) => string} */ - pluginPrefix: globalName => globalName, + pluginPrefix: (globalName: string) => globalName, /** @type {(globalName: string) => string} */ - readyCallback: globalName => `on${pascalCase(globalName)}Ready`, + readyCallback: (globalName: string) => `on${pascalCase(globalName)}Ready`, /** @type {(globalName: string) => string} */ - loadedCallback: globalName => `_on${pascalCase(globalName)}Loaded` + loadedCallback: (globalName: string) => `_on${pascalCase(globalName)}Loaded` }, /** @@ -427,10 +431,10 @@ export default { */ modulesDir: { $default: ['node_modules'], - $resolve: (val, get) => [].concat( - val.map(dir => resolve(get('rootDir'), dir)), + $resolve: (val, get) => [ + ...val.map((dir: string) => resolve(get('rootDir'), dir)), resolve(process.cwd(), 'node_modules') - ) + ] }, /** @@ -759,4 +763,4 @@ export default { * @version 3 */ appConfig: {}, -} +}) diff --git a/packages/schema/src/config/_internal.ts b/packages/schema/src/config/_internal.ts index ba3144962b..400aad87e8 100644 --- a/packages/schema/src/config/_internal.ts +++ b/packages/schema/src/config/_internal.ts @@ -1,4 +1,6 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** @private */ _majorVersion: 2, /** @private */ @@ -21,4 +23,4 @@ export default { _nuxtConfigFiles: [], /** @private */ appDir: '' -} +}) diff --git a/packages/schema/src/config/build.ts b/packages/schema/src/config/build.ts index ab78aff522..e1122c7ec5 100644 --- a/packages/schema/src/config/build.ts +++ b/packages/schema/src/config/build.ts @@ -2,8 +2,9 @@ import defu from 'defu' import { join } from 'pathe' import { isCI, isTest } from 'std-env' import { normalizeURL, withTrailingSlash } from 'ufo' +import { defineUntypedSchema } from 'untyped' -export default { +export default defineUntypedSchema({ /** * The builder to use for bundling the Vue part of your application. * @@ -15,7 +16,7 @@ export default { if (typeof val === 'object') { return val } - const map = { + const map: Record = { vite: '@nuxt/vite-builder', webpack: '@nuxt/webpack-builder', } @@ -225,15 +226,16 @@ export default { * chunk: ({ isDev }) => (isDev ? '[name].js' : '[id].[contenthash].js') * } * ``` + * @type {Record string)>} * @version 2 */ filenames: { - app: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, - chunk: ({ isDev, isModern }) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, - css: ({ isDev }) => isDev ? '[name].css' : 'css/[contenthash:7].css', - img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]', - font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', - video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]' + app: ({ isDev, isModern }: any) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, + chunk: ({ isDev, isModern }: any) => isDev ? `[name]${isModern ? '.modern' : ''}.js` : `[contenthash:7]${isModern ? '.modern' : ''}.js`, + css: ({ isDev }: any) => isDev ? '[name].css' : 'css/[contenthash:7].css', + img: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]', + font: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', + video: ({ isDev }: any) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]' }, /** @@ -360,7 +362,9 @@ export default { optimization: { runtimeChunk: 'single', /** Set minimize to false to disable all minimizers. (It is disabled in development by default) */ - minimize: { $resolve: (val, get) => val ?? !get('dev') }, + minimize: { + $resolve: (val, get) => val ?? !get('dev') + }, /** You can set minimizer to a customized array of plugins. */ minimizer: undefined, splitChunks: { @@ -639,4 +643,4 @@ export default { */ followSymlinks: false } -} +}) diff --git a/packages/schema/src/config/cli.ts b/packages/schema/src/config/cli.ts index 287873d998..93bb421980 100644 --- a/packages/schema/src/config/cli.ts +++ b/packages/schema/src/config/cli.ts @@ -1,4 +1,6 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** * Add a message to the CLI banner by adding a string to this array. * @type {string[]} @@ -11,4 +13,4 @@ export default { * @version 2 */ bannerColor: 'green' -} +}) diff --git a/packages/schema/src/config/experimental.ts b/packages/schema/src/config/experimental.ts index 8dbf76b482..491cb3f82f 100644 --- a/packages/schema/src/config/experimental.ts +++ b/packages/schema/src/config/experimental.ts @@ -1,11 +1,13 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** @version 3 */ experimental: { /** * Set to true to generate an async entry point for the Vue bundle (for module federation support). */ asyncEntry: { - $resolve: (val, get) => val ?? false + $resolve: (val) => val ?? false }, /** @@ -51,4 +53,4 @@ export default { */ viteServerDynamicImports: true } -} +}) diff --git a/packages/schema/src/config/generate.ts b/packages/schema/src/config/generate.ts index b881d6b330..ea41f9c072 100644 --- a/packages/schema/src/config/generate.ts +++ b/packages/schema/src/config/generate.ts @@ -1,10 +1,11 @@ import { resolve } from 'pathe' import { joinURL } from 'ufo' +import { SchemaDefinition } from 'untyped' /** * @version 2 */ -export default { + export default { /** * Directory name that holds all the assets and generated pages for a `static` build. */ @@ -160,10 +161,16 @@ export default { * The full path to the directory underneath `/_nuxt/` where static assets * (payload, state and manifest files) will live. */ - base: { $resolve: (val, get) => val || joinURL(get('app').buildAssetsDir, get('generate.dir')) }, - /** The full path to the versioned directory where static assets for the current buidl are located. */ - versionBase: { $resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version')) }, + base: { + $resolve: (val, get) => val || joinURL(get('app').buildAssetsDir, get('generate.dir')) + }, + /** The full path to the versioned directory where static assets for the current build are located. */ + versionBase: { + $resolve: (val, get) => val || joinURL(get('generate.base'), get('generate.version')) + }, /** A unique string to uniquely identify payload versions (defaults to the current timestamp). */ - version: { $resolve: val => val || (String(Math.round(Date.now() / 1000))) } + version: { + $resolve: val => val || (String(Math.round(Date.now() / 1000))) + } } } diff --git a/packages/schema/src/config/messages.ts b/packages/schema/src/config/messages.ts index 8bc2beb420..f6eff563b5 100644 --- a/packages/schema/src/config/messages.ts +++ b/packages/schema/src/config/messages.ts @@ -1,7 +1,9 @@ +import { SchemaDefinition } from 'untyped' + /** * @version 2 */ -export default { +export default { /** The text that displays on the Nuxt loading indicator when `ssr: false`. */ loading: 'Loading...', /** The 404 text on the default Nuxt error page. */ diff --git a/packages/schema/src/config/nitro.ts b/packages/schema/src/config/nitro.ts index d6828e11d1..091bee65ae 100644 --- a/packages/schema/src/config/nitro.ts +++ b/packages/schema/src/config/nitro.ts @@ -1,4 +1,6 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** * Configuration for Nitro. * @@ -31,4 +33,4 @@ export default { * @version 3 */ devServerHandlers: [] -} +}) diff --git a/packages/schema/src/config/postcss.ts b/packages/schema/src/config/postcss.ts index 60edb87784..d2f03632d2 100644 --- a/packages/schema/src/config/postcss.ts +++ b/packages/schema/src/config/postcss.ts @@ -1,7 +1,8 @@ import defu from 'defu' import createResolver from 'postcss-import-resolver' +import { defineUntypedSchema } from 'untyped' -export default { +export default defineUntypedSchema({ /** @version 3 */ postcss: { /** Path to postcss config file. */ @@ -51,4 +52,4 @@ export default { } } } -} +}) diff --git a/packages/schema/src/config/render.ts b/packages/schema/src/config/render.ts index 7f71aca9c5..203ebc4e0f 100644 --- a/packages/schema/src/config/render.ts +++ b/packages/schema/src/config/render.ts @@ -1,7 +1,9 @@ +import { SchemaDefinition } from 'untyped' + /** * @version 2 */ -export default { +export default { /** * Use this option to customize the Vue SSR bundle renderer. * This option is skipped if `ssr: false`. @@ -10,9 +12,11 @@ export default { */ bundleRenderer: { shouldPrefetch: () => false, - shouldPreload: (_fileWithoutQuery, asType) => ['script', 'style'].includes(asType), + shouldPreload: (_fileWithoutQuery: string, asType: string) => ['script', 'style'].includes(asType), /** enabled by default for development */ - runInNewContext: { $resolve: (val, get) => val ?? get('dev') } + runInNewContext: { + $resolve: (val, get) => val ?? get('dev') + } }, /** @@ -41,7 +45,9 @@ export default { * * Set to `collapsed` to collapse the logs, or `false` to disable. */ - ssrLog: { $resolve: (val, get) => get('dev') ? Boolean(val) : false }, + ssrLog: { + $resolve: (val, get) => get('dev') ? Boolean(val) : false + }, /** * Configuration for HTTP2 push headers. diff --git a/packages/schema/src/config/router.ts b/packages/schema/src/config/router.ts index 2ac691d3f8..6a895654dd 100644 --- a/packages/schema/src/config/router.ts +++ b/packages/schema/src/config/router.ts @@ -1,6 +1,7 @@ import { normalizeURL, withTrailingSlash } from 'ufo' +import { defineUntypedSchema } from 'untyped' -export default { +export default defineUntypedSchema({ /** * Additional options passed to `vue-router`. * @@ -168,4 +169,4 @@ export default { * @version 2 */ trailingSlash: undefined -} +}) diff --git a/packages/schema/src/config/server.ts b/packages/schema/src/config/server.ts index 973d63a40e..51ebed8c4b 100644 --- a/packages/schema/src/config/server.ts +++ b/packages/schema/src/config/server.ts @@ -1,5 +1,7 @@ +import { SchemaDefinition } from 'untyped' + /** @version 2 */ -export default { +export default { /** * Whether to enable HTTPS. * diff --git a/packages/schema/src/config/typescript.ts b/packages/schema/src/config/typescript.ts index ad4c77e11f..7b3c7d185e 100644 --- a/packages/schema/src/config/typescript.ts +++ b/packages/schema/src/config/typescript.ts @@ -1,4 +1,6 @@ -export default { +import { defineUntypedSchema } from 'untyped' + +export default defineUntypedSchema({ /** * Configuration for Nuxt's TypeScript integration. * @@ -35,4 +37,4 @@ export default { */ shim: true } -} +}) diff --git a/packages/schema/src/config/vite.ts b/packages/schema/src/config/vite.ts index 0a194fa57a..e5feca1a01 100644 --- a/packages/schema/src/config/vite.ts +++ b/packages/schema/src/config/vite.ts @@ -1,7 +1,8 @@ import { resolve } from 'pathe' import { withoutLeadingSlash } from 'ufo' +import { defineUntypedSchema } from 'untyped' -export default { +export default defineUntypedSchema({ /** * Configuration that will be passed directly to Vite. * @@ -45,7 +46,7 @@ export default { exclude: { $resolve: (val, get) => [ ...val || [], - ...get('build.transpile').filter((i) => typeof i === 'string'), + ...get('build.transpile').filter((i: string) => typeof i === 'string'), 'vue-demi' ] } @@ -77,4 +78,4 @@ export default { } } } -} +}) diff --git a/packages/schema/src/config/webpack.ts b/packages/schema/src/config/webpack.ts index 15d40baf3e..42c6830aab 100644 --- a/packages/schema/src/config/webpack.ts +++ b/packages/schema/src/config/webpack.ts @@ -1,6 +1,7 @@ import { join } from 'pathe' +import { defineUntypedSchema } from 'untyped' -export default { +export default defineUntypedSchema({ /** @version 3 */ webpack: { /** @@ -122,12 +123,12 @@ export default { * ``` */ filenames: { - app: ({ isDev }) => isDev ? `[name].js` : `[contenthash:7].js`, - chunk: ({ isDev }) => isDev ? `[name].js` : `[contenthash:7].js`, - css: ({ isDev }) => isDev ? '[name].css' : 'css/[contenthash:7].css', - img: ({ isDev }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]', - font: ({ isDev }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', - video: ({ isDev }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]' + app: ({ isDev }: { isDev: boolean }) => isDev ? `[name].js` : `[contenthash:7].js`, + chunk: ({ isDev }: { isDev: boolean }) => isDev ? `[name].js` : `[contenthash:7].js`, + css: ({ isDev }: { isDev: boolean }) => isDev ? '[name].css' : 'css/[contenthash:7].css', + img: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'img/[name].[contenthash:7].[ext]', + font: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'fonts/[name].[contenthash:7].[ext]', + video: ({ isDev }: { isDev: boolean }) => isDev ? '[path][name].[ext]' : 'videos/[name].[contenthash:7].[ext]' }, /** @@ -297,4 +298,4 @@ export default { */ warningIgnoreFilters: [], } -} +}) diff --git a/packages/schema/src/types/module.ts b/packages/schema/src/types/module.ts index f963478b20..1a410fbe41 100644 --- a/packages/schema/src/types/module.ts +++ b/packages/schema/src/types/module.ts @@ -71,10 +71,10 @@ export interface ModuleContainer { addServerMiddleware(arg1: any): void /** Allows extending webpack build config by chaining `options.build.extend` function. */ - extendBuild(fn): void + extendBuild(fn: Function): void /** Allows extending routes by chaining `options.router.extendRoutes` function. */ - extendRoutes(fn): void + extendRoutes(fn: Function): void /** Registers a module. */ requireModule(installOptions: any, opts: any): Promise diff --git a/packages/test-utils/src/browser.ts b/packages/test-utils/src/browser.ts index 03a005fc8e..1fe15c77cf 100644 --- a/packages/test-utils/src/browser.ts +++ b/packages/test-utils/src/browser.ts @@ -31,7 +31,7 @@ export async function getBrowser (): Promise { if (!ctx.browser) { await createBrowser() } - return ctx.browser + return ctx.browser! } export async function createPage (path?: string, options?: BrowserContextOptions) { diff --git a/packages/test-utils/src/context.ts b/packages/test-utils/src/context.ts index 85bff696d2..3a09ecab5f 100644 --- a/packages/test-utils/src/context.ts +++ b/packages/test-utils/src/context.ts @@ -2,7 +2,7 @@ import { resolve } from 'node:path' import defu from 'defu' import type { TestContext, TestOptions, TestRunner } from './types' -let currentContext: TestContext +let currentContext: TestContext | undefined export function createTestContext (options: Partial): TestContext { const _options: Partial = defu(options, { @@ -18,7 +18,7 @@ export function createTestContext (options: Partial): TestContext { // TODO: auto detect based on process.env runner: 'vitest', browserOptions: { - type: 'chromium' + type: 'chromium' as const } }) @@ -32,7 +32,9 @@ export function useTestContext (): TestContext { return currentContext } -export function setTestContext (context: TestContext): TestContext { +export function setTestContext (context: TestContext): TestContext +export function setTestContext (context?: TestContext): TestContext | undefined +export function setTestContext (context?: TestContext): TestContext | undefined { currentContext = context return currentContext } diff --git a/packages/test-utils/src/nuxt.ts b/packages/test-utils/src/nuxt.ts index b50ac34a94..fe022b34cd 100644 --- a/packages/test-utils/src/nuxt.ts +++ b/packages/test-utils/src/nuxt.ts @@ -64,5 +64,5 @@ export async function loadFixture () { export async function buildFixture () { const ctx = useTestContext() - await kit.buildNuxt(ctx.nuxt) + await kit.buildNuxt(ctx.nuxt!) } diff --git a/packages/test-utils/src/run.ts b/packages/test-utils/src/run.ts index c594e0c6df..094b14845d 100644 --- a/packages/test-utils/src/run.ts +++ b/packages/test-utils/src/run.ts @@ -21,6 +21,7 @@ export async function runTests (opts: RunTestOptions) { process.env.NUXT_TEST_DEV = 'true' } + // @ts-ignore missing types const { startVitest } = await import('vitest/dist/node.mjs') const succeeded = await startVitest( [] /* argv */, diff --git a/packages/test-utils/src/server.ts b/packages/test-utils/src/server.ts index 20e16641a0..a67ec4eec5 100644 --- a/packages/test-utils/src/server.ts +++ b/packages/test-utils/src/server.ts @@ -16,7 +16,7 @@ export async function startServer () { if (ctx.options.dev) { const nuxiCLI = await kit.resolvePath('nuxi/cli') ctx.serverProcess = execa(nuxiCLI, ['dev'], { - cwd: ctx.nuxt.options.rootDir, + cwd: ctx.nuxt!.options.rootDir, stdio: 'inherit', env: { ...process.env, @@ -37,7 +37,7 @@ export async function startServer () { throw new Error('Timeout waiting for dev server!') } else { ctx.serverProcess = execa('node', [ - resolve(ctx.nuxt.options.nitro.output.dir, 'server/index.mjs') + resolve(ctx.nuxt!.options.nitro.output!.dir!, 'server/index.mjs') ], { stdio: 'inherit', env: { diff --git a/packages/vite/tsconfig.json b/packages/vite/tsconfig.json deleted file mode 100644 index 35a35f0192..0000000000 --- a/packages/vite/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "strict": true, - "noImplicitAny": true - }, - "include": [ - "./src/**/*.ts", - "./test/**/*.ts" - ] -} diff --git a/packages/webpack/package.json b/packages/webpack/package.json index f63b32d2ed..58bf31e4dd 100644 --- a/packages/webpack/package.json +++ b/packages/webpack/package.json @@ -58,6 +58,7 @@ }, "devDependencies": { "@nuxt/schema": "3.0.0-rc.8", + "@types/lodash-es": "^4.17.6", "@types/pify": "^5.0.1", "@types/webpack-bundle-analyzer": "^4.4.2", "@types/webpack-dev-middleware": "^5.0.2", diff --git a/packages/webpack/src/configs/client.ts b/packages/webpack/src/configs/client.ts index cde0f7cf89..e817e577c6 100644 --- a/packages/webpack/src/configs/client.ts +++ b/packages/webpack/src/configs/client.ts @@ -68,6 +68,7 @@ function clientHMR (ctx: WebpackConfigContext) { `webpack-hot-middleware/client?${hotMiddlewareClientOptionsStr}` ) + config.plugins = config.plugins || [] config.plugins.push(new webpack.HotModuleReplacementPlugin()) } diff --git a/packages/webpack/src/configs/server.ts b/packages/webpack/src/configs/server.ts index f84e031be8..a5fae9ceb1 100644 --- a/packages/webpack/src/configs/server.ts +++ b/packages/webpack/src/configs/server.ts @@ -26,7 +26,7 @@ export function server (ctx: WebpackConfigContext) { function serverPreset (ctx: WebpackConfigContext) { const { config } = ctx - config.output.filename = 'server.mjs' + config.output!.filename = 'server.mjs' config.devtool = 'cheap-module-source-map' config.optimization = { @@ -53,8 +53,11 @@ function serverStandalone (ctx: WebpackConfigContext) { if (!Array.isArray(ctx.config.externals)) { return } ctx.config.externals.push(({ request }, cb) => { + if (!request) { + return cb(undefined, false) + } if (external.includes(request)) { - return cb(null, true) + return cb(undefined, true) } if ( request[0] === '.' || @@ -63,16 +66,18 @@ function serverStandalone (ctx: WebpackConfigContext) { assetPattern.test(request) ) { // console.log('Inline', request) - return cb(null, false) + return cb(undefined, false) } // console.log('Ext', request) - return cb(null, true) + return cb(undefined, true) }) } function serverPlugins (ctx: WebpackConfigContext) { const { config, options } = ctx + config.plugins = config.plugins || [] + // Server polyfills if (options.webpack.serverURLPolyfill) { config.plugins.push(new webpack.ProvidePlugin({ @@ -83,6 +88,6 @@ function serverPlugins (ctx: WebpackConfigContext) { // Add type-checking if (ctx.nuxt.options.typescript.typeCheck === true || (ctx.nuxt.options.typescript.typeCheck === 'build' && !ctx.nuxt.options.dev)) { - ctx.config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger })) + config.plugins.push(new ForkTSCheckerWebpackPlugin({ logger })) } } diff --git a/packages/webpack/src/plugins/dynamic-base.ts b/packages/webpack/src/plugins/dynamic-base.ts index 8fd6ccf9c1..b51506de06 100644 --- a/packages/webpack/src/plugins/dynamic-base.ts +++ b/packages/webpack/src/plugins/dynamic-base.ts @@ -24,7 +24,9 @@ export const DynamicBasePlugin = createUnplugin((options: DynamicBasePluginOptio s.append(`${options.globalPublicPath} = buildAssetsURL();\n`) return { code: s.toString(), - map: options.sourcemap && s.generateMap({ source: id, includeContent: true }) + map: options.sourcemap + ? s.generateMap({ source: id, includeContent: true }) + : undefined } } } diff --git a/packages/webpack/src/plugins/vue/client.ts b/packages/webpack/src/plugins/vue/client.ts index de8259996b..0cb12426dd 100644 --- a/packages/webpack/src/plugins/vue/client.ts +++ b/packages/webpack/src/plugins/vue/client.ts @@ -10,6 +10,7 @@ import { uniq } from 'lodash-es' import fse from 'fs-extra' import type { Nuxt } from '@nuxt/schema' +import type { Compilation, Compiler } from 'webpack' import { isJS, isCSS, isHotUpdate } from './util' interface PluginOptions { @@ -26,17 +27,17 @@ export default class VueSSRClientPlugin { }, options) } - apply (compiler) { - compiler.hooks.afterEmit.tap('VueSSRClientPlugin', async (compilation: any) => { + apply (compiler: Compiler) { + compiler.hooks.afterEmit.tap('VueSSRClientPlugin', async (compilation: Compilation) => { const stats = compilation.getStats().toJson() - const allFiles = uniq(stats.assets + const allFiles = uniq(stats.assets! .map(a => a.name)) .filter(file => !isHotUpdate(file)) - const initialFiles = uniq(Object.keys(stats.entrypoints) - .map(name => stats.entrypoints[name].assets) - .reduce((files, entryAssets) => files.concat(entryAssets.map(entryAsset => entryAsset.name)), []) + const initialFiles = uniq(Object.keys(stats.entrypoints!) + .map(name => stats.entrypoints![name].assets!) + .reduce((files, entryAssets) => files.concat(entryAssets.map(entryAsset => entryAsset.name)), [] as string[]) .filter(file => isJS(file) || isCSS(file))) .filter(file => !isHotUpdate(file)) @@ -45,11 +46,11 @@ export default class VueSSRClientPlugin { .filter(file => !initialFiles.includes(file)) .filter(file => !isHotUpdate(file)) - const assetsMapping = {} - stats.assets + const assetsMapping: Record = {} + stats.assets! .filter(({ name }) => isJS(name)) .filter(({ name }) => !isHotUpdate(name)) - .forEach(({ name, chunkNames }) => { + .forEach(({ name, chunkNames = [] }) => { const componentHash = hash(chunkNames.join('|')) if (!assetsMapping[componentHash]) { assetsMapping[componentHash] = [] @@ -62,29 +63,29 @@ export default class VueSSRClientPlugin { all: allFiles, initial: initialFiles, async: asyncFiles, - modules: { /* [identifier: string]: Array */ }, + modules: { /* [identifier: string]: Array */ } as Record, assetsMapping } - const { entrypoints, namedChunkGroups } = stats - const assetModules = stats.modules.filter(m => m.assets.length) - const fileToIndex = file => webpackManifest.all.indexOf(file) - stats.modules.forEach((m) => { + const { entrypoints = {}, namedChunkGroups = {} } = stats + const assetModules = stats.modules!.filter(m => m.assets!.length) + const fileToIndex = (file: string) => webpackManifest.all.indexOf(file) + stats.modules!.forEach((m) => { // Ignore modules duplicated in multiple chunks - if (m.chunks.length === 1) { - const [cid] = m.chunks - const chunk = stats.chunks.find(c => c.id === cid) + if (m.chunks!.length === 1) { + const [cid] = m.chunks! + const chunk = stats.chunks!.find(c => c.id === cid) if (!chunk || !chunk.files) { return } - const id = m.identifier.replace(/\s\w+$/, '') // remove appended hash + const id = m.identifier!.replace(/\s\w+$/, '') // remove appended hash const filesSet = new Set(chunk.files.map(fileToIndex).filter(i => i !== -1)) - for (const chunkName of chunk.names) { + for (const chunkName of chunk.names!) { if (!entrypoints[chunkName]) { const chunkGroup = namedChunkGroups[chunkName] if (chunkGroup) { - for (const asset of chunkGroup.assets) { + for (const asset of chunkGroup.assets!) { filesSet.add(fileToIndex(asset.name)) } } @@ -98,7 +99,7 @@ export default class VueSSRClientPlugin { // Include ConcatenatedModule for not losing module-component mapping if (Array.isArray(m.modules)) { for (const concatenatedModule of m.modules) { - const id = hash(concatenatedModule.identifier.replace(/\s\w+$/, '')) + const id = hash(concatenatedModule.identifier!.replace(/\s\w+$/, '')) if (!webpackManifest.modules[id]) { webpackManifest.modules[id] = files } @@ -107,14 +108,14 @@ export default class VueSSRClientPlugin { // Find all asset modules associated with the same chunk assetModules.forEach((m) => { - if (m.chunks.includes(cid)) { - files.push.apply(files, m.assets.map(fileToIndex)) + if (m.chunks!.includes(cid)) { + files.push.apply(files, (m.assets as string[]).map(fileToIndex)) } }) } }) - const manifest = normalizeWebpackManifest(webpackManifest) + const manifest = normalizeWebpackManifest(webpackManifest as any) await this.options.nuxt.callHook('build:manifest', manifest) const src = JSON.stringify(manifest, null, 2) diff --git a/packages/webpack/src/plugins/vue/server.ts b/packages/webpack/src/plugins/vue/server.ts index e9bd1ee311..bc5769b5e8 100644 --- a/packages/webpack/src/plugins/vue/server.ts +++ b/packages/webpack/src/plugins/vue/server.ts @@ -1,35 +1,36 @@ - -import webpack from 'webpack' +import webpack, { Compilation, Compiler } from 'webpack' import { validate, isJS, extractQueryPartJS } from './util' -export default class VueSSRServerPlugin { - options: { - filename?: string - } +export interface VueSSRServerPluginOptions { + filename: string +} - constructor (options = {}) { +export default class VueSSRServerPlugin { + options: VueSSRServerPluginOptions + + constructor (options: Partial = {}) { this.options = Object.assign({ filename: null - }, options) + }, options) as VueSSRServerPluginOptions } - apply (compiler) { + apply (compiler: Compiler) { validate(compiler) - compiler.hooks.make.tap('VueSSRServerPlugin', (compilation: any) => { + compiler.hooks.make.tap('VueSSRServerPlugin', (compilation: Compilation) => { compilation.hooks.processAssets.tapAsync({ name: 'VueSSRServerPlugin', stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONAL - }, (assets, cb) => { + }, (assets: any, cb: any) => { const stats = compilation.getStats().toJson() - const [entryName] = Object.keys(stats.entrypoints) - const entryInfo = stats.entrypoints[entryName] + const [entryName] = Object.keys(stats.entrypoints!) + const entryInfo = stats.entrypoints![entryName] if (!entryInfo) { // #5553 return cb() } - const entryAssets = entryInfo.assets.filter(asset => isJS(asset.name)) + const entryAssets = entryInfo.assets!.filter((asset: { name:string }) => isJS(asset.name)) if (entryAssets.length > 1) { throw new Error( @@ -47,11 +48,11 @@ export default class VueSSRServerPlugin { const bundle = { entry: entry.name, - files: {}, - maps: {} + files: {} as Record, + maps: {} as Record } - stats.assets.forEach((asset) => { + stats.assets!.forEach((asset: any) => { if (isJS(asset.name)) { const queryPart = extractQueryPartJS(asset.name) if (queryPart !== undefined) { diff --git a/packages/webpack/src/plugins/vue/util.ts b/packages/webpack/src/plugins/vue/util.ts index 7a092f2a9c..590d6ceec2 100644 --- a/packages/webpack/src/plugins/vue/util.ts +++ b/packages/webpack/src/plugins/vue/util.ts @@ -4,8 +4,9 @@ */ import { logger } from '@nuxt/kit' +import type { Compiler } from 'webpack' -export const validate = (compiler) => { +export const validate = (compiler: Compiler) => { if (compiler.options.target !== 'node') { logger.warn('webpack config `target` should be "node".') } @@ -20,10 +21,10 @@ export const validate = (compiler) => { const isJSRegExp = /\.[cm]?js(\?[^.]+)?$/ -export const isJS = file => isJSRegExp.test(file) +export const isJS = (file: string) => isJSRegExp.test(file) -export const extractQueryPartJS = file => isJSRegExp.exec(file)[1] +export const extractQueryPartJS = (file: string) => isJSRegExp.exec(file)?.[1] -export const isCSS = file => /\.css(\?[^.]+)?$/.test(file) +export const isCSS = (file: string) => /\.css(\?[^.]+)?$/.test(file) -export const isHotUpdate = file => file.includes('hot-update') +export const isHotUpdate = (file: string) => file.includes('hot-update') diff --git a/packages/webpack/src/presets/assets.ts b/packages/webpack/src/presets/assets.ts index 15a52ad7b2..9f588fd331 100644 --- a/packages/webpack/src/presets/assets.ts +++ b/packages/webpack/src/presets/assets.ts @@ -1,7 +1,7 @@ import { fileName, WebpackConfigContext } from '../utils/config' export function assets (ctx: WebpackConfigContext) { - ctx.config.module.rules.push( + ctx.config.module!.rules!.push( { test: /\.(png|jpe?g|gif|svg|webp)$/i, use: [{ diff --git a/packages/webpack/src/presets/base.ts b/packages/webpack/src/presets/base.ts index 171eeeb3bc..e57d7bf004 100644 --- a/packages/webpack/src/presets/base.ts +++ b/packages/webpack/src/presets/base.ts @@ -1,8 +1,10 @@ import { resolve, normalize } from 'pathe' +// @ts-expect-error missing types import TimeFixPlugin from 'time-fix-plugin' import WebpackBar from 'webpackbar' import webpack from 'webpack' import { logger } from '@nuxt/kit' +// @ts-expect-error missing types import FriendlyErrorsWebpackPlugin from '@nuxt/friendly-errors-webpack-plugin' import escapeRegExp from 'escape-string-regexp' import { joinURL } from 'ufo' @@ -44,6 +46,8 @@ function baseConfig (ctx: WebpackConfigContext) { function basePlugins (ctx: WebpackConfigContext) { const { config, options, nuxt } = ctx + config.plugins = config.plugins || [] + // Add timefix-plugin before other plugins if (options.dev) { config.plugins.push(new TimeFixPlugin()) @@ -63,7 +67,7 @@ function basePlugins (ctx: WebpackConfigContext) { ctx.isServer || (ctx.isDev && !options.build.quiet && options.webpack.friendlyErrors) ) { - ctx.config.plugins.push( + config.plugins.push( new FriendlyErrorsWebpackPlugin({ clearConsole: false, reporter: 'consola', @@ -81,16 +85,17 @@ function basePlugins (ctx: WebpackConfigContext) { } config.plugins.push(new WebpackBar({ name: ctx.name, - color: colors[ctx.name], + color: colors[ctx.name as keyof typeof colors], reporters: ['stats'], stats: !ctx.isDev, reporter: { - // @ts-ignore + // @ts-ignore change: (_, { shortPath }) => { if (!ctx.isServer) { nuxt.callHook('bundler:change', shortPath) } }, + // @ts-ignore done: ({ state }) => { if (state.hasErrors) { nuxt.callHook('bundler:error') @@ -101,6 +106,7 @@ function basePlugins (ctx: WebpackConfigContext) { allDone: () => { nuxt.callHook('bundler:done') }, + // @ts-ignore progress ({ statesArray }) { nuxt.callHook('bundler:progress', statesArray) } @@ -220,7 +226,7 @@ function getWarningIgnoreFilter (ctx: WebpackConfigContext): WarningFilter { function getEnv (ctx: WebpackConfigContext) { const { options } = ctx - const _env = { + const _env: Record = { 'process.env.NODE_ENV': JSON.stringify(ctx.config.mode), 'process.mode': JSON.stringify(ctx.config.mode), 'process.dev': options.dev, @@ -239,7 +245,7 @@ function getEnv (ctx: WebpackConfigContext) { Object.entries(options.env).forEach(([key, value]) => { const isNative = ['boolean', 'number'].includes(typeof value) - _env['process.env.' + key] = isNative ? value : JSON.stringify(value) + _env['process.env.' + key] = isNative ? value as string : JSON.stringify(value) }) return _env diff --git a/packages/webpack/src/presets/esbuild.ts b/packages/webpack/src/presets/esbuild.ts index 494282144c..e78c514722 100644 --- a/packages/webpack/src/presets/esbuild.ts +++ b/packages/webpack/src/presets/esbuild.ts @@ -10,9 +10,9 @@ export function esbuild (ctx: WebpackConfigContext) { const target = ctx.isServer ? 'es2019' : 'chrome85' // https://github.com/nuxt/framework/issues/2372 - config.optimization.minimizer.push(new (esbuildLoader as unknown as typeof import('esbuild-loader')).ESBuildMinifyPlugin()) + config.optimization!.minimizer!.push(new (esbuildLoader as unknown as typeof import('esbuild-loader')).ESBuildMinifyPlugin()) - config.module.rules.push( + config.module!.rules!.push( { test: /\.m?[jt]s$/i, loader: 'esbuild-loader', diff --git a/packages/webpack/src/presets/node.ts b/packages/webpack/src/presets/node.ts index 4f1fd4a9ce..b5d584c6e4 100644 --- a/packages/webpack/src/presets/node.ts +++ b/packages/webpack/src/presets/node.ts @@ -6,7 +6,7 @@ export function node (ctx: WebpackConfigContext) { config.target = 'node' config.node = false - config.experiments.outputModule = true + config.experiments!.outputModule = true config.output = { ...config.output, diff --git a/packages/webpack/src/presets/pug.ts b/packages/webpack/src/presets/pug.ts index 2cccf5867b..2a414a28c9 100644 --- a/packages/webpack/src/presets/pug.ts +++ b/packages/webpack/src/presets/pug.ts @@ -1,7 +1,7 @@ import { WebpackConfigContext } from '../utils/config' export function pug (ctx: WebpackConfigContext) { - ctx.config.module.rules.push({ + ctx.config.module!.rules!.push({ test: /\.pug$/i, oneOf: [ { diff --git a/packages/webpack/src/presets/style.ts b/packages/webpack/src/presets/style.ts index d51609a509..5a5d39efe5 100644 --- a/packages/webpack/src/presets/style.ts +++ b/packages/webpack/src/presets/style.ts @@ -14,8 +14,8 @@ export function style (ctx: WebpackConfigContext) { function minimizer (ctx: WebpackConfigContext) { const { options, config } = ctx - if (options.webpack.optimizeCSS && Array.isArray(config.optimization.minimizer)) { - config.optimization.minimizer.push(new CssMinimizerPlugin({ + if (options.webpack.optimizeCSS && Array.isArray(config.optimization!.minimizer)) { + config.optimization!.minimizer.push(new CssMinimizerPlugin({ ...options.webpack.optimizeCSS })) } @@ -26,7 +26,7 @@ function extractCSS (ctx: WebpackConfigContext) { // CSS extraction if (options.webpack.extractCSS) { - config.plugins.push(new MiniCssExtractPlugin({ + config.plugins!.push(new MiniCssExtractPlugin({ filename: fileName(ctx, 'css'), chunkFilename: fileName(ctx, 'css'), ...options.webpack.extractCSS === true ? {} : options.webpack.extractCSS @@ -38,28 +38,28 @@ function loaders (ctx: WebpackConfigContext) { const { config, options } = ctx // CSS - config.module.rules.push(createdStyleRule('css', /\.css$/i, null, ctx)) + config.module!.rules!.push(createdStyleRule('css', /\.css$/i, null, ctx)) // Postcss - config.module.rules.push(createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx)) + config.module!.rules!.push(createdStyleRule('postcss', /\.p(ost)?css$/i, null, ctx)) // Less const lessLoader = { loader: 'less-loader', options: options.webpack.loaders.less } - config.module.rules.push(createdStyleRule('less', /\.less$/i, lessLoader, ctx)) + config.module!.rules!.push(createdStyleRule('less', /\.less$/i, lessLoader, ctx)) // Sass (TODO: optional dependency) const sassLoader = { loader: 'sass-loader', options: options.webpack.loaders.sass } - config.module.rules.push(createdStyleRule('sass', /\.sass$/i, sassLoader, ctx)) + config.module!.rules!.push(createdStyleRule('sass', /\.sass$/i, sassLoader, ctx)) const scssLoader = { loader: 'sass-loader', options: options.webpack.loaders.scss } - config.module.rules.push(createdStyleRule('scss', /\.scss$/i, scssLoader, ctx)) + config.module!.rules!.push(createdStyleRule('scss', /\.scss$/i, scssLoader, ctx)) // Stylus const stylusLoader = { loader: 'stylus-loader', options: options.webpack.loaders.stylus } - config.module.rules.push(createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx)) + config.module!.rules!.push(createdStyleRule('stylus', /\.styl(us)?$/i, stylusLoader, ctx)) } -function createdStyleRule (lang: string, test: RegExp, processorLoader, ctx: WebpackConfigContext) { +function createdStyleRule (lang: string, test: RegExp, processorLoader: any, ctx: WebpackConfigContext) { const { options } = ctx const styleLoaders = [ @@ -90,7 +90,7 @@ function createdStyleRule (lang: string, test: RegExp, processorLoader, ctx: Web } } -function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions) { +function createCssLoadersRule (ctx: WebpackConfigContext, cssLoaderOptions: any) { const { options } = ctx const cssLoader = { loader: 'css-loader', options: cssLoaderOptions } diff --git a/packages/webpack/src/presets/vue.ts b/packages/webpack/src/presets/vue.ts index 8032e696b8..b81e277f79 100644 --- a/packages/webpack/src/presets/vue.ts +++ b/packages/webpack/src/presets/vue.ts @@ -11,7 +11,7 @@ export function vue (ctx: WebpackConfigContext) { // @ts-ignore config.plugins.push(new (VueLoaderPlugin.default || VueLoaderPlugin)()) - config.module.rules.push({ + config.module!.rules!.push({ test: /\.vue$/i, loader: 'vue-loader', options: { @@ -21,12 +21,12 @@ export function vue (ctx: WebpackConfigContext) { }) if (ctx.isClient) { - config.plugins.push(new VueSSRClientPlugin({ + config.plugins!.push(new VueSSRClientPlugin({ filename: resolve(options.buildDir, 'dist/server', `${ctx.name}.manifest.json`), nuxt: ctx.nuxt })) } else { - config.plugins.push(new VueSSRServerPlugin({ + config.plugins!.push(new VueSSRServerPlugin({ filename: `${ctx.name}.manifest.json` })) } @@ -34,7 +34,7 @@ export function vue (ctx: WebpackConfigContext) { // Feature flags // https://github.com/vuejs/vue-next/tree/master/packages/vue#bundler-build-feature-flags // TODO: Provide options to toggle - config.plugins.push(new webpack.DefinePlugin({ + config.plugins!.push(new webpack.DefinePlugin({ __VUE_OPTIONS_API__: 'true', __VUE_PROD_DEVTOOLS__: 'false' })) diff --git a/packages/webpack/src/utils/config.ts b/packages/webpack/src/utils/config.ts index ac0415c889..1e70520a67 100644 --- a/packages/webpack/src/utils/config.ts +++ b/packages/webpack/src/utils/config.ts @@ -19,7 +19,7 @@ export function createWebpackConfigContext (nuxt: Nuxt) { isServer: false, isClient: false, - alias: {} as Configuration['resolve']['alias'], + alias: {} as { [index: string]: string | false | string[] }, transpile: [] as RegExp[] } } @@ -40,7 +40,7 @@ export function applyPresets (ctx: WebpackConfigContext, presets: WebpackConfigP export function fileName (ctx: WebpackConfigContext, key: string) { const { options } = ctx - let fileName = options.webpack.filenames[key] + let fileName = options.webpack.filenames[key as keyof typeof options.webpack.filenames] as ((ctx: WebpackConfigContext) => string) | string if (typeof fileName === 'function') { fileName = fileName(ctx) @@ -61,7 +61,7 @@ export function getWebpackConfig (ctx: WebpackConfigContext): Configuration { // TODO const builder = {} - const loaders = [] + const loaders: any[] = [] // @ts-ignore const { extend } = options.build diff --git a/packages/webpack/src/utils/mfs.ts b/packages/webpack/src/utils/mfs.ts index 4df4d4ecc9..06239d6981 100644 --- a/packages/webpack/src/utils/mfs.ts +++ b/packages/webpack/src/utils/mfs.ts @@ -9,7 +9,7 @@ export function createMFS () { const fs = createFsFromVolume(new Volume()) // Clone to extend - const _fs: Partial & { join?(...paths: string[]): string } = { ...fs } + const _fs: IFs & { join?(...paths: string[]): string } = { ...fs } as any // fs.join method is (still) expected by webpack-dev-middleware // There might be differences with https://github.com/webpack/memory-fs/blob/master/lib/join.js diff --git a/packages/webpack/src/utils/postcss.ts b/packages/webpack/src/utils/postcss.ts index b04566777c..badf932a8e 100644 --- a/packages/webpack/src/utils/postcss.ts +++ b/packages/webpack/src/utils/postcss.ts @@ -35,20 +35,20 @@ export const getPostcssConfig = (nuxt: Nuxt) => { } } - function sortPlugins ({ plugins, order }) { + function sortPlugins ({ plugins, order }: any) { const names = Object.keys(plugins) if (typeof order === 'string') { - order = orderPresets[order] + order = orderPresets[order as keyof typeof orderPresets] } return typeof order === 'function' ? order(names, orderPresets) : (order || names) } - function loadPlugins (config) { + function loadPlugins (config: any) { if (!isPureObject(config.plugins)) { return } // Map postcss plugins into instances on object mode once const cjs = createCommonJS(import.meta.url) - config.plugins = sortPlugins(config).map((pluginName) => { + config.plugins = sortPlugins(config).map((pluginName: string) => { const pluginFn = requireModule(pluginName, { paths: [cjs.__dirname] }) const pluginOptions = config.plugins[pluginName] if (!pluginOptions || typeof pluginFn !== 'function') { return null } @@ -81,9 +81,11 @@ export const getPostcssConfig = (nuxt: Nuxt) => { loadPlugins(postcssOptions) } + // @ts-expect-error delete nuxt.options.webpack.postcss.order return { + // @ts-expect-error sourceMap: nuxt.options.webpack.cssSourceMap, ...nuxt.options.webpack.postcss, postcssOptions diff --git a/packages/webpack/src/virtual-modules.ts b/packages/webpack/src/virtual-modules.ts index 688690b2a3..068f9e0fbc 100644 --- a/packages/webpack/src/virtual-modules.ts +++ b/packages/webpack/src/virtual-modules.ts @@ -21,6 +21,6 @@ export function registerVirtualModules () { nuxt.hook('webpack:config', configs => configs.forEach((config) => { // Support virtual modules (input) - config.plugins.push(virtualModules) + config.plugins!.push(virtualModules) })) } diff --git a/packages/webpack/src/webpack.ts b/packages/webpack/src/webpack.ts index 0952f56d44..7f114a67c5 100644 --- a/packages/webpack/src/webpack.ts +++ b/packages/webpack/src/webpack.ts @@ -1,7 +1,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http' import pify from 'pify' import webpack from 'webpack' -import webpackDevMiddleware, { API } from 'webpack-dev-middleware' +import webpackDevMiddleware, { API, OutputFileSystem } from 'webpack-dev-middleware' import webpackHotMiddleware from 'webpack-hot-middleware' import type { Compiler, Watching } from 'webpack' @@ -34,10 +34,10 @@ export async function bundle (nuxt: Nuxt) { // Configure compilers const compilers = webpackConfigs.map((config) => { - config.plugins.push(DynamicBasePlugin.webpack({ + config.plugins!.push(DynamicBasePlugin.webpack({ sourcemap: nuxt.options.sourcemap })) - config.plugins.push(composableKeysPlugin.webpack({ + config.plugins!.push(composableKeysPlugin.webpack({ sourcemap: nuxt.options.sourcemap, rootDir: nuxt.options.rootDir })) @@ -47,7 +47,7 @@ export async function bundle (nuxt: Nuxt) { // In dev, write files in memory FS if (nuxt.options.dev) { - compiler.outputFileSystem = mfs + compiler.outputFileSystem = mfs as unknown as OutputFileSystem } return compiler @@ -88,7 +88,7 @@ async function createDevMiddleware (compiler: Compiler) { const hotMiddleware = pify(webpackHotMiddleware(compiler, { log: false, heartbeat: 10000, - path: joinURL(nuxt.options.app.baseURL, '__webpack_hmr', compiler.options.name), + path: joinURL(nuxt.options.app.baseURL, '__webpack_hmr', compiler.options.name!), ...hotMiddlewareOptions })) @@ -96,9 +96,9 @@ async function createDevMiddleware (compiler: Compiler) { await nuxt.callHook('webpack:hotMiddleware', hotMiddleware) // Register devMiddleware on server - await nuxt.callHook('server:devMiddleware', async (req, res, next) => { + await nuxt.callHook('server:devMiddleware', async (req: IncomingMessage, res: ServerResponse, next: (error?: any) => void) => { for (const mw of [devMiddleware, hotMiddleware]) { - await mw?.(req, res) + await mw?.(req, res, next) } next() }) @@ -111,11 +111,11 @@ async function compile (compiler: Compiler) { const { name } = compiler.options - await nuxt.callHook('build:compile', { name, compiler }) + await nuxt.callHook('build:compile', { name: name!, compiler }) // Load renderer resources after build compiler.hooks.done.tap('load-resources', async (stats) => { - await nuxt.callHook('build:compiled', { name, compiler, stats }) + await nuxt.callHook('build:compiled', { name: name!, compiler, stats }) // Reload renderer await nuxt.callHook('build:resources', compiler.outputFileSystem) }) @@ -152,7 +152,7 @@ async function compile (compiler: Compiler) { } // --- Production Build --- - const stats = await new Promise((resolve, reject) => compiler.run((err, stats) => err ? reject(err) : resolve(stats))) + const stats = await new Promise((resolve, reject) => compiler.run((err, stats) => err ? reject(err) : resolve(stats!))) if (stats.hasErrors()) { // non-quiet mode: errors will be printed by webpack itself diff --git a/scripts/bump-edge.ts b/scripts/bump-edge.ts index 9096979d7d..09c916ae3f 100644 --- a/scripts/bump-edge.ts +++ b/scripts/bump-edge.ts @@ -3,16 +3,22 @@ import { execSync } from 'node:child_process' import { resolve } from 'pathe' import { globby } from 'globby' +interface Dep { + name: string, + range: string, + type: string +} + async function loadPackage (dir: string) { const pkgPath = resolve(dir, 'package.json') const data = JSON.parse(await fsp.readFile(pkgPath, 'utf-8').catch(() => '{}')) const save = () => fsp.writeFile(pkgPath, JSON.stringify(data, null, 2) + '\n') - const updateDeps = (reviver: Function) => { + const updateDeps = (reviver: (dep: Dep) => Dep | void) => { for (const type of ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies']) { if (!data[type]) { continue } for (const e of Object.entries(data[type])) { - const dep = { name: e[0], range: e[1], type } + const dep: Dep = { name: e[0], range: e[1] as string, type } delete data[type][dep.name] const updated = reviver(dep) || dep data[updated.type] = data[updated.type] || {} diff --git a/test/basic.test.ts b/test/basic.test.ts index 07450c8067..b3709b9359 100644 --- a/test/basic.test.ts +++ b/test/basic.test.ts @@ -350,7 +350,7 @@ describe('extends support', () => { describe('app', () => { it('extends foo/app/router.options & bar/app/router.options', async () => { const html: string = await $fetch('/') - const routerLinkClasses = html.match(/href="\/" class="([^"]*)"/)[1].split(' ') + const routerLinkClasses = html.match(/href="\/" class="([^"]*)"/)?.[1].split(' ') expect(routerLinkClasses).toContain('foo-active-class') expect(routerLinkClasses).toContain('bar-exact-active-class') }) @@ -404,7 +404,7 @@ describe('dynamic paths', () => { } it('should work with no overrides', async () => { - const html = await $fetch('/assets') + const html: string = await $fetch('/assets') for (const match of html.matchAll(/(href|src)="(.*?)"/g)) { const url = match[2] expect(url.startsWith('/_nuxt/') || url === '/public.svg').toBeTruthy() @@ -417,11 +417,11 @@ describe('dynamic paths', () => { return } - const html = await $fetch('/assets') + const html: string = await $fetch('/assets') const urls = Array.from(html.matchAll(/(href|src)="(.*?)"/g)).map(m => m[2]) const cssURL = urls.find(u => /_nuxt\/assets.*\.css$/.test(u)) expect(cssURL).toBeDefined() - const css = await $fetch(cssURL) + const css: string = await $fetch(cssURL!) const imageUrls = Array.from(css.matchAll(/url\(([^)]*)\)/g)).map(m => m[1].replace(/[-.][\w]{8}\./g, '.')) expect(imageUrls).toMatchInlineSnapshot(` [ diff --git a/test/utils.ts b/test/utils.ts index bdd96611d7..517274a5d6 100644 --- a/test/utils.ts +++ b/test/utils.ts @@ -4,13 +4,13 @@ import { expect } from 'vitest' export async function renderPage (path = '/') { const ctx = useTestContext() if (!ctx.options.browser) { - return + throw new Error('`renderPage` require `options.browser` to be set') } const browser = await getBrowser() const page = await browser.newPage({}) - const pageErrors = [] - const consoleLogs = [] + const pageErrors: Error[] = [] + const consoleLogs: { type:string, text:string }[] = [] page.on('console', (message) => { consoleLogs.push({ @@ -39,7 +39,7 @@ export async function expectNoClientErrors (path: string) { return } - const { pageErrors, consoleLogs } = await renderPage(path) + const { pageErrors, consoleLogs } = (await renderPage(path))! const consoleLogErrors = consoleLogs.filter(i => i.type === 'error') const consoleLogWarnings = consoleLogs.filter(i => i.type === 'warning') diff --git a/tsconfig.json b/tsconfig.json index ffabca27f6..ad18daf7ab 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -6,7 +6,8 @@ "target": "ESNext", "module": "ESNext", "moduleResolution": "Node", - "strict": false, + "strict": true, + "noImplicitAny": true, "allowJs": true, "noEmit": true, "noUnusedLocals": true, @@ -33,7 +34,7 @@ } }, "exclude": [ - "**/*/dist/*", + "**/dist/**", "**/.nuxt/**", "**/nuxt.d.ts", "**/examples/**", diff --git a/yarn.lock b/yarn.lock index 61cc4d7080..64ae347cd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -327,7 +327,7 @@ __metadata: languageName: node linkType: hard -"@babel/standalone@npm:^7.18.11": +"@babel/standalone@npm:^7.18.11, @babel/standalone@npm:^7.18.13": version: 7.18.13 resolution: "@babel/standalone@npm:7.18.13" checksum: da010b1ef0d53f7888d01b3ef93aac9a17af5711979e7bc048b80bf08ae6dfa6b637bf92fee0c5753b4ff1bc3639a5b82925f9234d4e2150fc6d4d5c2ccc1f89 @@ -1661,7 +1661,7 @@ __metadata: unbuild: latest unctx: ^2.0.1 unimport: ^0.6.7 - untyped: ^0.4.5 + untyped: ^0.4.7 languageName: unknown linkType: soft @@ -1688,6 +1688,7 @@ __metadata: ufo: ^0.8.5 unbuild: latest unimport: ^0.6.7 + untyped: ^0.4.7 vite: ~3.0.9 languageName: unknown linkType: soft @@ -1825,6 +1826,7 @@ __metadata: "@nuxt/friendly-errors-webpack-plugin": ^2.5.2 "@nuxt/kit": 3.0.0-rc.8 "@nuxt/schema": 3.0.0-rc.8 + "@types/lodash-es": ^4.17.6 "@types/pify": ^5.0.1 "@types/webpack-bundle-analyzer": ^4.4.2 "@types/webpack-dev-middleware": ^5.0.2 @@ -2280,6 +2282,13 @@ __metadata: languageName: node linkType: hard +"@types/flat@npm:^5.0.2": + version: 5.0.2 + resolution: "@types/flat@npm:5.0.2" + checksum: e21d51d872e788bdb381887c2880f717ba4377beb4055078136127134858efd15044655610f1fce4832d9a103ded468a25335203fc53f36db08edd5ab5a8b3db + languageName: node + linkType: hard + "@types/fs-extra@npm:^9.0.13": version: 9.0.13 resolution: "@types/fs-extra@npm:9.0.13" @@ -2331,6 +2340,15 @@ __metadata: languageName: node linkType: hard +"@types/lodash-es@npm:^4.17.6": + version: 4.17.6 + resolution: "@types/lodash-es@npm:4.17.6" + dependencies: + "@types/lodash": "*" + checksum: 9bd239dd525086e278821949ce12fbdd4f100a060fed9323fc7ad5661113e1641f28a7ebab617230ed3474680d8f4de705c1928b48252bb684be6ec9eed715db + languageName: node + linkType: hard + "@types/lodash.template@npm:^4": version: 4.5.1 resolution: "@types/lodash.template@npm:4.5.1" @@ -9860,6 +9878,7 @@ __metadata: "@nuxt/kit": 3.0.0-rc.8 "@nuxt/schema": 3.0.0-rc.8 "@types/clear": ^0 + "@types/flat": ^5.0.2 "@types/mri": ^1.1.1 "@types/semver": ^7 c12: ^0.2.9 @@ -9976,7 +9995,7 @@ __metadata: unenv: ^0.6.1 unimport: ^0.6.7 unplugin: ^0.9.2 - untyped: ^0.4.5 + untyped: ^0.4.7 vue: ^3.2.37 vue-bundle-renderer: ^0.4.2 vue-devtools-stub: ^0.1.0 @@ -13190,6 +13209,18 @@ __metadata: languageName: node linkType: hard +"untyped@npm:^0.4.7": + version: 0.4.7 + resolution: "untyped@npm:0.4.7" + dependencies: + "@babel/core": ^7.18.13 + "@babel/standalone": ^7.18.13 + "@babel/types": ^7.18.13 + scule: ^0.3.2 + checksum: d5b189b19e114c4d60e122da9234c68a93d71b312a64bd8303e3aaa96f7a677befa8519ce003dec8cb587ed3e5503046131532196257ed10e647bc741532b1bc + languageName: node + linkType: hard + "upath@npm:^2.0.1": version: 2.0.1 resolution: "upath@npm:2.0.1"